diff --git a/jar/EigenPSF_Extractor-0.0.3.jar b/jar/EigenPSF_Extractor-0.0.3.jar index 4083cd65759b6ef0bd70c5e33d84096068dbaf6f..4dcdecfec910ea7a47f179f1007353aa081bbab1 100644 Binary files a/jar/EigenPSF_Extractor-0.0.3.jar and b/jar/EigenPSF_Extractor-0.0.3.jar differ diff --git a/javaworkspace/EigenPSF_Extractor/.classpath b/javaworkspace/EigenPSF_Extractor/.classpath index f96c12c9b6b688792fde90370f4f7f8ef161608f..e6a9ad7c578e466c088a1d0c063c38ccabe906e9 100644 --- a/javaworkspace/EigenPSF_Extractor/.classpath +++ b/javaworkspace/EigenPSF_Extractor/.classpath @@ -2,7 +2,6 @@ <classpath> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="src" path="src"/> - <classpathentry kind="lib" path="lib/bilib-commons.jar"/> <classpathentry kind="lib" path="lib/ij.jar"/> <classpathentry kind="lib" path="lib/jblas-1.2.5.jar"/> <classpathentry kind="lib" path="lib/JTransforms-3.1-with-dependencies.jar"/> diff --git a/javaworkspace/EigenPSF_Extractor/.project b/javaworkspace/EigenPSF_Extractor/.project index 4f63843730f30413911ed7c961131300fcf73a5f..45fba7c793ac84e09188bb6962ad60407c59742c 100644 --- a/javaworkspace/EigenPSF_Extractor/.project +++ b/javaworkspace/EigenPSF_Extractor/.project @@ -40,11 +40,6 @@ <type>1</type> <locationURI>PARENT-2-PROJECT_LOC/src/lib/JTransforms-3.1-with-dependencies.jar</locationURI> </link> - <link> - <name>lib/bilib-commons.jar</name> - <type>1</type> - <locationURI>PARENT-2-PROJECT_LOC/src/lib/bilib-commons.jar</locationURI> - </link> <link> <name>lib/ij.jar</name> <type>1</type> @@ -85,6 +80,11 @@ <type>1</type> <locationURI>PARENT-2-PROJECT_LOC/src/src/Unit_Tests.java</locationURI> </link> + <link> + <name>src/bilib</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> <link> <name>src/eigenpsf</name> <type>2</type> @@ -120,6 +120,16 @@ <type>1</type> <locationURI>PARENT-2-PROJECT_LOC/src/src/RefineCodeCpp/libEigenPSF_Refine.so</locationURI> </link> + <link> + <name>bin/bilib/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/.DS_Store</locationURI> + </link> + <link> + <name>bin/bilib/commons.zip</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons.zip</locationURI> + </link> <link> <name>bin/resources/about.png</name> <type>1</type> @@ -255,6 +265,31 @@ <type>1</type> <locationURI>PARENT-2-PROJECT_LOC/src/src/RefineCodeCpp/libEigenPSF_Refine.so</locationURI> </link> + <link> + <name>src/bilib/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/.DS_Store</locationURI> + </link> + <link> + <name>src/bilib/commons</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons.zip</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons.zip</locationURI> + </link> + <link> + <name>src/bilib/fft</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/optimization</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> <link> <name>src/eigenpsf/AdvancedSettingsPanel.java</name> <type>1</type> @@ -460,6 +495,81 @@ <type>1</type> <locationURI>PARENT-2-PROJECT_LOC/src/src/resources/update.png</locationURI> </link> + <link> + <name>bin/bilib/commons/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/.DS_Store</locationURI> + </link> + <link> + <name>bin/bilib/optimization/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/optimization/.DS_Store</locationURI> + </link> + <link> + <name>src/bilib/commons/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/.DS_Store</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/components</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/fft</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/job</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/math</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/random</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/settings</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/table</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/utils</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/fft/AcademicFourierTransform.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/fft/AcademicFourierTransform.java</locationURI> + </link> + <link> + <name>src/bilib/optimization/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/optimization/.DS_Store</locationURI> + </link> + <link> + <name>src/bilib/optimization/levenbergmarquardt</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> <link> <name>src/eigenpsf/data/Convolution.java</name> <type>1</type> @@ -660,5 +770,385 @@ <type>1</type> <locationURI>PARENT-2-PROJECT_LOC/src/src/eigenpsf/stack/ZStack.java</locationURI> </link> + <link> + <name>bin/bilib/commons/buttons/about.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/about.png</locationURI> + </link> + <link> + <name>bin/bilib/commons/buttons/close.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/close.png</locationURI> + </link> + <link> + <name>bin/bilib/commons/buttons/help.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/help.png</locationURI> + </link> + <link> + <name>bin/bilib/commons/buttons/prefs.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/prefs.png</locationURI> + </link> + <link> + <name>bin/bilib/commons/buttons/run.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/run.png</locationURI> + </link> + <link> + <name>bin/bilib/commons/buttons/save.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/save.png</locationURI> + </link> + <link> + <name>bin/bilib/commons/buttons/snapshot.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/snapshot.png</locationURI> + </link> + <link> + <name>bin/bilib/commons/buttons/stop.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/stop.png</locationURI> + </link> + <link> + <name>bin/bilib/commons/job/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/.DS_Store</locationURI> + </link> + <link> + <name>bin/bilib/commons/math/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/math/.DS_Store</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons/ButtonFactory.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/ButtonFactory.java</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons/about.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/about.png</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons/close.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/close.png</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons/help.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/help.png</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons/prefs.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/prefs.png</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons/run.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/run.png</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons/save.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/save.png</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons/snapshot.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/snapshot.png</locationURI> + </link> + <link> + <name>src/bilib/commons/buttons/stop.png</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/buttons/stop.png</locationURI> + </link> + <link> + <name>src/bilib/commons/components/BorderToggledButton.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/components/BorderToggledButton.java</locationURI> + </link> + <link> + <name>src/bilib/commons/components/DoubleScrollablePanel.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/components/DoubleScrollablePanel.java</locationURI> + </link> + <link> + <name>src/bilib/commons/components/GridPanel.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/components/GridPanel.java</locationURI> + </link> + <link> + <name>src/bilib/commons/components/GridToolbar.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/components/GridToolbar.java</locationURI> + </link> + <link> + <name>src/bilib/commons/components/HTMLPane.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/components/HTMLPane.java</locationURI> + </link> + <link> + <name>src/bilib/commons/components/SpinnerRangeDouble.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/components/SpinnerRangeDouble.java</locationURI> + </link> + <link> + <name>src/bilib/commons/components/SpinnerRangeFloat.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/components/SpinnerRangeFloat.java</locationURI> + </link> + <link> + <name>src/bilib/commons/components/SpinnerRangeInteger.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/components/SpinnerRangeInteger.java</locationURI> + </link> + <link> + <name>src/bilib/commons/fft/BasicFFT.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/fft/BasicFFT.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/.DS_Store</locationURI> + </link> + <link> + <name>src/bilib/commons/job/ExecutionMode.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/ExecutionMode.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/JobAbstract.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/JobAbstract.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/JobEvent.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/JobEvent.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/MonitorAbstract.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/MonitorAbstract.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/MonitorConsole.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/MonitorConsole.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/MonitorProgressBar.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/MonitorProgressBar.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/MonitorTimedLog.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/MonitorTimedLog.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/MonitorTimedProgressBar.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/MonitorTimedProgressBar.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/PoolAbstract.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/PoolAbstract.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/callable</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/job/runnable</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/job/worker</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/math/.DS_Store</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/math/.DS_Store</locationURI> + </link> + <link> + <name>src/bilib/commons/math/bessel</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/math/windowing</name> + <type>2</type> + <locationURI>virtual:/virtual</locationURI> + </link> + <link> + <name>src/bilib/commons/random/Noise.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/random/Noise.java</locationURI> + </link> + <link> + <name>src/bilib/commons/random/NoiseExponential.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/random/NoiseExponential.java</locationURI> + </link> + <link> + <name>src/bilib/commons/random/NoiseGaussian.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/random/NoiseGaussian.java</locationURI> + </link> + <link> + <name>src/bilib/commons/random/NoisePoisson.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/random/NoisePoisson.java</locationURI> + </link> + <link> + <name>src/bilib/commons/random/NoiseRayleigh.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/random/NoiseRayleigh.java</locationURI> + </link> + <link> + <name>src/bilib/commons/random/NoiseUniform.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/random/NoiseUniform.java</locationURI> + </link> + <link> + <name>src/bilib/commons/settings/Settings.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/settings/Settings.java</locationURI> + </link> + <link> + <name>src/bilib/commons/settings/SettingsFileDialog.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/settings/SettingsFileDialog.java</locationURI> + </link> + <link> + <name>src/bilib/commons/table/CustomizedColumn.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/table/CustomizedColumn.java</locationURI> + </link> + <link> + <name>src/bilib/commons/table/CustomizedTable.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/table/CustomizedTable.java</locationURI> + </link> + <link> + <name>src/bilib/commons/utils/Chrono.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/utils/Chrono.java</locationURI> + </link> + <link> + <name>src/bilib/commons/utils/Files.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/utils/Files.java</locationURI> + </link> + <link> + <name>src/bilib/commons/utils/Log.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/utils/Log.java</locationURI> + </link> + <link> + <name>src/bilib/commons/utils/NumFormat.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/utils/NumFormat.java</locationURI> + </link> + <link> + <name>src/bilib/commons/utils/WebBrowser.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/utils/WebBrowser.java</locationURI> + </link> + <link> + <name>src/bilib/optimization/levenbergmarquardt/Cholesky.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/optimization/levenbergmarquardt/Cholesky.java</locationURI> + </link> + <link> + <name>src/bilib/optimization/levenbergmarquardt/Function.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/optimization/levenbergmarquardt/Function.java</locationURI> + </link> + <link> + <name>src/bilib/optimization/levenbergmarquardt/LevenbergMarquardt.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/optimization/levenbergmarquardt/LevenbergMarquardt.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/callable/CallableDemo.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/callable/CallableDemo.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/callable/Job.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/callable/Job.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/callable/Pool.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/callable/Pool.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/callable/PoolResponder.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/callable/PoolResponder.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/runnable/Job.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/runnable/Job.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/runnable/Pool.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/runnable/Pool.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/runnable/PoolResponder.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/runnable/PoolResponder.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/runnable/RunnableDemo.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/runnable/RunnableDemo.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/worker/Job.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/worker/Job.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/worker/Pool.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/worker/Pool.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/worker/PoolResponder.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/worker/PoolResponder.java</locationURI> + </link> + <link> + <name>src/bilib/commons/job/worker/WorkerDemo.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/job/worker/WorkerDemo.java</locationURI> + </link> + <link> + <name>src/bilib/commons/math/bessel/Bessel.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/math/bessel/Bessel.java</locationURI> + </link> + <link> + <name>src/bilib/commons/math/windowing/Windowing.java</name> + <type>1</type> + <locationURI>PARENT-2-PROJECT_LOC/src/bilib/src/bilib/commons/math/windowing/Windowing.java</locationURI> + </link> </linkedResources> </projectDescription> diff --git a/javaworkspace/EigenPSF_Extractor/tt/BackgroundPatches.tif b/javaworkspace/EigenPSF_Extractor/tt/BackgroundPatches.tif new file mode 100644 index 0000000000000000000000000000000000000000..e830a35cefe845cc6a460fc4aa1bf687d1d16e84 Binary files /dev/null and b/javaworkspace/EigenPSF_Extractor/tt/BackgroundPatches.tif differ diff --git a/javaworkspace/EigenPSF_Extractor/tt/EigenPSF.tif b/javaworkspace/EigenPSF_Extractor/tt/EigenPSF.tif new file mode 100644 index 0000000000000000000000000000000000000000..29282da5bc828418a5917dea51a7c2c905584085 Binary files /dev/null and b/javaworkspace/EigenPSF_Extractor/tt/EigenPSF.tif differ diff --git a/javaworkspace/EigenPSF_Extractor/tt/ProcessedPatches.tif b/javaworkspace/EigenPSF_Extractor/tt/ProcessedPatches.tif new file mode 100644 index 0000000000000000000000000000000000000000..5619a00edb29f1d5e30c64013936ff41d0379ad3 Binary files /dev/null and b/javaworkspace/EigenPSF_Extractor/tt/ProcessedPatches.tif differ diff --git a/javaworkspace/EigenPSF_Extractor/tt/ProjectedPatches.tif b/javaworkspace/EigenPSF_Extractor/tt/ProjectedPatches.tif new file mode 100644 index 0000000000000000000000000000000000000000..2bde6e0b9407e602960761d7cac5c7cc00358d89 Binary files /dev/null and b/javaworkspace/EigenPSF_Extractor/tt/ProjectedPatches.tif differ diff --git a/javaworkspace/EigenPSF_Extractor/tt/RawPatches.tif b/javaworkspace/EigenPSF_Extractor/tt/RawPatches.tif new file mode 100644 index 0000000000000000000000000000000000000000..f863fb9f8ce0a70d6e1115484b83889ed794a530 Binary files /dev/null and b/javaworkspace/EigenPSF_Extractor/tt/RawPatches.tif differ diff --git a/javaworkspace/EigenPSF_Extractor/tt/config.csv b/javaworkspace/EigenPSF_Extractor/tt/config.csv new file mode 100644 index 0000000000000000000000000000000000000000..fb61b8a244432a346f32a7947cda6ac104e39238 --- /dev/null +++ b/javaworkspace/EigenPSF_Extractor/tt/config.csv @@ -0,0 +1,18 @@ +detectionMethod, SIFT +backgroundMethod, Polynomial Fit +registrationMethod, Scale Space +normalize, l2 +dim, 2 +Nscale, 3 +NbasisVectSIFT, 3 +NeigenElements, 1 +nthin, 7 +scaleBack, 4 +factorDiamBack, 2.0 +thresholdDetection, 0.5 +quantile, 2.0 +smin, 0.5 +smax, 1.5 +psf_visible_width_0, 17 +psf_visible_width_1, 17 +psf_visible_width_2, 1 diff --git a/javaworkspace/EigenPSF_Extractor/tt/listfiles.csv b/javaworkspace/EigenPSF_Extractor/tt/listfiles.csv new file mode 100644 index 0000000000000000000000000000000000000000..2c705dff213cc5acbb264baa8b168174d2ee70ec --- /dev/null +++ b/javaworkspace/EigenPSF_Extractor/tt/listfiles.csv @@ -0,0 +1,2 @@ +Name,Beads,Show,Mask, +1,2D_widefield_astig-1.tif,/home/esoubies/Bureau/GitHub/eigenpsf-extractor/demo/2D_widefield_astig-1.tif, diff --git a/javaworkspace/EigenPSF_Extractor/tt/patchesTable.csv b/javaworkspace/EigenPSF_Extractor/tt/patchesTable.csv new file mode 100644 index 0000000000000000000000000000000000000000..a7a581fad12511bb4580a33afe48905410e2cd7a --- /dev/null +++ b/javaworkspace/EigenPSF_Extractor/tt/patchesTable.csv @@ -0,0 +1,60 @@ +Image name ID X Y Z Quality Dist Max Valid +2D_widefield_astig-1.tif 52 231 334 0 2.6368922825871293 138.74076545846214 8,161E+03 +2D_widefield_astig-1.tif 40 289 183 0 1.9621766979946318 92.39588735436226 1,104E+04 Ok +2D_widefield_astig-1.tif 57 101 162 0 3.4731905008960595 104.06248123122954 9,983E+03 +2D_widefield_astig-1.tif 34 60 207 0 1.3833614005738457 138.2931668593933 5,789E+03 Ok +2D_widefield_astig-1.tif 36 376 248 0 1.639697072655175 184.6212338816963 6,704E+03 Ok +2D_widefield_astig-1.tif 13 315 222 0 0.9588205913708715 119.4361754243663 8,999E+03 Ok +2D_widefield_astig-1.tif 42 110 263 0 2.051581162503771 108.60018416190647 7,072E+03 +2D_widefield_astig-1.tif 15 169 99 0 1.039431340797815 104.12012293500234 8,953E+03 Ok +2D_widefield_astig-1.tif 39 98 333 0 1.9097765431261826 168.6001186239203 1,715E+04 Ok +2D_widefield_astig-1.tif 50 117 201 0 2.476141207912426 82.02438661763951 2,001E+04 +2D_widefield_astig-1.tif 49 133 218 0 2.43296303234266 68.00735254367721 1,296E+04 +2D_widefield_astig-1.tif 48 291 375 0 2.1925531446676088 200.83077453418338 1,181E+04 +2D_widefield_astig-1.tif 38 111 308 0 1.7730343406949798 140.24621207005913 7,977E+03 Ok +2D_widefield_astig-1.tif 37 141 327 0 1.7044494201054463 141.0319112825179 8,899E+03 Ok +2D_widefield_astig-1.tif 16 133 34 0 1.1020035515862272 176.41145087550296 6,234E+03 Ok +2D_widefield_astig-1.tif 35 373 159 0 1.6114569779425758 179.2930561957155 8,358E+03 Ok +2D_widefield_astig-1.tif 47 224 249 0 2.175836056596235 58.137767414994535 1,444E+04 +2D_widefield_astig-1.tif 55 193 344 0 2.9265074368094908 145.1240848377691 9,201E+03 +2D_widefield_astig-1.tif 43 193 173 0 2.1160033926768933 26.476404589747453 1,273E+04 +2D_widefield_astig-1.tif 22 152 305 0 1.1690761198439292 116.46887996370532 1,775E+04 Ok +2D_widefield_astig-1.tif 21 232 290 0 1.1684242470791302 98.08159868191383 1,104E+04 Ok +2D_widefield_astig-1.tif 53 322 242 0 2.7845849677774575 132.18925826253812 8,761E+03 +2D_widefield_astig-1.tif 46 220 307 0 2.1602337204229864 111.9866063420086 1,174E+04 +2D_widefield_astig-1.tif 7 61 257 0 0.898166793749632 149.164338901763 6,674E+03 Ok +2D_widefield_astig-1.tif 10 272 179 0 0.9308440447335254 76.6550715869472 3,827E+04 Ok +2D_widefield_astig-1.tif 2 372 202 0 0.8365680637800508 174.04597093871493 7,782E+03 Ok +2D_widefield_astig-1.tif 14 90 210 0 0.9607983531660049 108.664621657649 1,720E+04 Ok +2D_widefield_astig-1.tif 51 308 256 0 2.602329097485422 123.47064428438041 1,146E+04 +2D_widefield_astig-1.tif 11 315 190 0 0.9396605727284989 117.27318534089538 2,809E+04 Ok +2D_widefield_astig-1.tif 9 252 192 0 0.9093135207899893 53.46026561849464 2,802E+04 Ok +2D_widefield_astig-1.tif 27 108 229 0 1.2895707808526016 95.1892851112981 8,811E+03 Ok +2D_widefield_astig-1.tif 17 180 321 0 1.121353980827542 124.31009613060397 2,224E+04 Ok +2D_widefield_astig-1.tif 29 200 156 0 1.3195480677918965 42.04759208325728 1,071E+04 Ok +2D_widefield_astig-1.tif 56 184 292 0 3.2042571166320943 94.89467845985885 1,406E+04 +2D_widefield_astig-1.tif 41 367 115 0 2.0246417215407626 186.9438418349211 7,738E+03 +2D_widefield_astig-1.tif 24 89 308 0 1.2037193785876887 155.56349186104046 1,193E+04 Ok +2D_widefield_astig-1.tif 1 356 167 0 0.7821929662752916 160.0312469488381 1,100E+04 Ok +2D_widefield_astig-1.tif 59 263 296 0 4.72015806113066 116.50321883965266 1,144E+04 +2D_widefield_astig-1.tif 3 257 89 0 0.8522766100250591 123.94353553130554 1,033E+04 Ok +2D_widefield_astig-1.tif 44 163 326 0 2.1181977831426106 131.73458164050928 9,948E+03 +2D_widefield_astig-1.tif 12 263 8 0 0.9454884362991656 200.48940121612415 8,717E+03 Ok +2D_widefield_astig-1.tif 18 256 210 0 1.1327329132058517 59.22837157984339 1,164E+04 Ok +2D_widefield_astig-1.tif 28 283 272 0 1.3065621529883933 112.69871339105873 8,977E+03 Ok +2D_widefield_astig-1.tif 45 251 331 0 2.1194805664581393 144.10065926289164 8,908E+03 +2D_widefield_astig-1.tif 54 257 271 0 2.8405014851743613 93.08598175880189 2,937E+04 +2D_widefield_astig-1.tif 20 145 238 0 1.151344362258985 65.80273550544841 2,230E+04 Ok +2D_widefield_astig-1.tif 30 276 307 0 1.3200147695348847 133.2216198670471 1,042E+04 Ok +2D_widefield_astig-1.tif 58 165 197 0 4.009037772596921 31.016124838541646 2,136E+04 +2D_widefield_astig-1.tif 33 298 241 0 1.3808148976687682 108.85311203635843 1,323E+04 Ok +2D_widefield_astig-1.tif 31 276 210 0 1.3501578905120262 78.91767862779544 1,517E+04 Ok +2D_widefield_astig-1.tif 25 352 250 0 1.2414301893684534 162.22515218054195 2,044E+04 Ok +2D_widefield_astig-1.tif 32 162 356 0 1.3788240341940585 162.04937519163718 1,149E+04 Ok +2D_widefield_astig-1.tif 8 146 124 0 0.9082565892758712 90.44335243676011 8,439E+03 Ok +2D_widefield_astig-1.tif 4 170 121 0 0.8702071389742275 82.87339742040264 4,710E+04 Ok +2D_widefield_astig-1.tif 5 210 191 0 0.8757715793006416 13.892443989449804 4,780E+04 Ok +2D_widefield_astig-1.tif 26 252 240 0 1.2811400940397435 68.41052550594829 2,894E+04 Ok +2D_widefield_astig-1.tif 6 349 119 0 0.8867731113538374 170.88300090997933 1,735E+04 Ok +2D_widefield_astig-1.tif 23 263 160 0 1.1942832656560562 75.29276193632427 2,333E+04 Ok +2D_widefield_astig-1.tif 19 197 96 0 1.1511892666591277 102.00490184299969 1,702E+04 Ok diff --git a/src/bilib/src/.DS_Store b/src/bilib/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6b9fe70d098578936fb60f7f68699ac925a87938 Binary files /dev/null and b/src/bilib/src/.DS_Store differ diff --git a/src/bilib/src/additionaluserinterface.zip b/src/bilib/src/additionaluserinterface.zip new file mode 100644 index 0000000000000000000000000000000000000000..c0afaeb8e9bb683213def10a9810079f6f03a981 Binary files /dev/null and b/src/bilib/src/additionaluserinterface.zip differ diff --git a/src/bilib/src/additionaluserinterface/Chrono.java b/src/bilib/src/additionaluserinterface/Chrono.java new file mode 100644 index 0000000000000000000000000000000000000000..178ea58447c9297792f88a3ffb468b2461d3d02c --- /dev/null +++ b/src/bilib/src/additionaluserinterface/Chrono.java @@ -0,0 +1,54 @@ +package additionaluserinterface; + +import java.text.DecimalFormat; + +/** + * This class provides static methods to measures the elapsed time. It is a + * equivalent to the function tic and toc of Matlab. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class Chrono { + + static private double chrono = 0; + + /** + * Register the current time. + */ + public static void tic() { + chrono = System.currentTimeMillis(); + } + + /** + * Returns a string that indicates the elapsed time since the last tic() + * call. + */ + public static String toc() { + return toc(""); + } + + /** + * Returns a string that indicates the elapsed time since the last tic() + * call. + * + * @param msg + * message to print + */ + public static String toc(String msg) { + double te = System.currentTimeMillis() - chrono; + String s = msg + " "; + DecimalFormat df = new DecimalFormat("####.##"); + if (te < 3000.0) + return s + df.format(te) + " ms"; + te /= 1000; + if (te < 600.1) + return s + df.format(te) + " s"; + te /= 60; + if (te < 240.1) + return s + df.format(te) + " min."; + te /= 24; + return s + df.format(te) + " h."; + } + +} diff --git a/src/bilib/src/additionaluserinterface/GridPanel.java b/src/bilib/src/additionaluserinterface/GridPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..0fa3fe0164c824e4b038c3419e072fc5aa3f58de --- /dev/null +++ b/src/bilib/src/additionaluserinterface/GridPanel.java @@ -0,0 +1,128 @@ +package additionaluserinterface; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; + +/** + * This class extends the JPanel to create grid panel given the possibility to + * place Java compoments in an organized manner in the dialog box. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class GridPanel extends JPanel { + + private GridBagLayout layout = new GridBagLayout(); + private GridBagConstraints constraint = new GridBagConstraints(); + private int defaultSpace = 3; + + /** + * Constructor. + */ + public GridPanel() { + super(); + setLayout(layout); + setBorder(BorderFactory.createEtchedBorder()); + } + + /** + * Constructor. + */ + public GridPanel(int defaultSpace) { + super(); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createEtchedBorder()); + } + + /** + * Constructor. + */ + public GridPanel(boolean border) { + super(); + setLayout(layout); + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + } + + /** + * Constructor. + */ + public GridPanel(String title) { + super(); + setLayout(layout); + setBorder(BorderFactory.createTitledBorder(title)); + } + + /** + * Constructor. + */ + public GridPanel(boolean border, int defaultSpace) { + super(); + setLayout(layout); + this.defaultSpace = defaultSpace; + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + } + + /** + * Constructor. + */ + public GridPanel(String title, int defaultSpace) { + super(); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createTitledBorder(title)); + } + + /** + * Specify the defaultSpace. + */ + public void setSpace(int defaultSpace) { + this.defaultSpace = defaultSpace; + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, JComponent comp) { + place(row, col, 1, 1, defaultSpace, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int space, JComponent comp) { + place(row, col, 1, 1, space, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, JComponent comp) { + place(row, col, width, height, defaultSpace, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, int space, JComponent comp) { + constraint.gridx = col; + constraint.gridy = row; + constraint.gridwidth = width; + constraint.gridheight = height; + constraint.anchor = GridBagConstraints.NORTHWEST; + constraint.insets = new Insets(space, space, space, space); + constraint.fill = GridBagConstraints.HORIZONTAL; + layout.setConstraints(comp, constraint); + add(comp); + } + +} diff --git a/src/bilib/src/additionaluserinterface/GridToolbar.java b/src/bilib/src/additionaluserinterface/GridToolbar.java new file mode 100644 index 0000000000000000000000000000000000000000..c2066f261ece7fe5e99a2560bbfa64a99da8a09d --- /dev/null +++ b/src/bilib/src/additionaluserinterface/GridToolbar.java @@ -0,0 +1,191 @@ +package additionaluserinterface; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JToolBar; + +/** + * This class extends the JToolbar to create grid panel given the possibility to + * place Java compoments in an organized manner in the dialog box. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class GridToolbar extends JToolBar { + + private GridBagLayout layout = new GridBagLayout(); + private GridBagConstraints constraint = new GridBagConstraints(); + private int defaultSpace = 3; + + /** + * Constructor. + */ + public GridToolbar() { + super("Control"); + setLayout(layout); + setBorder(BorderFactory.createEtchedBorder()); + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(boolean border) { + super("Control"); + setLayout(layout); + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(String title) { + super(title); + setLayout(layout); + setBorder(BorderFactory.createTitledBorder(title)); + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(int defaultSpace) { + super("Control"); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createEtchedBorder()); + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(boolean border, int defaultSpace) { + super("Control"); + setLayout(layout); + this.defaultSpace = defaultSpace; + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(boolean border, int defaultSpace, boolean floatable) { + super("Control"); + setLayout(layout); + this.defaultSpace = defaultSpace; + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + setFloatable(floatable); + } + + /** + * Constructor. + */ + public GridToolbar(boolean border, boolean floatable) { + super("Control"); + setLayout(layout); + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + setFloatable(floatable); + } + + /** + * Constructor. + */ + public GridToolbar(String title, boolean floatable) { + super(title); + setLayout(layout); + setBorder(BorderFactory.createTitledBorder(title)); + setFloatable(floatable); + } + + /** + * Constructor. + */ + public GridToolbar(int defaultSpace, boolean floatable) { + super("Control"); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createEtchedBorder()); + setFloatable(floatable); + } + + /** + * Constructor. + */ + public GridToolbar(String title, int defaultSpace) { + super(title); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createTitledBorder(title)); + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(String title, int defaultSpace, boolean floatable) { + super(title); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createTitledBorder(title)); + setFloatable(floatable); + } + + /** + * Specify the defaultSpace. + */ + public void setSpace(int defaultSpace) { + this.defaultSpace = defaultSpace; + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, JComponent comp) { + place(row, col, 1, 1, defaultSpace, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int space, JComponent comp) { + place(row, col, 1, 1, space, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, JComponent comp) { + place(row, col, width, height, defaultSpace, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, int space, JComponent comp) { + constraint.gridx = col; + constraint.gridy = row; + constraint.gridwidth = width; + constraint.gridheight = height; + constraint.anchor = GridBagConstraints.NORTHWEST; + constraint.insets = new Insets(space, space, space, space); + constraint.fill = GridBagConstraints.HORIZONTAL; + layout.setConstraints(comp, constraint); + add(comp); + } + +} diff --git a/src/bilib/src/additionaluserinterface/NumericTable.java b/src/bilib/src/additionaluserinterface/NumericTable.java new file mode 100644 index 0000000000000000000000000000000000000000..1c8a3b922ddbfff7f115668679a13c74778dfa89 --- /dev/null +++ b/src/bilib/src/additionaluserinterface/NumericTable.java @@ -0,0 +1,82 @@ +package additionaluserinterface; + +import java.awt.Dimension; +import java.awt.Point; +import java.text.DecimalFormat; + +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ScrollPaneConstants; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumn; + +/** + * This class extends JFrame and draw a simple table. All values are in 2D + * double arrays + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ + +public class NumericTable extends JFrame { + + private JTable table; + private DefaultTableModel model; + + public NumericTable(String title, String[] headings, Dimension dim) { + super(title); + setMinimumSize(dim); + setSize(dim); + setPreferredSize(dim); + + JScrollPane pane = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + model = new DefaultTableModel(); + table = new JTable(model); + for (int i = 0; i < headings.length; i++) { + model.addColumn(headings[i]); + } + + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + pane.getViewport().add(table, null); + add(pane); + } + + public void setData(double data[][]) { + int nrow = data.length; + int ncol = data[0].length; + String s[] = new String[ncol]; + for (int r = 0; r < nrow; r++) { + for (int c = 0; c < ncol; c++) + s[c] = "" + data[r][c]; + model.addRow(s); + } + + } + + public void setData(double data[][], String[] formats) { + int nrow = data.length; + int ncol = data[0].length; + String s[] = new String[ncol]; + for (int r = 0; r < nrow; r++) { + for (int c = 0; c < ncol; c++) + s[c] = (new DecimalFormat(formats[c])).format(data[r][c]); + model.addRow(s); + } + + } + + public void setColumnSize(int width[]) { + for (int i = 0; i < width.length; i++) { + TableColumn column = table.getColumnModel().getColumn(i); + column.setPreferredWidth(width[i]); + } + } + + public void show(int posx, int posy) { + pack(); + setLocation(new Point(posx, posy)); + setVisible(true); + } + +} diff --git a/src/bilib/src/additionaluserinterface/Settings.java b/src/bilib/src/additionaluserinterface/Settings.java new file mode 100644 index 0000000000000000000000000000000000000000..7b694fee5490cf6c95132097b41f2d908d77a16c --- /dev/null +++ b/src/bilib/src/additionaluserinterface/Settings.java @@ -0,0 +1,479 @@ +package additionaluserinterface; + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.Properties; +import java.util.Vector; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JSlider; +import javax.swing.JSpinner; +import javax.swing.JTextField; +import javax.swing.JToggleButton; +import javax.swing.Timer; + +/** + * This class allows to store and load key-associated values in a text file. The + * class has methods to load and store single value linked to a string key + * describing the value. Futhermore, this class has methods to record a GUI + * component to a specified key. By this way this class allows to load and store + * all recorded items. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class Settings { + + private String filename; + private String project; + private Vector<Item> items; + private Properties props; + + /** + * Constructors a Settings abject for a given project name and a given + * filename. + * + * @param project + * a string describing the project + * @param filename + * a string give the full name of the file, including the path + */ + public Settings(String project, String filename) { + this.filename = filename; + this.project = project; + items = new Vector<Item>(); + props = new Properties(); + } + + /** + * Records a JTextField component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JTextField component, String defaultValue) { + Item item = new Item(key, component, defaultValue); + items.add(item); + } + + /** + * Records a JComboBox component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JComboBox component, String defaultValue) { + Item item = new Item(key, component, defaultValue); + items.add(item); + } + + /** + * Records a JSpinner component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JSpinner component, String defaultValue) { + Item item = new Item(key, component, defaultValue); + items.add(item); + } + + /** + * Records a JToggleButton component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JToggleButton component, boolean defaultValue) { + Item item = new Item(key, component, (defaultValue ? "on" : "off")); + items.add(item); + } + + /** + * Records a JCheckBox component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JCheckBox component, boolean defaultValue) { + Item item = new Item(key, component, (defaultValue ? "on" : "off")); + items.add(item); + } + + /** + * Records a JSlider component to store/load automatically. + * + * @param key + * a int value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JSlider component, String defaultValue) { + Item item = new Item(key, component, defaultValue); + items.add(item); + } + + /** + * Load an individual double value given a specified key + * + * @param key + * a string describing the value + * @param defaultValue + * the default value + * @return the value get from the file + */ + public String loadValue(String key, String defaultValue) { + String s = ""; + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + s = props.getProperty(key, "" + defaultValue); + } + catch (Exception e) { + s = defaultValue; + } + return s; + } + + /** + * Load an individual double value given a specified key + * + * @param key + * a string describing the value + * @param defaultValue + * the default value + * @return the value get from the file + */ + public double loadValue(String key, double defaultValue) { + double d = 0; + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + String value = props.getProperty(key, "" + defaultValue); + d = (new Double(value)).doubleValue(); + } + catch (Exception e) { + d = defaultValue; + } + return d; + } + + /** + * Load an individual integer value given a specified key + * + * @param key + * a string describing the value + * @param defaultValue + * the default value + * @return the value get from the file + */ + public int loadValue(String key, int defaultValue) { + int i = 0; + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + String value = props.getProperty(key, "" + defaultValue); + i = (new Integer(value)).intValue(); + } + catch (Exception e) { + i = defaultValue; + } + return i; + } + + /** + * Load an individual boolean value given a specified key + * + * @param key + * a string describing the value + * @param defaultValue + * the default value + * @return the value get from the file + */ + public boolean loadValue(String key, boolean defaultValue) { + boolean b = false; + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + String value = props.getProperty(key, "" + defaultValue); + b = (new Boolean(value)).booleanValue(); + } + catch (Exception e) { + b = defaultValue; + } + return b; + } + + /** + * Store an individual double value given a specified key + * + * @param key + * a string describing the value + * @param value + * the value to store + */ + public void storeValue(String key, String value) { + props.setProperty(key, value); + try { + FileOutputStream out = new FileOutputStream(filename); + props.store(out, project); + } + catch (Exception e) { + new Msg(project, "Impossible to store settings in (" + filename + ")"); + } + } + + /** + * Store an individual double value given a specified key + * + * @param key + * a string describing the value + * @param value + * the value to store + */ + public void storeValue(String key, double value) { + props.setProperty(key, "" + value); + try { + FileOutputStream out = new FileOutputStream(filename); + props.store(out, project); + } + catch (Exception e) { + new Msg(project, "Impossible to store settings in (" + filename + ")"); + } + } + + /** + * Store an individual integer value given a specified key + * + * @param key + * a string describing the value + * @param value + * the value to store + */ + public void storeValue(String key, int value) { + props.setProperty(key, "" + value); + try { + FileOutputStream out = new FileOutputStream(filename); + props.store(out, project); + } + catch (Exception e) { + new Msg(project, "Impossible to store settings in (" + filename + ")"); + } + } + + /** + * Store an individual boolean value given a specified key + * + * @param key + * a string describing the value + * @param value + * the value to store + */ + public void storeValue(String key, boolean value) { + props.setProperty(key, "" + value); + try { + FileOutputStream out = new FileOutputStream(filename); + props.store(out, project); + } + catch (Exception e) { + new Msg(project, "Impossible to store settings in (" + filename + ")"); + } + } + + /** + * Load all recorded values. + */ + public void loadRecordedItems() { + loadRecordedItems(filename); + } + + /** + * Load all recorded values from a specified filename. + */ + public void loadRecordedItems(String fname) { + try { + FileInputStream in = new FileInputStream(fname); + props.load(in); + } + catch (Exception e) { + new Msg(project, "Loading default value. No settings file (" + fname + ")"); + return; + } + + for (int i = 0; i < items.size(); i++) { + Item item = (Item) items.get(i); + String value = props.getProperty(item.key, item.defaultValue); + if (item.component instanceof JTextField) { + ((JTextField) item.component).setText(value); + } + else if (item.component instanceof JComboBox) { + ((JComboBox) item.component).setSelectedItem(value); + } + else if (item.component instanceof JCheckBox) { + ((JCheckBox) item.component).setSelected(value.equals("on") ? true : false); + } + else if (item.component instanceof JToggleButton) { + ((JToggleButton) item.component).setSelected(value.equals("on") ? true : false); + } + else if (item.component instanceof SpinnerInteger) { + ((SpinnerInteger) item.component).set(Math.round((new Double(value)).intValue())); + } + else if (item.component instanceof SpinnerDouble) { + ((SpinnerDouble) item.component).set((new Double(value)).doubleValue()); + } + else if (item.component instanceof SpinnerFloat) { + ((SpinnerFloat) item.component).set((new Float(value)).floatValue()); + } + else if (item.component instanceof JSlider) { + ((JSlider) item.component).setValue((new Integer(value)).intValue()); + } + } + } + + /** + * Store all recorded values. + */ + public void storeRecordedItems() { + storeRecordedItems(filename); + } + + /** + * Store all recorded values into a specified filename + */ + public void storeRecordedItems(String fname) { + + for (int i = 0; i < items.size(); i++) { + Item item = (Item) items.get(i); + if (item.component instanceof JTextField) { + String value = ((JTextField) item.component).getText(); + props.setProperty(item.key, value); + } + else if (item.component instanceof JComboBox) { + String value = (String) ((JComboBox) item.component).getSelectedItem(); + props.setProperty(item.key, value); + } + else if (item.component instanceof JCheckBox) { + String value = (((JCheckBox) item.component).isSelected() ? "on" : "off"); + props.setProperty(item.key, value); + } + else if (item.component instanceof JToggleButton) { + String value = (((JToggleButton) item.component).isSelected() ? "on" : "off"); + props.setProperty(item.key, value); + } + else if (item.component instanceof JSpinner) { + String value = "" + ((JSpinner) item.component).getValue(); + props.setProperty(item.key, value); + } + else if (item.component instanceof JSlider) { + String value = "" + ((JSlider) item.component).getValue(); + props.setProperty(item.key, value); + } + } + + try { + FileOutputStream out = new FileOutputStream(fname); + props.store(out, project); + } + catch (Exception e) { + new Msg(project, "Impossible to store settings in (" + fname + ")"); + + } + } + + /** + * Private class to store one component and its key. + */ + private class Item { + public Object component; + public String defaultValue; + public String key; + + public Item(String key, Object component, String defaultValue) { + this.component = component; + this.defaultValue = defaultValue; + this.key = key; + } + } + + /** + * Private class to display an alert message when the file is not found. + */ + private class Msg extends JFrame { + + public Msg(String project, String msg) { + super(project); + GridBagLayout layout = new GridBagLayout(); + GridBagConstraints constraints = new GridBagConstraints(); + Container contentPane = getContentPane(); + contentPane.setLayout(layout); + constraints.weightx = 0.0; + constraints.weighty = 1.0; + constraints.gridx = 0; + constraints.gridy = 0; + constraints.gridwidth = 1; + constraints.gridheight = 1; + constraints.insets = new Insets(10, 10, 10, 10); + constraints.anchor = GridBagConstraints.CENTER; + JLabel newLabel = new JLabel(msg); + layout.setConstraints(newLabel, constraints); + contentPane.add(newLabel); + setResizable(false); + pack(); + setVisible(true); + Dimension dim = getToolkit().getScreenSize(); + Rectangle abounds = getBounds(); + setLocation((dim.width - abounds.width) / 2, (dim.height - abounds.height) / 2); + Timer timer = new Timer(1000, new DelayListener(this)); + timer.start(); + } + } + + /** + * Private class to dispose the message after 1 second. + */ + private class DelayListener implements ActionListener { + private Msg msg; + + public DelayListener(Msg msg) { + this.msg = msg; + } + + public void actionPerformed(ActionEvent evt) { + msg.dispose(); + } + } + +} diff --git a/src/bilib/src/additionaluserinterface/SpinnerDouble.java b/src/bilib/src/additionaluserinterface/SpinnerDouble.java new file mode 100644 index 0000000000000000000000000000000000000000..94a5909d9ec2eb4aa70ffecffbd5d6d186a4633c --- /dev/null +++ b/src/bilib/src/additionaluserinterface/SpinnerDouble.java @@ -0,0 +1,105 @@ +package additionaluserinterface; + +import javax.swing.JSpinner; +import javax.swing.SpinnerNumberModel; + +/** + * This class extends the generic JSpinner of Java for a specific JSpinner for + * double. It handles double type. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class SpinnerDouble extends JSpinner { + + private SpinnerNumberModel model; + + private double defValue; + private double minValue; + private double maxValue; + private double incValue; + + /** + * Constructor. + */ + public SpinnerDouble(double defValue, double minValue, double maxValue, double incValue) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Double def = new Double(defValue); + Double min = new Double(minValue); + Double max = new Double(maxValue); + Double inc = new Double(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Set the minimal and the maximal limit. + */ + public void setLimit(double minValue, double maxValue) { + this.minValue = minValue; + this.maxValue = maxValue; + double value = get(); + Double min = new Double(minValue); + Double max = new Double(maxValue); + Double inc = new Double(incValue); + defValue = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + Double def = new Double(defValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Set the incremental step. + */ + public void setIncrement(double incValue) { + this.incValue = incValue; + Double def = (Double) getModel().getValue(); + Double min = new Double(minValue); + Double max = new Double(maxValue); + Double inc = new Double(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Returns the incremental step. + */ + public double getIncrement() { + return incValue; + } + + /** + * Set the value in the JSpinner with clipping in the range [min..max]. + */ + public void set(double value) { + value = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + model.setValue(value); + } + + /** + * Return the value with clipping the value in the range [min..max]. + */ + public double get() { + if (model.getValue() instanceof Integer) { + Integer i = (Integer) model.getValue(); + double ii = i.intValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Double) { + Double i = (Double) model.getValue(); + double ii = i.doubleValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Float) { + Float i = (Float) model.getValue(); + double ii = i.floatValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + return 0.0; + } +} diff --git a/src/bilib/src/additionaluserinterface/SpinnerFloat.java b/src/bilib/src/additionaluserinterface/SpinnerFloat.java new file mode 100644 index 0000000000000000000000000000000000000000..1796e732a5e9d693588cd277c96e37f78c11ed80 --- /dev/null +++ b/src/bilib/src/additionaluserinterface/SpinnerFloat.java @@ -0,0 +1,106 @@ +package additionaluserinterface; + +import javax.swing.JSpinner; +import javax.swing.SpinnerNumberModel; + +/** + * This class extends the generic JSpinner of Java for a specific JSpinner for + * float. It handles float type. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class SpinnerFloat extends JSpinner { + + private SpinnerNumberModel model; + + private float defValue; + private float minValue; + private float maxValue; + private float incValue; + + /** + * Constructor. + */ + public SpinnerFloat(float defValue, float minValue, float maxValue, float incValue) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Float def = new Float(defValue); + Float min = new Float(minValue); + Float max = new Float(maxValue); + Float inc = new Float(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Set the minimal and the maximal limit. + */ + public void setLimit(float minValue, float maxValue) { + this.minValue = minValue; + this.maxValue = maxValue; + float value = get(); + Float min = new Float(minValue); + Float max = new Float(maxValue); + Float inc = new Float(incValue); + defValue = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + Float def = new Float(defValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Set the incremental step. + */ + public void setIncrement(float incValue) { + this.incValue = incValue; + Float def = (Float) getModel().getValue(); + Float min = new Float(minValue); + Float max = new Float(maxValue); + Float inc = new Float(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Returns the incremental step. + */ + public float getIncrement() { + return incValue; + } + + /** + * Set the value in the JSpinner with clipping in the range [min..max]. + */ + public void set(float value) { + value = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + model.setValue(value); + } + + /** + * Return the value without clipping the value in the range [min..max]. + */ + public float get() { + if (model.getValue() instanceof Integer) { + Integer i = (Integer) model.getValue(); + float ii = (float) i.intValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Double) { + Double i = (Double) model.getValue(); + float ii = (float) i.doubleValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Float) { + Float i = (Float) model.getValue(); + float ii = i.floatValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + return 0f; + } + +} diff --git a/src/bilib/src/additionaluserinterface/SpinnerInteger.java b/src/bilib/src/additionaluserinterface/SpinnerInteger.java new file mode 100644 index 0000000000000000000000000000000000000000..b4c7cb9b8b022bd205c6b5fc98c29687f4cc5280 --- /dev/null +++ b/src/bilib/src/additionaluserinterface/SpinnerInteger.java @@ -0,0 +1,104 @@ +package additionaluserinterface; + +import javax.swing.*; + +/** + * This class extends the generic JSpinner of Java for a specific JSpinner for + * integer. It handles int type. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class SpinnerInteger extends JSpinner { + + private SpinnerNumberModel model; + + private int defValue; + private int minValue; + private int maxValue; + private int incValue; + + /** + * Constructor. + */ + public SpinnerInteger(int defValue, int minValue, int maxValue, int incValue) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Integer def = new Integer(defValue); + Integer min = new Integer(minValue); + Integer max = new Integer(maxValue); + Integer inc = new Integer(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Set the minimal and the maximal limit. + */ + public void setLimit(int minValue, int maxValue) { + this.minValue = minValue; + this.maxValue = maxValue; + int value = get(); + Integer min = new Integer(minValue); + Integer max = new Integer(maxValue); + Integer inc = new Integer(incValue); + defValue = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + Integer def = new Integer(defValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Set the incremental step. + */ + public void setIncrement(int incValue) { + this.incValue = incValue; + Integer def = (Integer) getModel().getValue(); + Integer min = new Integer(minValue); + Integer max = new Integer(maxValue); + Integer inc = new Integer(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Returns the incremental step. + */ + public int getIncrement() { + return incValue; + } + + /** + * Set the value in the JSpinner with clipping in the range [min..max]. + */ + public void set(int value) { + value = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + model.setValue(value); + } + + /** + * Return the value without clipping the value in the range [min..max]. + */ + public int get() { + if (model.getValue() instanceof Integer) { + Integer i = (Integer) model.getValue(); + int ii = i.intValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Double) { + Double i = (Double) model.getValue(); + int ii = (int) i.doubleValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Float) { + Float i = (Float) model.getValue(); + int ii = (int) i.floatValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + return 0; + } +} diff --git a/src/bilib/src/additionaluserinterface/WalkBar.java b/src/bilib/src/additionaluserinterface/WalkBar.java new file mode 100644 index 0000000000000000000000000000000000000000..bd9496df19aa8bc36ee71d640acbebb4c98fa26b --- /dev/null +++ b/src/bilib/src/additionaluserinterface/WalkBar.java @@ -0,0 +1,356 @@ +package additionaluserinterface; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JProgressBar; +import javax.swing.JScrollPane; +import javax.swing.JToolBar; +import javax.swing.SwingUtilities; +import javax.swing.text.DefaultCaret; + +/** + * This class extends the JToolbar of Java to create a status bar including some + * of the following component ProgressBar, Help Button About Button and Close + * Button + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class WalkBar extends JToolBar implements ActionListener { + + private JProgressBar progress = new JProgressBar(); + private JButton bnHelp = new JButton("Help"); + private JButton bnAbout = new JButton("About"); + private JButton bnClose = new JButton("Close"); + private String about[] = { "About", "Version", "Description", "Author", "Biomedical Image Group", "2008", "http://bigwww.epfl.ch" }; + private String help; + private double chrono; + private int xSizeAbout = 400; + private int ySizeAbout = 400; + private int xSizeHelp = 400; + private int ySizeHelp = 400; + + /** + * Class SetValue in the swing thread. + */ + private static class SetValue implements Runnable { + private int value; + private JProgressBar progress; + + public SetValue(JProgressBar progress, int value) { + this.progress = progress; + this.value = value; + } + + public void run() { + progress.setValue(value); + } + } + + /** + * Class IncValue in the swing thread. + */ + private static class IncValue implements Runnable { + private double inc; + private JProgressBar progress; + + public IncValue(JProgressBar progress, double inc) { + this.progress = progress; + this.inc = inc; + } + + public void run() { + progress.setValue((int) Math.round(progress.getValue() + inc)); + } + } + + /** + * Class SetMessage in the swing thread. + */ + private static class SetMessage implements Runnable { + private String msg; + private JProgressBar progress; + + public SetMessage(JProgressBar progress, String msg) { + this.progress = progress; + this.msg = msg; + } + + public void run() { + progress.setString(msg); + } + } + + /** + * Constructor. + */ + public WalkBar() { + super("Walk Bar"); + build("", false, false, false, 100); + } + + public WalkBar(String initialMessage, boolean isAbout, boolean isHelp, boolean isClose) { + super("Walk Bar"); + build(initialMessage, isAbout, isHelp, isClose, 100); + } + + public WalkBar(String initialMessage, boolean isAbout, boolean isHelp, boolean isClose, int size) { + super("Walk Bar"); + build(initialMessage, isAbout, isHelp, isClose, size); + + } + + private void build(String initialMessage, boolean isAbout, boolean isHelp, boolean isClose, int size) { + if (isAbout) + add(bnAbout); + if (isHelp) + add(bnHelp); + addSeparator(); + add(progress); + addSeparator(); + if (isClose) + add(bnClose); + + progress.setStringPainted(true); + progress.setString(initialMessage); + // progress.setFont(new Font("Arial", Font.PLAIN, 20)); + progress.setMinimum(0); + progress.setMaximum(100); + progress.setPreferredSize(new Dimension(size, 20)); + bnAbout.addActionListener(this); + bnHelp.addActionListener(this); + + setFloatable(false); + setRollover(true); + setBorderPainted(false); + chrono = System.currentTimeMillis(); + } + + /** + * Implements the actionPerformed for the ActionListener. + */ + public synchronized void actionPerformed(ActionEvent e) { + if (e.getSource() == bnHelp) { + showHelp(); + } + else if (e.getSource() == bnAbout) { + showAbout(); + } + else if (e.getSource() == bnClose) { + } + } + + /** + * Return a reference to the Close button. + */ + public JButton getButtonClose() { + return bnClose; + } + + /** + * Set a value and a message in the progress bar. + */ + public void progress(String msg, int value) { + double elapsedTime = System.currentTimeMillis() - chrono; + String t = " [" + (elapsedTime > 3000 ? Math.round(elapsedTime / 10) / 100.0 + "s." : elapsedTime + "ms") + "]"; + SwingUtilities.invokeLater(new SetValue(progress, value)); + SwingUtilities.invokeLater(new SetMessage(progress, msg + t)); + } + + /** + * Set a value and a message in the progress bar. + */ + public void increment(double inc) { + SwingUtilities.invokeLater(new IncValue(progress, inc)); + } + + /** + * Set a value in the progress bar. + */ + public void setValue(int value) { + SwingUtilities.invokeLater(new SetValue(progress, value)); + } + + /** + * Set a message in the progress bar. + */ + public void setMessage(String msg) { + SwingUtilities.invokeLater(new SetMessage(progress, msg)); + } + + /** + * Set a value and a message in the progress bar. + */ + public void progress(String msg, double value) { + progress(msg, (int) Math.round(value)); + } + + /** + * Set to 0 the progress bar. + */ + public void reset() { + chrono = System.currentTimeMillis(); + progress("Start", 0); + } + + /** + * Set to 100 the progress bar. + */ + public void finish() { + progress("End", 100); + } + + /** + * Set to 100 the progress bar with an additional message. + */ + public void finish(String msg) { + progress(msg, 100); + } + + /** + * Specify the content of the About window. + */ + public void fillAbout(String name, String version, String description, String author, String organisation, String date, String info) { + this.about[0] = name; + this.about[1] = version; + this.about[2] = description; + this.about[3] = author; + this.about[4] = organisation; + this.about[5] = date; + this.about[6] = info; + } + + /** + * Specify the content of the Help window. + */ + public void fillHelp(String help) { + this.help = help; + } + + /** + * Show the content of the About window. + */ + public void showAbout() { + + final JFrame frame = new JFrame("About " + about[0]); + JEditorPane pane = new JEditorPane(); + pane.setEditable(false); + pane.setContentType("text/html; charset=ISO-8859-1"); + pane.setText("<html><head><title>" + about[0] + "</title>" + getStyle() + "</head><body>" + (about[0] == "" ? "" : "<p class=\"name\">" + about[0] + "</p>") + + // Name + (about[1] == "" ? "" : "<p class=\"vers\">" + about[1] + "</p>") + + // Version + (about[2] == "" ? "" : "<p class=\"desc\">" + about[2] + "</p><hr>") + + // Description + (about[3] == "" ? "" : "<p class=\"auth\">" + about[3] + "</p>") + + // author + (about[4] == "" ? "" : "<p class=\"orga\">" + about[4] + "</p>") + (about[5] == "" ? "" : "<p class=\"date\">" + about[5] + "</p>") + + (about[6] == "" ? "" : "<p class=\"more\">" + about[6] + "</p>") + "</html>"); + + final JButton bnClose = new JButton("Close"); + bnClose.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + frame.dispose(); + } + }); + pane.setCaret(new DefaultCaret()); + JScrollPane scrollPane = new JScrollPane(pane); + // helpScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + scrollPane.setPreferredSize(new Dimension(xSizeAbout, ySizeAbout)); + frame.getContentPane().add(scrollPane, BorderLayout.NORTH); + frame.getContentPane().add(bnClose, BorderLayout.CENTER); + + frame.pack(); + frame.setResizable(false); + frame.setVisible(true); + center(frame); + } + + /** + * Show the content of the Help window of a given size. + */ + public void showHelp() { + final JFrame frame = new JFrame("Help " + about[0]); + JEditorPane pane = new JEditorPane(); + pane.setEditable(false); + pane.setContentType("text/html; charset=ISO-8859-1"); + pane.setText("<html><head><title>" + about[0] + "</title>" + getStyle() + "</head><body>" + (about[0] == "" ? "" : "<p class=\"name\">" + about[0] + "</p>") + // Name + (about[1] == "" ? "" : "<p class=\"vers\">" + about[1] + "</p>") + // Version + (about[2] == "" ? "" : "<p class=\"desc\">" + about[2] + "</p>") + // Description + "<hr><p class=\"help\">" + help + "</p>" + "</html>"); + final JButton bnClose = new JButton("Close"); + bnClose.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + frame.dispose(); + } + }); + pane.setCaret(new DefaultCaret()); + JScrollPane scrollPane = new JScrollPane(pane); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + scrollPane.setPreferredSize(new Dimension(xSizeHelp, ySizeHelp)); + frame.setPreferredSize(new Dimension(xSizeHelp, ySizeHelp)); + frame.getContentPane().add(scrollPane, BorderLayout.CENTER); + frame.getContentPane().add(bnClose, BorderLayout.SOUTH); + frame.setVisible(true); + frame.pack(); + center(frame); + } + + /* + * Place the window in the center of the screen. + */ + private void center(Window w) { + Dimension screenSize = new Dimension(0, 0); + boolean isWin = System.getProperty("os.name").startsWith("Windows"); + if (isWin) { // GraphicsEnvironment.getConfigurations is *very* slow on + // Windows + screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + } + if (GraphicsEnvironment.isHeadless()) + screenSize = new Dimension(0, 0); + else { + // Can't use Toolkit.getScreenSize() on Linux because it returns + // size of all displays rather than just the primary display. + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gd = ge.getScreenDevices(); + GraphicsConfiguration[] gc = gd[0].getConfigurations(); + Rectangle bounds = gc[0].getBounds(); + if (bounds.x == 0 && bounds.y == 0) + screenSize = new Dimension(bounds.width, bounds.height); + else + screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + } + Dimension window = w.getSize(); + if (window.width == 0) + return; + int left = screenSize.width / 2 - window.width / 2; + int top = (screenSize.height - window.height) / 4; + if (top < 0) + top = 0; + w.setLocation(left, top); + } + + /* + * Defines the CSS style for the help and about window. + */ + private String getStyle() { + return "<style type=text/css>" + "body {backgroud-color:#222277}" + "hr {width:80% color:#333366; padding-top:7px }" + + "p, li {margin-left:10px;margin-right:10px; color:#000000; font-size:1em; font-family:Verdana,Helvetica,Arial,Geneva,Swiss,SunSans-Regular,sans-serif}" + + "p.name {color:#ffffff; font-size:1.2em; font-weight: bold; background-color: #333366; text-align:center;}" + "p.vers {color:#333333; text-align:center;}" + + "p.desc {color:#333333; font-weight: bold; text-align:center;}" + "p.auth {color:#333333; font-style: italic; text-align:center;}" + + "p.orga {color:#333333; text-align:center;}" + "p.date {color:#333333; text-align:center;}" + "p.more {color:#333333; text-align:center;}" + + "p.help {color:#000000; text-align:left;}" + "</style>"; + } +} diff --git a/src/bilib/src/bilib.zip b/src/bilib/src/bilib.zip new file mode 100644 index 0000000000000000000000000000000000000000..2ef6e196c2d25c8eb2717582cab0ae148956c022 Binary files /dev/null and b/src/bilib/src/bilib.zip differ diff --git a/src/bilib/src/bilib/.DS_Store b/src/bilib/src/bilib/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2dae4405c103007dd70cd4f46b3f7f99458b776a Binary files /dev/null and b/src/bilib/src/bilib/.DS_Store differ diff --git a/src/bilib/src/bilib/commons.zip b/src/bilib/src/bilib/commons.zip new file mode 100644 index 0000000000000000000000000000000000000000..cd3f5e1a05f420e086e25203b7b333f7fabb00a1 Binary files /dev/null and b/src/bilib/src/bilib/commons.zip differ diff --git a/src/bilib/src/bilib/commons/.DS_Store b/src/bilib/src/bilib/commons/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..05370983747f7d8fa1271a67dd854d587f24703c Binary files /dev/null and b/src/bilib/src/bilib/commons/.DS_Store differ diff --git a/src/bilib/src/bilib/commons/buttons/ButtonFactory.java b/src/bilib/src/bilib/commons/buttons/ButtonFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..67bb752061649188f6bdd7093e8cd53ab2a01db0 --- /dev/null +++ b/src/bilib/src/bilib/commons/buttons/ButtonFactory.java @@ -0,0 +1,89 @@ +package bilib.commons.buttons; + +import java.awt.Dimension; +import java.net.URL; + +import javax.swing.ImageIcon; +import javax.swing.JButton; + +public class ButtonFactory { + + private static JButton icon(JButton bn) { + URL url = ButtonFactory.class.getResource(bn.getText().toLowerCase() +".png"); + if (url != null) { + ImageIcon icon = new ImageIcon(url, ""); + if (icon != null) { + JButton bni = new JButton(icon); + Dimension d = new Dimension(icon.getIconWidth(), icon.getIconHeight()+2); + bni.setMaximumSize(d); + bni.setPreferredSize(d); + return bni; + } + } + return bn; + } + + public static JButton about(boolean tryIcon) { + JButton bn = new JButton("About"); + if (tryIcon == true) + bn = icon(bn); + bn.setToolTipText("About ..."); + return bn; + } + + public static JButton close(boolean tryIcon) { + JButton bn = new JButton("Close"); + if (tryIcon == true) + bn = icon(bn); + bn.setToolTipText("Save the settings and close"); + return bn; + } + + public static JButton prefs(boolean tryIcon) { + JButton bn = new JButton("Prefs"); + if (tryIcon == true) + bn = icon(bn); + bn.setToolTipText("Manage the settings"); + return bn; + } + + public static JButton help(boolean tryIcon) { + JButton bn = new JButton("Help"); + if (tryIcon == true) + bn = icon(bn); + bn.setToolTipText("Get online help"); + return bn; + } + + public static JButton run(boolean tryIcon) { + JButton bn = new JButton("Run"); + if (tryIcon == true) + bn = icon(bn); + bn.setToolTipText("Start the processing"); + return bn; + } + + public static JButton save(boolean tryIcon) { + JButton bn = new JButton("Save"); + if (tryIcon == true) + bn = icon(bn); + bn.setToolTipText("Save"); + return bn; + } + + public static JButton snapshot(boolean tryIcon) { + JButton bn = new JButton("Snapshot"); + if (tryIcon == true) + bn = icon(bn); + bn.setToolTipText("Snapshot"); + return bn; + } + + public static JButton stop(boolean tryIcon) { + JButton bn = new JButton("Stop"); + if (tryIcon == true) + bn = icon(bn); + bn.setToolTipText("Abort the processing"); + return bn; + } +} diff --git a/src/bilib/src/bilib/commons/buttons/about.png b/src/bilib/src/bilib/commons/buttons/about.png new file mode 100644 index 0000000000000000000000000000000000000000..8b79af592e1b717d318a6d70da2a964e608a24ab Binary files /dev/null and b/src/bilib/src/bilib/commons/buttons/about.png differ diff --git a/src/bilib/src/bilib/commons/buttons/close.png b/src/bilib/src/bilib/commons/buttons/close.png new file mode 100644 index 0000000000000000000000000000000000000000..253ac8afeb193e2825e59d50da8a80e8d763a925 Binary files /dev/null and b/src/bilib/src/bilib/commons/buttons/close.png differ diff --git a/src/bilib/src/bilib/commons/buttons/help.png b/src/bilib/src/bilib/commons/buttons/help.png new file mode 100644 index 0000000000000000000000000000000000000000..3549c560cdb5700c0abc0c0caedcfb2149c72554 Binary files /dev/null and b/src/bilib/src/bilib/commons/buttons/help.png differ diff --git a/src/bilib/src/bilib/commons/buttons/prefs.png b/src/bilib/src/bilib/commons/buttons/prefs.png new file mode 100644 index 0000000000000000000000000000000000000000..611406224177d9adcce8bf124ffca437c55db12b Binary files /dev/null and b/src/bilib/src/bilib/commons/buttons/prefs.png differ diff --git a/src/bilib/src/bilib/commons/buttons/run.png b/src/bilib/src/bilib/commons/buttons/run.png new file mode 100644 index 0000000000000000000000000000000000000000..b5f15e97e4ac0a80ea5c571b7e202948dfdb0417 Binary files /dev/null and b/src/bilib/src/bilib/commons/buttons/run.png differ diff --git a/src/bilib/src/bilib/commons/buttons/save.png b/src/bilib/src/bilib/commons/buttons/save.png new file mode 100644 index 0000000000000000000000000000000000000000..3133d5a0e2654587d7151057b1355d27cc4b006e Binary files /dev/null and b/src/bilib/src/bilib/commons/buttons/save.png differ diff --git a/src/bilib/src/bilib/commons/buttons/snapshot.png b/src/bilib/src/bilib/commons/buttons/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd56b514729b3e114e688cab15fe1f02fa81ab7 Binary files /dev/null and b/src/bilib/src/bilib/commons/buttons/snapshot.png differ diff --git a/src/bilib/src/bilib/commons/buttons/stop.png b/src/bilib/src/bilib/commons/buttons/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..ed24ea55c7d256a163ccc32d2d93cb5686371e75 Binary files /dev/null and b/src/bilib/src/bilib/commons/buttons/stop.png differ diff --git a/src/bilib/src/bilib/commons/components/BorderToggledButton.java b/src/bilib/src/bilib/commons/components/BorderToggledButton.java new file mode 100644 index 0000000000000000000000000000000000000000..a3f4ccb41214c34e1c1d8bbb95fc1b6f92417eee --- /dev/null +++ b/src/bilib/src/bilib/commons/components/BorderToggledButton.java @@ -0,0 +1,54 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.components; + +import java.awt.Insets; + +import javax.swing.JButton; + +public class BorderToggledButton extends JButton { + + private String text = ""; + public BorderToggledButton(String text) { + super(text); + this.text = text; + setMargin(new Insets(1, 1, 1, 1)); + } + + @Override + public void setSelected(boolean selected) { + if (selected) + setText("<html><b>" + text + "</b></html>"); + else + setText(text); + } +} diff --git a/src/bilib/src/bilib/commons/components/DoubleScrollablePanel.java b/src/bilib/src/bilib/commons/components/DoubleScrollablePanel.java new file mode 100644 index 0000000000000000000000000000000000000000..c91aedca90920d8c474466b412434a7a04fdfa84 --- /dev/null +++ b/src/bilib/src/bilib/commons/components/DoubleScrollablePanel.java @@ -0,0 +1,73 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.components; + +import java.awt.Dimension; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; + +/** + * This class extends the JSplitPane to create two scrollable panel splitted in + * the vertical direction. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ + +public class DoubleScrollablePanel extends JSplitPane { + + public DoubleScrollablePanel(int hpref1, JComponent panel1, int hpref2, JComponent panel2) { + super(JSplitPane.VERTICAL_SPLIT); + int hmin = 70; + JScrollPane scroll1 = new JScrollPane(panel1); + scroll1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scroll1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + scroll1.setBorder(BorderFactory.createEmptyBorder()); + scroll1.setMinimumSize(new Dimension(200, hmin)); + scroll1.setPreferredSize(new Dimension(200, hpref1)); + add(scroll1, 1); + + JScrollPane scroll2 = new JScrollPane(panel2); + scroll2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scroll2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + scroll2.setBorder(BorderFactory.createEmptyBorder()); + scroll2.setMinimumSize(new Dimension(200, hmin)); + scroll2.setPreferredSize(new Dimension(200, hpref2)); + add(scroll2, 1); + setOneTouchExpandable(true); + setBorder(BorderFactory.createEtchedBorder()); + } + +} diff --git a/src/bilib/src/bilib/commons/components/GridPanel.java b/src/bilib/src/bilib/commons/components/GridPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..3bdcba25def121a806d7ea24c4f2b334dba0ea0c --- /dev/null +++ b/src/bilib/src/bilib/commons/components/GridPanel.java @@ -0,0 +1,200 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.components; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +/** + * This class extends the JPanel to create grid panel given the possibility to + * place Java components in an organized manner in the dialog box. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class GridPanel extends JPanel { + + private static final long serialVersionUID = 1L; + private GridBagLayout layout = new GridBagLayout(); + private GridBagConstraints constraint = new GridBagConstraints(); + private int defaultSpace = 3; + + /** + * Constructor. + */ + public GridPanel() { + super(); + setLayout(layout); + setBorder(BorderFactory.createEtchedBorder()); + } + + /** + * Constructor. + */ + public GridPanel(int defaultSpace) { + super(); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createEtchedBorder()); + } + + /** + * Constructor. + */ + public GridPanel(boolean border) { + super(); + setLayout(layout); + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + } + + /** + * Constructor. + */ + public GridPanel(String title) { + super(); + setLayout(layout); + setBorder(BorderFactory.createTitledBorder(title)); + } + + /** + * Constructor. + */ + public GridPanel(boolean border, int defaultSpace) { + super(); + setLayout(layout); + this.defaultSpace = defaultSpace; + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + } + + /** + * Constructor. + */ + public GridPanel(String title, int defaultSpace) { + super(); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createTitledBorder(title)); + } + + /** + * Specify the defaultSpace. + */ + public void setSpace(int defaultSpace) { + this.defaultSpace = defaultSpace; + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, String label) { + place(row, col, 1, 1, defaultSpace, new JLabel(label)); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int space, String label) { + place(row, col, 1, 1, space, new JLabel(label)); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, String label) { + place(row, col, width, height, defaultSpace, new JLabel(label)); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, JComponent comp) { + place(row, col, 1, 1, defaultSpace, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int space, JComponent comp) { + place(row, col, 1, 1, space, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, JComponent comp) { + place(row, col, width, height, defaultSpace, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, int space, JComponent comp) { + if (comp == null) + return; + constraint.gridx = col; + constraint.gridy = row; + constraint.gridwidth = width; + constraint.gridheight = height; + constraint.anchor = GridBagConstraints.NORTHWEST; + constraint.insets = new Insets(space, space, space, space); + constraint.fill = GridBagConstraints.HORIZONTAL; + layout.setConstraints(comp, constraint); + add(comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, int spaceHorizontal, int spaceVertical, JComponent comp) { + if (comp == null) + return; + constraint.gridx = col; + constraint.gridy = row; + constraint.gridwidth = width; + constraint.gridheight = height; + constraint.anchor = GridBagConstraints.NORTHWEST; + constraint.insets = new Insets(spaceVertical, spaceHorizontal, spaceHorizontal, spaceVertical); + constraint.fill = GridBagConstraints.HORIZONTAL; + layout.setConstraints(comp, constraint); + add(comp); + } +} diff --git a/src/bilib/src/bilib/commons/components/GridToolbar.java b/src/bilib/src/bilib/commons/components/GridToolbar.java new file mode 100644 index 0000000000000000000000000000000000000000..ffb8d5e13f6a26b7143badae50191eb38aa18e44 --- /dev/null +++ b/src/bilib/src/bilib/commons/components/GridToolbar.java @@ -0,0 +1,246 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.components; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JToolBar; + +/** + * This class extends the JToolbar to create grid panel given the possibility to + * place Java components in an organized manner in the dialog box. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class GridToolbar extends JToolBar { + + private GridBagLayout layout = new GridBagLayout(); + private GridBagConstraints constraint = new GridBagConstraints(); + private int defaultSpace = 3; + + /** + * Constructor. + */ + public GridToolbar() { + super("Control"); + setLayout(layout); + setBorder(BorderFactory.createEtchedBorder()); + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(boolean border) { + super("Control"); + setLayout(layout); + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(String title) { + super(title); + setLayout(layout); + setBorder(BorderFactory.createTitledBorder(title)); + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(int defaultSpace) { + super("Control"); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createEtchedBorder()); + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(boolean border, int defaultSpace) { + super("Control"); + setLayout(layout); + this.defaultSpace = defaultSpace; + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(boolean border, int defaultSpace, boolean floatable) { + super("Control"); + setLayout(layout); + this.defaultSpace = defaultSpace; + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + setFloatable(floatable); + } + + /** + * Constructor. + */ + public GridToolbar(boolean border, boolean floatable) { + super("Control"); + setLayout(layout); + if (border) { + setBorder(BorderFactory.createEtchedBorder()); + } + setFloatable(floatable); + } + + /** + * Constructor. + */ + public GridToolbar(String title, boolean floatable) { + super(title); + setLayout(layout); + setBorder(BorderFactory.createTitledBorder(title)); + setFloatable(floatable); + } + + /** + * Constructor. + */ + public GridToolbar(int defaultSpace, boolean floatable) { + super("Control"); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createEtchedBorder()); + setFloatable(floatable); + } + + /** + * Constructor. + */ + public GridToolbar(String title, int defaultSpace) { + super(title); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createTitledBorder(title)); + setFloatable(false); + } + + /** + * Constructor. + */ + public GridToolbar(String title, int defaultSpace, boolean floatable) { + super(title); + setLayout(layout); + this.defaultSpace = defaultSpace; + setBorder(BorderFactory.createTitledBorder(title)); + setFloatable(floatable); + } + + /** + * Specify the defaultSpace. + */ + public void setSpace(int defaultSpace) { + this.defaultSpace = defaultSpace; + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, String label) { + place(row, col, 1, 1, defaultSpace, new JLabel(label)); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int space, String label) { + place(row, col, 1, 1, space, new JLabel(label)); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, String label) { + place(row, col, width, height, defaultSpace, new JLabel(label)); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, JComponent comp) { + place(row, col, 1, 1, defaultSpace, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int space, JComponent comp) { + place(row, col, 1, 1, space, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, JComponent comp) { + place(row, col, width, height, defaultSpace, comp); + } + + /** + * Place a component in the northwest of the cell. + */ + public void place(int row, int col, int width, int height, int space, JComponent comp) { + if (comp == null) + return; + constraint.gridx = col; + constraint.gridy = row; + constraint.gridwidth = width; + constraint.gridheight = height; + constraint.anchor = GridBagConstraints.NORTHWEST; + constraint.insets = new Insets(space, space, space, space); + constraint.fill = GridBagConstraints.HORIZONTAL; + layout.setConstraints(comp, constraint); + add(comp); + } + +} diff --git a/src/bilib/src/bilib/commons/components/HTMLPane.java b/src/bilib/src/bilib/commons/components/HTMLPane.java new file mode 100644 index 0000000000000000000000000000000000000000..676e07915b67b0376cb7fa8bfe785fc4f3c1bc6e --- /dev/null +++ b/src/bilib/src/bilib/commons/components/HTMLPane.java @@ -0,0 +1,141 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.components; + +import java.awt.Dimension; + +import javax.swing.JEditorPane; +import javax.swing.JScrollPane; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; + +/** + * This class extends the Java JEditorPane to make a easy to use panel to + * display HTML information. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class HTMLPane extends JEditorPane { + + private String html = ""; + private String header = ""; + private String footer = ""; + private Dimension dim; + private String font = "verdana"; + private String color = "#222222"; + private String background = "#f8f8f8"; + + public HTMLPane() { + create(); + } + + public HTMLPane(String font) { + this.font = font; + create(); + } + + public HTMLPane(int width, int height) { + this.dim = new Dimension(width, height); + create(); + } + + public HTMLPane(String font, int width, int height) { + this.font = font; + this.dim = new Dimension(width, height); + create(); + } + + public HTMLPane(String font, String color, String background, int width, int height) { + this.font = font; + this.dim = new Dimension(width, height); + this.color = color; + this.background = background; + create(); + } + + @Override + public String getText() { + Document doc = this.getDocument(); + try { + return doc.getText(0, doc.getLength()); + } + catch (BadLocationException e) { + e.printStackTrace(); + return getText(); + } + } + + public void clear() { + html = ""; + append(""); + } + + private void create() { + header += "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n"; + header += "<html><head>\n"; + header += "<style>body {background-color:" + background + "; color:" + color + "; font-family: " + font + ";margin:4px}</style>\n"; + header += "<style>h1 {color:#555555; font-size:1.0em; font-weight:bold; padding:1px; margin:1px;}</style>\n"; + header += "<style>h2 {color:#333333; font-size:0.9em; font-weight:bold; padding:1px; margin:1px;}</style>\n"; + header += "<style>h3 {color:#000000; font-size:0.9em; font-weight:italic; padding:1px; margin:1px;}</style>\n"; + header += "<style>p {color:" + color + "; font-size:0.9em; padding:1px; margin:0px;}</style>\n"; + header += "</head>\n"; + header += "<body>\n"; + footer += "</body></html>\n"; + setEditable(false); + setContentType("text/html; charset=ISO-8859-1"); + } + + public void append(String content) { + html += content; + setText(header + html + footer); + if (dim != null) { + setPreferredSize(dim); + } + setCaretPosition(0); + } + + public void append(String tag, String content) { + html += "<" + tag + ">" + content + "</" + tag + ">"; + setText(header + html + footer); + if (dim != null) { + setPreferredSize(dim); + } + setCaretPosition(0); + } + + public JScrollPane getPane() { + JScrollPane scroll = new JScrollPane(this, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scroll.setPreferredSize(dim); + return scroll; + } +} diff --git a/src/bilib/src/bilib/commons/components/SpinnerRangeDouble.java b/src/bilib/src/bilib/commons/components/SpinnerRangeDouble.java new file mode 100644 index 0000000000000000000000000000000000000000..f67a8cb51a9cffa3dd0033cfdcb53440e70ce422 --- /dev/null +++ b/src/bilib/src/bilib/commons/components/SpinnerRangeDouble.java @@ -0,0 +1,197 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.components; + +import javax.swing.JFormattedTextField; +import javax.swing.JSpinner; +import javax.swing.SpinnerNumberModel; + +/** + * This class extends the Java Swing JSpinner to make a easy to use spinner for + * double. It handles double type. The size can be control by the number of + * visible chars or by a specific format (NumberEditor). + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class SpinnerRangeDouble extends JSpinner { + + private SpinnerNumberModel model; + + private double defValue; + private double minValue; + private double maxValue; + private double incValue; + + /** + * Constructor. + */ + public SpinnerRangeDouble(double defValue, double minValue, double maxValue, double incValue) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Double def = new Double(defValue); + Double min = new Double(minValue); + Double max = new Double(maxValue); + Double inc = new Double(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); + tf.setColumns(7); + } + + /** + * Constructor. + */ + public SpinnerRangeDouble(double defValue, double minValue, double maxValue, double incValue, String format) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Double def = new Double(defValue); + Double min = new Double(minValue); + Double max = new Double(maxValue); + Double inc = new Double(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + setEditor(new JSpinner.NumberEditor(this, format)); + JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); + tf.setColumns(7); + } + + /** + * Constructor. + */ + public SpinnerRangeDouble(double defValue, double minValue, double maxValue, double incValue, int visibleChars) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Double def = new Double(defValue); + Double min = new Double(minValue); + Double max = new Double(maxValue); + Double inc = new Double(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); + tf.setColumns(visibleChars); + } + + /** + * Set the format of the numerical value. + */ + public void setFormat(String format) { + setEditor(new JSpinner.NumberEditor(this, format)); + } + + /** + * Set the minimal and the maximal limit. + */ + public void setLimit(double minValue, double maxValue) { + this.minValue = minValue; + this.maxValue = maxValue; + double value = get(); + Double min = new Double(minValue); + Double max = new Double(maxValue); + Double inc = new Double(incValue); + defValue = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + Double def = new Double(defValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Set the incremental step. + */ + public void setIncrement(double incValue) { + this.incValue = incValue; + Double def = (Double) getModel().getValue(); + Double min = new Double(minValue); + Double max = new Double(maxValue); + Double inc = new Double(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Returns the incremental step. + */ + public double getIncrement() { + return incValue; + } + + /** + * Set the value in the JSpinner with clipping in the range [min..max]. + */ + public void set(double value) { + value = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + model.setValue(new Double(value)); + } + + /** + * Return the value with clipping the value in the range [min..max]. + */ + public double get() { + if (model.getValue() instanceof Integer) { + Integer i = (Integer) model.getValue(); + double ii = i.intValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Double) { + Double i = (Double) model.getValue(); + double ii = i.doubleValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Float) { + Float i = (Float) model.getValue(); + double ii = i.floatValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + return 0.0; + } + + public double getRangeMaximum() { + return maxValue; + } + + public double getRangeMinimum() { + return minValue; + } + +} diff --git a/src/bilib/src/bilib/commons/components/SpinnerRangeFloat.java b/src/bilib/src/bilib/commons/components/SpinnerRangeFloat.java new file mode 100644 index 0000000000000000000000000000000000000000..3ee802ad8c4fdd02d13d1d8e3ed3a173b0f58914 --- /dev/null +++ b/src/bilib/src/bilib/commons/components/SpinnerRangeFloat.java @@ -0,0 +1,197 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.components; + +import javax.swing.JFormattedTextField; +import javax.swing.JSpinner; +import javax.swing.SpinnerNumberModel; + +/** + * This class extends the Java Swing JSpinner to make a easy to use spinner for + * float. It handles float type. The size can be control by the number of + * visible chars or by a specific format (NumberEditor). + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class SpinnerRangeFloat extends JSpinner { + + private SpinnerNumberModel model; + + private float defValue; + private float minValue; + private float maxValue; + private float incValue; + + /** + * Constructor. + */ + public SpinnerRangeFloat(float defValue, float minValue, float maxValue, float incValue) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Float def = new Float(defValue); + Float min = new Float(minValue); + Float max = new Float(maxValue); + Float inc = new Float(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); + tf.setColumns(7); + } + + /** + * Constructor. + */ + public SpinnerRangeFloat(float defValue, float minValue, float maxValue, float incValue, String format) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Double def = new Double(defValue); + Double min = new Double(minValue); + Double max = new Double(maxValue); + Double inc = new Double(incValue); + this.model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + setEditor(new JSpinner.NumberEditor(this, format)); + JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); + tf.setColumns(7); + } + + /** + * Constructor. + */ + public SpinnerRangeFloat(float defValue, float minValue, float maxValue, float incValue, int visibleChars) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Float def = new Float(defValue); + Float min = new Float(minValue); + Float max = new Float(maxValue); + Float inc = new Float(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); + tf.setColumns(visibleChars); + } + + /** + * Set the format of the numerical value. + */ + public void setFormat(String format) { + setEditor(new JSpinner.NumberEditor(this, format)); + } + + /** + * Set the minimal and the maximal limit. + */ + public void setLimit(float minValue, float maxValue) { + this.minValue = minValue; + this.maxValue = maxValue; + float value = get(); + Float min = new Float(minValue); + Float max = new Float(maxValue); + Float inc = new Float(incValue); + defValue = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + Float def = new Float(defValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Set the incremental step. + */ + public void setIncrement(float incValue) { + this.incValue = incValue; + Float def = (Float) getModel().getValue(); + Float min = new Float(minValue); + Float max = new Float(maxValue); + Float inc = new Float(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Returns the incremental step. + */ + public float getIncrement() { + return incValue; + } + + /** + * Set the value in the JSpinner with clipping in the range [min..max]. + */ + public void set(float value) { + value = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + model.setValue(new Float(value)); + } + + /** + * Return the value without clipping the value in the range [min..max]. + */ + public float get() { + if (model.getValue() instanceof Integer) { + Integer i = (Integer) model.getValue(); + float ii = (float) i.intValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Double) { + Double i = (Double) model.getValue(); + float ii = (float) i.doubleValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Float) { + Float i = (Float) model.getValue(); + float ii = i.floatValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + return 0f; + } + + public float getRangeMaximum() { + return maxValue; + } + + public float getRangeMinimum() { + return minValue; + } + +} diff --git a/src/bilib/src/bilib/commons/components/SpinnerRangeInteger.java b/src/bilib/src/bilib/commons/components/SpinnerRangeInteger.java new file mode 100644 index 0000000000000000000000000000000000000000..a9b345f0d5416dd183467e6395db18705c36e732 --- /dev/null +++ b/src/bilib/src/bilib/commons/components/SpinnerRangeInteger.java @@ -0,0 +1,196 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.components; + +import javax.swing.JFormattedTextField; +import javax.swing.JSpinner; +import javax.swing.SpinnerNumberModel; + +/** + * This class extends the Java Swing JSpinner to make a easy to use spinner for + * integer. It handles int type. The size can be control by the number of + * visible chars or by a specific format (NumberEditor). + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class SpinnerRangeInteger extends JSpinner { + + private SpinnerNumberModel model; + + private int defValue; + private int minValue; + private int maxValue; + private int incValue; + + /** + * Constructor. + */ + public SpinnerRangeInteger(int defValue, int minValue, int maxValue, int incValue) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Integer def = new Integer(defValue); + Integer min = new Integer(minValue); + Integer max = new Integer(maxValue); + Integer inc = new Integer(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); + tf.setColumns(7); + } + + /** + * Constructor. + */ + public SpinnerRangeInteger(int defValue, int minValue, int maxValue, int incValue, String format) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Integer def = new Integer(defValue); + Integer min = new Integer(minValue); + Integer max = new Integer(maxValue); + Integer inc = new Integer(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + setEditor(new JSpinner.NumberEditor(this, format)); + JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); + tf.setColumns(format.length()); + } + + /** + * Constructor. + */ + public SpinnerRangeInteger(int defValue, int minValue, int maxValue, int incValue, int visibleChars) { + super(); + this.defValue = defValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.incValue = incValue; + + Integer def = new Integer(defValue); + Integer min = new Integer(minValue); + Integer max = new Integer(maxValue); + Integer inc = new Integer(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField(); + tf.setColumns(visibleChars); + } + + /** + * Set the format of the numerical value. + */ + public void setFormat(String format) { + setEditor(new JSpinner.NumberEditor(this, format)); + } + + /** + * Set the minimal and the maximal limit. + */ + public void setLimit(int minValue, int maxValue) { + this.minValue = minValue; + this.maxValue = maxValue; + int value = get(); + Integer min = new Integer(minValue); + Integer max = new Integer(maxValue); + Integer inc = new Integer(incValue); + defValue = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + Integer def = new Integer(defValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Set the incremental step. + */ + public void setIncrement(int incValue) { + this.incValue = incValue; + Integer def = (Integer) getModel().getValue(); + Integer min = new Integer(minValue); + Integer max = new Integer(maxValue); + Integer inc = new Integer(incValue); + model = new SpinnerNumberModel(def, min, max, inc); + setModel(model); + } + + /** + * Returns the incremental step. + */ + public int getIncrement() { + return incValue; + } + + /** + * Set the value in the JSpinner with clipping in the range [min..max]. + */ + public void set(int value) { + value = (value > maxValue ? maxValue : (value < minValue ? minValue : value)); + model.setValue(new Integer(value)); + } + + /** + * Return the value without clipping the value in the range [min..max]. + */ + public int get() { + if (model.getValue() instanceof Integer) { + Integer i = (Integer) model.getValue(); + int ii = i.intValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Double) { + Double i = (Double) model.getValue(); + int ii = (int) i.doubleValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + else if (model.getValue() instanceof Float) { + Float i = (Float) model.getValue(); + int ii = (int) i.floatValue(); + return (ii > maxValue ? maxValue : (ii < minValue ? minValue : ii)); + } + return 0; + } + + public int getRangeMaximum() { + return maxValue; + } + + public int getRangeMinimum() { + return minValue; + } +} diff --git a/src/bilib/src/bilib/commons/fft/BasicFFT.java b/src/bilib/src/bilib/commons/fft/BasicFFT.java new file mode 100644 index 0000000000000000000000000000000000000000..c60e1012b6a36b28b339e6118a4fe1deda14cab3 --- /dev/null +++ b/src/bilib/src/bilib/commons/fft/BasicFFT.java @@ -0,0 +1,234 @@ +package bilib.commons.fft; + +/** + * Performs a 2D or 1D (double) Fourier transformation using a basic FFT + * algorithm. It is only a a size of signal which in a power of 2. The 2D signal + * are store in a 1D double array in row-major convention. The complex value are + * store in a additional dimension [2]. + * + * @author Daniel Sage + */ + +public class BasicFFT { + + /** + * Creates the real frequency part of the Fourier space with the array + * realFunction using hermitian symmetry. The imaginary part is set to zero. + */ + public double[] fillHermitian2D(double[][] realFunction) { + int xsize = (realFunction.length - 1); + int ysize = (realFunction[0].length - 1); + int nx = xsize * 2; + int ny = ysize * 2; + double[] signal = new double[nx * ny]; + for (int y = 0; y <= ysize; y++) + for (int x = 0; x <= xsize; x++) { + signal[x + nx * (y)] = realFunction[x][y]; + } + for (int y = 0; y < ysize; y++) + for (int x = 0; x < xsize; x++) { + signal[nx - 1 - x + nx * (y)] = realFunction[x + 1][y]; + signal[nx - 1 - x + nx * (ny - 1 - y)] = realFunction[x + 1][y + 1]; + signal[x + nx * (ny - 1 - y)] = realFunction[x][y + 1]; + } + return signal; + } + + /** + * Performs the 2D FFT (Cooley Tukey). Signal's size has to be a power of + * two : 2^n. Return a complex signal. + */ + public double[][] transform2D(double real[], double imag[], int nx, int ny) { + + double[][] signal = new double[2][nx * ny]; + + double rowReal[] = new double[nx]; + double rowImag[] = new double[nx]; + + for (int y = 0; y < ny; y++) { + for (int x = 0; x < nx; x++) { + rowReal[x] = real[x + y * nx]; + rowImag[x] = imag[x + y * nx]; + } + transform1D(rowReal, rowImag); + for (int x = 0; x < nx; x++) { + signal[0][x + nx * (y)] = rowReal[x]; + signal[1][x + nx * (y)] = rowImag[x]; + } + } + double colReal[] = new double[ny]; + double colImag[] = new double[ny]; + for (int x = 0; x < nx; x++) { + for (int y = 0; y < ny; y++) { + colReal[y] = signal[0][x + nx * (y)]; + colImag[y] = signal[1][x + nx * (y)]; + } + transform1D(colReal, colImag); + for (int y = 0; y < ny; y++) { + signal[0][x + nx * (y)] = colReal[y]; + signal[1][x + nx * (y)] = colImag[y]; + } + } + return signal; + } + + /** + * Performs the 2D inverse FFT (Cooley Tukey). Signal's size has to be a + * power of two : 2^n. + */ + public double[][] inverse2D(double real[], double imag[], int nx, int ny) { + + double[][] tmpreal = new double[nx][ny]; + double[][] tmpimag = new double[nx][ny]; + + double colReal[] = new double[ny]; + double colImag[] = new double[ny]; + + for (int x = 0; x < nx; x++) { + for (int y = 0; y < ny; y++) { + colReal[y] = real[x + nx * (y)]; + colImag[y] = imag[x + nx * (y)]; + } + inverseFFT1D(colReal, colImag); + for (int y = 0; y < ny; y++) { + tmpreal[x][y] = colReal[y]; + tmpimag[x][y] = colImag[y]; + } + } + + double rowReal[] = new double[nx]; + double rowImag[] = new double[nx]; + + double signal[][] = new double[2][nx * ny]; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < nx; x++) { + rowReal[x] = tmpreal[x][y]; + rowImag[x] = tmpimag[x][y]; + } + inverseFFT1D(rowReal, rowImag); + for (int x = 0; x < nx; x++) { + signal[0][x + nx * y] = rowReal[x]; + signal[1][x + nx * y] = rowImag[x]; + } + } + return signal; + } + + /** + * Perform the Fourier transform of the FFT 1D. + * + * 2D shift of the half size of the input. + */ + public void transform1D(double real[], double imag[]) { + fft1D(real, imag); + } + + /** + * Perform the Inverse of the FFT 1D. + * + * Signal's size has to be a power of two : 2^m + */ + public void inverseFFT1D(double real[], double imag[]) { + int size = real.length; + for (int i = 0; i < size; i++) { + imag[i] = -imag[i]; + } + + fft1D(real, imag); + + for (int i = 0; i < size; i++) { + real[i] = real[i] / size; + imag[i] = -imag[i] / size; + } + } + + /** + * 2D shift of the half size of the input. + */ + public void shift2D(double plane[], int nx, int ny) { + int nx2 = nx / 2; + int ny2 = ny / 2; + double tmp[] = new double[nx * ny]; + + for (int x = 0; x < nx; x++) { + int i = (x >= nx2 ? x - nx2 : x + nx2); + for (int y = 0; y < ny; y++) + tmp[i + nx * y] = plane[x + nx * y]; + } + + for (int y = 0; y < ny; y++) { + int j = (y >= ny2 ? y - ny2 : y + ny2); + for (int x = 0; x < nx; x++) + plane[x + nx * j] = tmp[x + nx * y]; + } + } + + /** + * Perform the FFT 1D Method Decimation in time (Cooley Tukey) + * + * Signal's size has to be a power of two : 2^m + */ + private void fft1D(double real[], double imaginary[]) { + int shift = 0; // start of the computation + int size = real.length; // length of the FFT + + int m = (int) Math.floor((Math.log((double) size) / Math.log(2.0))); + + double Retmp, Imtmp, arg; + int i, j, k, stepsize, shifter, n; + int i_j, i_j_s; + + n = 1 << m; + + double[] Imarg = new double[n]; + double[] Rearg = new double[n]; + + // compute W coefficients + double arg0 = 2.0 * Math.PI / (double) n; + for (i = 0; i < n; i++) { + arg = arg0 * (float) i; + Rearg[i] = Math.cos(arg); + Imarg[i] = -Math.sin(arg); + } + + // bit inversion + for (i = j = shift; i < shift + n - 1; i++) { + if (i < j) { + Retmp = real[i]; + Imtmp = imaginary[i]; + real[i] = real[j]; + imaginary[i] = imaginary[j]; + real[j] = Retmp; + imaginary[j] = Imtmp; + } + k = n >> 1; + while (k + shift <= j) { + j -= k; + k /= 2; + } + j += k; + } + + // Perform the FFT + for (stepsize = 1, shifter = m - 1; stepsize < n; stepsize <<= 1, --shifter) { + for (j = shift; j < shift + n; j += stepsize << 1) { + for (i = 0; i < stepsize; i++) { + i_j = i + j; + i_j_s = i_j + stepsize; + if (i > 0) { + Retmp = Rearg[i << shifter] * real[i_j_s] - Imarg[i << shifter] * imaginary[i_j_s]; + imaginary[i_j_s] = Rearg[i << shifter] * imaginary[i_j_s] + Imarg[i << shifter] * real[i_j_s]; + real[i_j_s] = Retmp; + } + Retmp = real[i_j] - real[i_j_s]; + Imtmp = imaginary[i_j] - imaginary[i_j_s]; + real[i_j] += real[i_j_s]; + imaginary[i_j] += imaginary[i_j_s]; + real[i_j_s] = Retmp; + imaginary[i_j_s] = Imtmp; + } + } + } + + } +} diff --git a/src/bilib/src/bilib/commons/job/.DS_Store b/src/bilib/src/bilib/commons/job/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b853ace37669751e41d0bd03e4c7f851f8d05f5c Binary files /dev/null and b/src/bilib/src/bilib/commons/job/.DS_Store differ diff --git a/src/bilib/src/bilib/commons/job/ExecutionMode.java b/src/bilib/src/bilib/commons/job/ExecutionMode.java new file mode 100644 index 0000000000000000000000000000000000000000..675b94956ee17bca8c965bc697b57bef1dd36459 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/ExecutionMode.java @@ -0,0 +1,17 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job; + +public enum ExecutionMode { + MULTITHREAD_NO, MULTITHREAD_SYNCHRONIZED, MULTITHREAD_ASYNCHRONIZED +} diff --git a/src/bilib/src/bilib/commons/job/JobAbstract.java b/src/bilib/src/bilib/commons/job/JobAbstract.java new file mode 100644 index 0000000000000000000000000000000000000000..eab12ad27d17e9fa3547df5186c8127a415952f2 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/JobAbstract.java @@ -0,0 +1,69 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job; + +import java.util.ArrayList; + +/** + * This class is an interface for three implementations of the Job concept: + * Runnable Job, Callable Job, SwingWorker Job. + * + * @author sage + * + */ +public interface JobAbstract { + + public abstract void addMonitor(MonitorAbstract monitor); + + public abstract void removeMonitor(MonitorAbstract monitor); + + public abstract void clearMonitor(); + + public abstract ArrayList<MonitorAbstract> getMonitor(); + + public abstract boolean isNotTimeOut(); + + public abstract boolean isJobLive(); + + public abstract boolean isJobDone(); + + public abstract boolean isJobIdle(); + + public abstract boolean isJobProcessing(); + + public abstract boolean isJobIncomplete(); + + @Override + public abstract String toString(); + + public abstract String getName(); + + public abstract void setName(String name); + + public abstract void setTimeOut(double timeoutms); + + public abstract void abort(); + + public abstract void interrupt(); + + public abstract void abort(String message); + + public abstract void interrupt(String message); + + public abstract void init(); + + public abstract PoolAbstract getPool(); + + public abstract void setPool(PoolAbstract pool); + +} diff --git a/src/bilib/src/bilib/commons/job/JobEvent.java b/src/bilib/src/bilib/commons/job/JobEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..a6ee541a7302c6bb3d44d5fcd7cf441676b09035 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/JobEvent.java @@ -0,0 +1,94 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job; + +import java.util.EventObject; + +public class JobEvent extends EventObject { + + public static byte VOID = 0; + public static byte STARTED = 1; + public static byte COMPLETED = 2; + public static byte ABORTED = 3; + public static byte TIMEOUT = 4; + public static byte EXCEPTION = 5; + public static byte INTERRUPTED = 6; + + private byte typeEvent = VOID; + private String message = ""; + private Exception exception; + private JobAbstract job; + + public JobEvent(JobAbstract source, byte typeEvent, String message) { + super(source); + this.job = source; + this.typeEvent = typeEvent; + this.exception = null; + this.message = message; + } + + public JobEvent(JobAbstract source, Exception exception, String message) { + super(source); + this.job = source; + this.typeEvent = EXCEPTION; + this.exception = exception; + this.message = message; + } + + public JobEvent(JobAbstract source, byte typeEvent) { + super(source); + this.job = source; + this.typeEvent = typeEvent; + this.message = ""; + } + + public JobAbstract getJob() { + return job; + } + + public String getMessage() { + return message; + } + + public Exception getException() { + return exception; + } + + public byte getTypeEvent() { + return typeEvent; + } + + public String getEventString() { + if (typeEvent == VOID) + return "VOID"; + if (typeEvent == STARTED) + return "STARTED"; + if (typeEvent == COMPLETED) + return "COMPLETED"; + if (typeEvent == ABORTED) + return "ABORTED"; + if (typeEvent == TIMEOUT) + return "TIMEOUT"; + if (typeEvent == EXCEPTION) + return "EXCEPTION"; + if (typeEvent == INTERRUPTED) + return "INTERRUPTED"; + return "UNDEFINED"; + } + + @Override + public String toString() { + return "JobEvent, type=(" + getEventString() + "), source=(" + source.toString() + "), message=(" + message + ") " + source.getClass().getName(); + } + +} diff --git a/src/bilib/src/bilib/commons/job/MonitorAbstract.java b/src/bilib/src/bilib/commons/job/MonitorAbstract.java new file mode 100644 index 0000000000000000000000000000000000000000..da98b572213a3f648da6ea62c1f3a468a2740960 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/MonitorAbstract.java @@ -0,0 +1,32 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job; + +public interface MonitorAbstract { + + public abstract void rewind(); + + public abstract void print(String message); + + public abstract void error(String message); + + public abstract void warning(String message); + + public abstract void progress(double percentage); + + public abstract void progress(double percentage, String message); + + public abstract void increment(double percentageIncrement); + + public abstract void increment(double percentageIncrement, String message); +} diff --git a/src/bilib/src/bilib/commons/job/MonitorConsole.java b/src/bilib/src/bilib/commons/job/MonitorConsole.java new file mode 100644 index 0000000000000000000000000000000000000000..3453533df13571c1397d99e2343aea4f827bab1c --- /dev/null +++ b/src/bilib/src/bilib/commons/job/MonitorConsole.java @@ -0,0 +1,55 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job; + +public class MonitorConsole implements MonitorAbstract { + + @Override + public void rewind() { + } + + @Override + public void print(String message) { + System.out.println(message); + } + + @Override + public void progress(double percentage) { + System.out.println("Progression:" + percentage); + } + + @Override + public void progress(double percentage, String message) { + System.out.println("Progression:" + percentage + " Message:" + message); + } + + @Override + public void increment(double percentageIncrement) { + System.out.println("+ Progression:" + percentageIncrement); + } + + @Override + public void increment(double percentageIncrement, String message) { + System.out.println("+ Progression:" + percentageIncrement + " Message:" + message); + } + + @Override + public void error(String message) { + System.out.println("Error:" + message); + } + + @Override + public void warning(String message) { + System.out.println("Warning:" + message); + } +} diff --git a/src/bilib/src/bilib/commons/job/MonitorProgressBar.java b/src/bilib/src/bilib/commons/job/MonitorProgressBar.java new file mode 100644 index 0000000000000000000000000000000000000000..b1a91e750da6805b523a9b351ceb1187c43c1fc4 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/MonitorProgressBar.java @@ -0,0 +1,76 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job; + +import javax.swing.JProgressBar; + +public class MonitorProgressBar extends JProgressBar implements MonitorAbstract { + + private double percentage = 0.0; + + public MonitorProgressBar() { + setStringPainted(true); + setMaximum(100); + setPercentage(0); + } + + @Override + public void rewind() { + setPercentage(0); + setString(""); + } + + @Override + public void print(String message) { + setString(message); + } + + @Override + public void progress(double percentage) { + setPercentage(percentage); + } + + @Override + public void progress(double percentage, String message) { + setPercentage(percentage); + setString(message); + } + + @Override + public void increment(double percentageIncrement) { + setPercentage(percentageIncrement + percentage); + } + + @Override + public void increment(double percentageIncrement, String message) { + setPercentage(percentageIncrement + percentage); + setString(message); + } + + @Override + public void error(String message) { + setString("Error:" + message); + } + + @Override + public void warning(String message) { + setString("Warning:" + message); + } + + private void setPercentage(double percentage) { + this.percentage = percentage; + setValue((int) Math.max(0, Math.min(100, percentage))); + + } + +} diff --git a/src/bilib/src/bilib/commons/job/MonitorTimedLog.java b/src/bilib/src/bilib/commons/job/MonitorTimedLog.java new file mode 100644 index 0000000000000000000000000000000000000000..e14784e83f57ee22e162e39394c283f6f7818bcf --- /dev/null +++ b/src/bilib/src/bilib/commons/job/MonitorTimedLog.java @@ -0,0 +1,100 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job; + +import java.awt.Insets; +import java.text.DecimalFormat; + +import javax.swing.JTextArea; +import javax.swing.text.DefaultCaret; + +public class MonitorTimedLog extends JTextArea implements MonitorAbstract { + + private double chrono = System.nanoTime(); + + public MonitorTimedLog(int rows, int columns) { + super(rows, columns); + setMargin(new Insets(5, 5, 5, 5)); + setEditable(false); + DefaultCaret caret = (DefaultCaret) getCaret(); + caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); + } + + @Override + public void rewind() { + chrono = System.nanoTime(); + setText(""); + } + + @Override + public void print(String message) { + update(message); + } + + @Override + public void error(String message) { + update(message); + } + + @Override + public void warning(String message) { + update(message); + } + + @Override + public void progress(double percentage) { + update("Progression: " + percentage); + } + + @Override + public void progress(double percentage, String message) { + update("Progression: " + percentage + " - "); + } + + @Override + public void increment(double percentage) { + update("+ Progression: " + percentage); + } + + @Override + public void increment(double percentage, String message) { + update("+ Progression: " + percentage + " - "); + } + + private void update(String message) { + append(toc() + " " + message + "\n"); + setCaretPosition(getDocument().getLength()); + } + + private String toc() { + double te = System.nanoTime() - chrono; + String s = " "; + DecimalFormat df = new DecimalFormat("####.##"); + if (te < 1000.0) + return s + df.format(te) + " ns"; + te /= 1000; + if (te < 1000.0) + return s + df.format(te) + " us"; + te /= 1000; + if (te < 3000.0) + return s + df.format(te) + " ms"; + te /= 1000; + if (te < 600.1) + return s + df.format(te) + " s"; + te /= 60; + if (te < 600.1) + return s + df.format(te) + " min."; + te /= 60; + return s + df.format(te) + " h."; + } +} diff --git a/src/bilib/src/bilib/commons/job/MonitorTimedProgressBar.java b/src/bilib/src/bilib/commons/job/MonitorTimedProgressBar.java new file mode 100644 index 0000000000000000000000000000000000000000..9431a910eb1f387e3a204e23cf7a340ee95e497e --- /dev/null +++ b/src/bilib/src/bilib/commons/job/MonitorTimedProgressBar.java @@ -0,0 +1,106 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job; + +import java.text.DecimalFormat; + +import javax.swing.JProgressBar; + +public class MonitorTimedProgressBar extends JProgressBar implements MonitorAbstract { + + private double chrono = System.nanoTime(); + private double percentage = 0.0; + + public MonitorTimedProgressBar() { + setStringPainted(true); + setMaximum(100); + setPercentage(0); + } + + @Override + public void rewind() { + setPercentage(0); + chrono = System.nanoTime(); + setText(""); + } + + @Override + public void print(String message) { + setText(message); + } + + @Override + public void progress(double percentage) { + setPercentage(percentage); + } + + @Override + public void progress(double percentage, String message) { + setPercentage(percentage); + setText(message); + } + + @Override + public void increment(double percentageIncrement) { + setPercentage(percentageIncrement + percentage); + } + + @Override + public void increment(double percentageIncrement, String message) { + setPercentage(percentageIncrement + percentage); + setText(message); + } + + @Override + public void error(String message) { + setText("Error:" + message); + } + + @Override + public void warning(String message) { + setText("Warning:" + message); + } + + private void setText(String message) { + setString(toc() + " - " + message); + } + + private String toc() { + double te = System.nanoTime() - chrono; + String s = " "; + DecimalFormat df = new DecimalFormat("####.##"); + if (te < 1000.0) + return s + df.format(te) + " ns"; + te /= 1000; + if (te < 1000.0) + return s + df.format(te) + " us"; + te /= 1000; + if (te < 3000.0) + return s + df.format(te) + " ms"; + te /= 1000; + if (te < 600.1) + return s + df.format(te) + " s"; + te /= 60; + if (te < 600.1) + return s + df.format(te) + " min."; + te /= 60; + return s + df.format(te) + " h."; + } + + private void setPercentage(double percentage) { + this.percentage = percentage; + setValue((int) Math.max(0, Math.min(100, percentage))); + + } + +} diff --git a/src/bilib/src/bilib/commons/job/PoolAbstract.java b/src/bilib/src/bilib/commons/job/PoolAbstract.java new file mode 100644 index 0000000000000000000000000000000000000000..aa7e3e8ea3b0835811f38bfbcbfc3373730efb9e --- /dev/null +++ b/src/bilib/src/bilib/commons/job/PoolAbstract.java @@ -0,0 +1,52 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job; + +import java.util.concurrent.Future; + +public interface PoolAbstract { + + public abstract String getName(); + + public abstract void execute(ExecutionMode mode); + + public abstract void execute(ExecutionMode mode, int nThreads); + + public abstract Future<Object> getFuture(String jobName); + + public abstract int size(); + + public abstract void cancel(); + + public abstract void register(JobAbstract job); + + public abstract void register(JobAbstract job, double timeoutms); + + public abstract void unregister(JobAbstract job); + + public abstract void unregisterAll(); + + public abstract boolean isJobDone(); + + public abstract boolean isJobLive(); + + public abstract boolean isJobIdle(); + + public abstract void waitTermination(); + + public abstract void die(); + + public abstract void fire(JobEvent event); + + public abstract void fire(JobAbstract parent, JobEvent event); +} diff --git a/src/bilib/src/bilib/commons/job/callable/CallableDemo.java b/src/bilib/src/bilib/commons/job/callable/CallableDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..7e2bf6254a58aeb00abb5fa75b84896ae6e7f614 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/callable/CallableDemo.java @@ -0,0 +1,303 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.callable; + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; + +import bilib.commons.job.ExecutionMode; +import bilib.commons.job.JobEvent; +import bilib.commons.job.MonitorAbstract; +import bilib.commons.job.MonitorProgressBar; +import bilib.commons.job.MonitorTimedLog; +import bilib.commons.job.MonitorTimedProgressBar; +import bilib.commons.job.callable.PoolResponder; + +public class CallableDemo extends JFrame implements PoolResponder, ActionListener { + + public JRadioButton rbSequential = new JRadioButton("Sequential", false); + public JRadioButton rbAsynchronized = new JRadioButton("Parallel - Asynchronized jobs (not wait)", false); + public JRadioButton rbSynchronized = new JRadioButton("Parallel - Synchronized jobs (wait termination)", true); + + public JButton execute = new JButton("Execute"); + public JTextField nthreads = new JTextField("0"); + public JTextField njobs = new JTextField("10"); + public JButton simulateAbort = new JButton("Abort"); + public JButton simulateException = new JButton("Simulate an Exception"); + public JButton simulateJobException = new JButton("Simulate an JobException"); + public JButton simulateInterruption = new JButton("Simulate an Interruption"); + public JButton simulateCancellation = new JButton("Simulate an Cancellation"); + public JButton simulateTimeOut = new JButton("Simulate an TimeOut"); + + public MonitorTimedProgressBar bar = new MonitorTimedProgressBar(); + public MonitorProgressBar bar1 = new MonitorProgressBar(); + public MonitorTimedLog log = new MonitorTimedLog(10, 10); + + private double chrono; + private MainProcessing main; + + public static void main(String args[]) { + new CallableDemo(); + } + + public CallableDemo() { + super("Callable Demo"); + main = new MainProcessing(this); + + ButtonGroup bg1 = new ButtonGroup(); + bg1.add(rbSequential); + bg1.add(rbAsynchronized); + bg1.add(rbSynchronized); + + JPanel panel1 = new JPanel(new GridLayout(20, 1)); + + panel1.add(rbSequential); + panel1.add(rbAsynchronized); + panel1.add(rbSynchronized); + + panel1.add(new JLabel("Number of threads (0 = nb of jobs)")); + panel1.add(nthreads); + panel1.add(new JLabel("Number of jobs")); + panel1.add(njobs); + panel1.add(execute); + panel1.add(new JLabel("")); + panel1.add(simulateAbort); + panel1.add(simulateException); + panel1.add(simulateJobException); + panel1.add(simulateInterruption); + panel1.add(simulateCancellation); + panel1.add(simulateTimeOut); + + JPanel panel3 = new JPanel(new BorderLayout()); + panel3.add(bar, BorderLayout.NORTH); + panel3.add(bar1, BorderLayout.SOUTH); + + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + panel.add(panel1, BorderLayout.NORTH); + panel.add(panel3, BorderLayout.SOUTH); + panel.add(log, BorderLayout.CENTER); + + execute.addActionListener(this); + simulateAbort.addActionListener(this); + simulateException.addActionListener(this); + simulateJobException.addActionListener(this); + simulateInterruption.addActionListener(this); + simulateCancellation.addActionListener(this); + simulateTimeOut.addActionListener(this); + getContentPane().add(panel); + pack(); + setVisible(true); + } + + private ExecutionMode getMode() { + ExecutionMode mode = ExecutionMode.MULTITHREAD_NO; + if (rbSynchronized.isSelected()) + mode = ExecutionMode.MULTITHREAD_SYNCHRONIZED; + if (rbAsynchronized.isSelected()) + mode = ExecutionMode.MULTITHREAD_ASYNCHRONIZED; + return mode; + } + + @Override + public void actionPerformed(ActionEvent event) { + + if (event.getSource() == execute) { + main.setMode(getMode(), Integer.parseInt(nthreads.getText()), Integer.parseInt(njobs.getText())); + System.out.println("\n\n"); + Pool pool = new Pool("Main", this); + pool.register(main); + pool.execute(ExecutionMode.MULTITHREAD_ASYNCHRONIZED); + chrono = System.nanoTime(); + } + + if (event.getSource() == simulateAbort) + main.simulateAbort(); + + if (event.getSource() == simulateException) + main.simulateException(); + + if (event.getSource() == simulateJobException) + main.simulateJobException(); + + if (event.getSource() == simulateInterruption) + main.simulateInterruption(); + + if (event.getSource() == simulateCancellation) + main.simulateCancellation(); + + if (event.getSource() == simulateTimeOut) + main.simulateTimeOut(); + } + + // + // MainProcessing + // + public class MainProcessing extends Job implements PoolResponder { + private ExecutionMode mode; + private int nthreads = 0; + private int njobs; + private PoolResponder responder; + private Pool pool; + private int niter = 15; + + public MainProcessing(PoolResponder responder) { + super(); + this.responder = responder; + } + + public void setMode(ExecutionMode mode, int nthreads, int njobs) { + this.mode = mode; + this.njobs = njobs; + this.nthreads = nthreads; + } + + @Override + public Object process() { + bar.rewind(); + bar1.rewind(); + log.rewind(); + + pool = new Pool("my", responder); + MyCallable p1 = new MyCallable(niter, bar); + p1.addMonitor(log); + p1.addMonitor(bar1); + pool.register(p1); + for (int i = 0; i < njobs; i++) + pool.register(new MyCallable(niter, bar)); + pool.execute(mode, nthreads); + + System.out.println("End of main"); + return "End"; + + } + + public void simulateAbort() { + if (pool != null) + pool.getRegisteredJob(pool.size() - 1).abort(); + } + + public void simulateCancellation() { + if (pool != null) + pool.cancel(); + } + + public void simulateException() { + if (pool != null) + ((MyCallable) pool.getRegisteredJob(pool.size() / 2 - 1)).withException = true; + } + + public void simulateJobException() { + if (pool != null) + ((MyCallable) pool.getRegisteredJob(pool.size() - 1)).withJobException = true; + } + + public void simulateInterruption() { + if (pool != null) + ((MyCallable) pool.getRegisteredJob(pool.size() - 1)).withInterruption = true; + } + + public void simulateTimeOut() { + if (pool != null) + ((MyCallable) pool.getRegisteredJob(pool.size() - 1)).withTimeOut = true; + } + + @Override + public void onEvent(Pool pool, JobEvent event) { + responder.onEvent(pool, event); + } + + @Override + public void onSuccess(Pool pool, JobEvent event) { + responder.onSuccess(pool, event); + } + + @Override + public void onFailure(Pool pool, JobEvent event) { + responder.onFailure(pool, event); + } + + } + + // + // MyCallable + // + public class MyCallable extends Job { + public boolean withTimeOut = false; + public boolean withInterruption = false; + public boolean withException = false; + public boolean withJobException = false; + private int niter = 15; + + public MyCallable(int niter, MonitorAbstract monitor) { + super(monitor); + this.niter = niter; + } + + @Override + public Object process() throws RuntimeException { + int i = 0; + for (i = 0; i < niter && live; i++) { + increment(2, getName() + " " + live + " " + done); + for (int j = 0; j < 600000 && live; j++) + Math.round(Math.cos(Math.exp(Math.pow(j, -3)))); + if (withJobException) + throw new RuntimeException("It is a programming exception"); + if (withInterruption) { + error("Interrupted messsage"); + interrupt(); + } + if (withTimeOut) + niter += 2; + if (withException) { + double a[] = new double[2]; + a[3] = 1; + } + if (!live) + return "no live"; + } + System.out.println("End of " + getName() + " iterations:" + i + " " + live + " " + done); + return "End of " + getName() + " iterations:" + i + " " + live + " " + done; + } + } + + @Override + public void onEvent(Pool pool, JobEvent event) { + System.out.println("Main side: Job Event " + event); + } + + @Override + public void onSuccess(Pool pool, JobEvent event) { + System.out.println(">>> Success " + event + " from pool " + pool.getName()); + System.out.println("Computation time: " + (System.nanoTime() - chrono) / 1000000.0); + } + + @Override + public void onFailure(Pool pool, JobEvent event) { + System.out.println(">>> Failure " + event + " from pool " + pool.getName()); + if (event.getException() != null) + event.getException().printStackTrace(); + } + +} diff --git a/src/bilib/src/bilib/commons/job/callable/Job.java b/src/bilib/src/bilib/commons/job/callable/Job.java new file mode 100644 index 0000000000000000000000000000000000000000..7f35fc54b37294b7087ae1ca2f767423c7705d1c --- /dev/null +++ b/src/bilib/src/bilib/commons/job/callable/Job.java @@ -0,0 +1,253 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.callable; + +import java.util.ArrayList; +import java.util.concurrent.Callable; + +import bilib.commons.job.JobAbstract; +import bilib.commons.job.JobEvent; +import bilib.commons.job.MonitorAbstract; +import bilib.commons.job.PoolAbstract; + +public abstract class Job implements JobAbstract, MonitorAbstract, Callable<Object> { + + public boolean live = false; + public boolean done = false; + public boolean idle = false; + private double chrono = -1; + private double timeoutns = -1; + private boolean stopTimeOut = false; + private ArrayList<MonitorAbstract> monitors = new ArrayList<MonitorAbstract>(); + + public PoolAbstract pool; + + public abstract Object process() throws RuntimeException; + + private String name; + + public Job() { + } + + public Job(MonitorAbstract monitor) { + monitors.add(monitor); + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public PoolAbstract getPool() { + return pool; + } + + @Override + public void setPool(PoolAbstract pool) { + this.pool = pool; + } + + @Override + public void setTimeOut(double timeoutms) { + this.timeoutns = timeoutms * 1000000.0; + this.stopTimeOut = true; + } + + @Override + public void abort() { + idle = false; + live = false; + done = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.ABORTED)); + } + + @Override + public void interrupt() { + idle = false; + live = false; + done = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.INTERRUPTED)); + } + + @Override + public void abort(String message) { + idle = false; + live = false; + done = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.ABORTED, message)); + } + + @Override + public void interrupt(String message) { + idle = false; + live = false; + done = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.INTERRUPTED, message)); + } + + @Override + public void init() { + idle = true; + live = true; + done = false; + chrono = System.nanoTime(); + } + + @Override + public Object call() { + Object o = null; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.STARTED)); + try { + idle = false; + o = process(); + if (live) { + done = true; + live = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.COMPLETED)); + } + } + catch (RuntimeException ex) { + if (pool != null) + pool.fire(new JobEvent(this, ex, ex.getMessage())); + } + live = false; + idle = true; + return o; + } + + @Override + public boolean isNotTimeOut() { + if (!live) + return false; + if (stopTimeOut) + if ((System.nanoTime() - chrono) > timeoutns) { + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.TIMEOUT)); + live = false; + done = false; + return false; + } + return true; + } + + @Override + public boolean isJobLive() { + return live; + } + + @Override + public boolean isJobDone() { + return done; + } + + @Override + public boolean isJobIdle() { + return idle; + } + + @Override + public boolean isJobProcessing() { + return !idle; + } + + @Override + public boolean isJobIncomplete() { + return !done; + } + + @Override + public String toString() { + return "JobCallable: " + getName(); + } + + @Override + public void rewind() { + for (MonitorAbstract monitor : monitors) + monitor.rewind(); + } + + @Override + public void print(String message) { + for (MonitorAbstract monitor : monitors) + monitor.print(message); + } + + @Override + public void error(String message) { + for (MonitorAbstract monitor : monitors) + monitor.error(message); + } + + @Override + public void warning(String message) { + for (MonitorAbstract monitor : monitors) + monitor.warning(message); + } + + @Override + public void progress(double percentage) { + for (MonitorAbstract monitor : monitors) + monitor.progress(percentage); + } + + @Override + public void progress(double percentage, String message) { + for (MonitorAbstract monitor : monitors) + monitor.progress(percentage, message); + } + + @Override + public void increment(double percentageIncrement) { + for (MonitorAbstract monitor : monitors) + monitor.increment(percentageIncrement); + } + + @Override + public void increment(double percentageIncrement, String message) { + for (MonitorAbstract monitor : monitors) + monitor.increment(percentageIncrement, message); + } + + @Override + public void addMonitor(MonitorAbstract monitor) { + monitors.add(monitor); + } + + @Override + public void removeMonitor(MonitorAbstract monitor) { + monitors.remove(monitor); + } + + @Override + public void clearMonitor() { + monitors.clear(); + } + + @Override + public ArrayList<MonitorAbstract> getMonitor() { + return monitors; + } + +} diff --git a/src/bilib/src/bilib/commons/job/callable/Pool.java b/src/bilib/src/bilib/commons/job/callable/Pool.java new file mode 100644 index 0000000000000000000000000000000000000000..7448679cf9b7198fb8740f523f9d9781c3292106 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/callable/Pool.java @@ -0,0 +1,288 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.callable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import bilib.commons.job.ExecutionMode; +import bilib.commons.job.JobAbstract; +import bilib.commons.job.JobEvent; +import bilib.commons.job.PoolAbstract; +import bilib.commons.job.callable.PoolResponder; +import bilib.commons.job.callable.Job; + +public class Pool implements PoolAbstract { + + private ArrayList<Job> jobs; + protected String name; + protected PoolResponder responder; + + protected HashMap<String, Future<Object>> results; + + /** + * Create a new pool with one registered job (Callable). + * + * @param job + * the job to register + * @param responder + * the responder handling the job event + */ + public Pool(Job job, PoolResponder responder) { + jobs = new ArrayList<Job>(); + results = new HashMap<String, Future<Object>>(); + this.name = job.getName(); + this.responder = responder; + register(job); + } + + /** + * Create a new pool without any registered job (Callable). + * + * @param name + * name of the pool + * @param responder + * the responder handling the job event + */ + public Pool(String name, PoolResponder responder) { + jobs = new ArrayList<Job>(); + results = new HashMap<String, Future<Object>>(); + this.name = name; + this.responder = responder; + } + + @Override + public void fire(JobEvent event) { + + int t = event.getTypeEvent(); + if (responder != null) + responder.onEvent(this, event); + + if (t == JobEvent.EXCEPTION) { + die(); + if (responder != null) { + responder.onFailure(this, event); + } + } + else if (t == JobEvent.ABORTED) { + die(); + if (responder != null) + responder.onFailure(this, event); + } + else if (t == JobEvent.TIMEOUT) { + die(); + if (responder != null) + responder.onFailure(this, event); + } + else if (t == JobEvent.COMPLETED) { + if (isJobDone()) { + die(); + if (responder != null) + responder.onSuccess(this, event); + } + } + } + + @Override + public void fire(JobAbstract parent, JobEvent event) { + if (parent == null) + return; + if (parent.getPool() == null) + return; + if (event.getTypeEvent() == JobEvent.EXCEPTION) + parent.getPool().fire(new JobEvent(parent, event.getException(), event.getMessage())); + else + parent.getPool().fire(new JobEvent(parent, event.getTypeEvent(), event.getMessage())); + + } + + public ArrayList<Job> getRegisteredJobs() { + return jobs; + } + + public Job getRegisteredJob(int i) { + return jobs.get(i); + } + + @Override + public void execute(ExecutionMode mode) { + execute(mode, jobs.size()); + } + + @Override + @SuppressWarnings("unchecked") + public void execute(ExecutionMode mode, int nThreads) { + for (Job job : jobs) + job.init(); + if (mode == ExecutionMode.MULTITHREAD_NO) { + for (Job job : jobs) { + job.call(); + } + } + else { + if (nThreads <= 0) + nThreads = jobs.size(); + ExecutorService executor = Executors.newFixedThreadPool(nThreads); + for (Job job : jobs) { + Future<?> future = executor.submit(job); + results.put(job.getName(), (Future<Object>) future); + } + executor.shutdown(); + if (mode == ExecutionMode.MULTITHREAD_SYNCHRONIZED) + waitTermination(); + } + } + + @Override + public Future<Object> getFuture(String jobName) { + if (jobs != null) + for (int i = 0; i < jobs.size(); i++) { + if (jobs.get(i).getName().equals(jobName)) + return results.get(jobs.get(i).getName()); + } + return null; + } + + @Override + public int size() { + int s = 0; + if (jobs != null) + s += jobs.size(); + return s; + } + + @Override + public void cancel() { + if (jobs != null) + for (Job job : jobs) + results.get(job.getName()).cancel(true); + } + + @Override + public void register(JobAbstract job) { + if (jobs == null) + return; + if (job instanceof Job) + if (jobs.add((Job) job)) { + job.setName(name + "-" + jobs.size()); + job.setPool(this); + } + } + + @Override + public void register(JobAbstract job, double timeoutms) { + if (jobs == null) + return; + if (job instanceof Job) + if (jobs.add((Job) job)) { + job.setTimeOut(timeoutms); + job.setName(name + "-" + jobs.size()); + job.setPool(this); + } + } + + @Override + public void unregister(JobAbstract job) { + if (jobs == null) + return; + if (job instanceof Job) { + jobs.remove((Job) job); + job.setPool(null); + } + } + + @Override + public void unregisterAll() { + if (jobs != null) + jobs.clear(); + } + + @Override + public boolean isJobDone() { + int count = 0; + if (jobs != null) { + for (Job job : jobs) { + if (job.done) + count++; + } + return (count == jobs.size()); + } + return false; + } + + @Override + public boolean isJobLive() { + int count = 0; + if (jobs != null) { + for (Job job : jobs) { + if (job.live) + count++; + } + return (count == jobs.size()); + } + return false; + } + + @Override + public boolean isJobIdle() { + int count = 0; + if (jobs != null) { + for (Job job : jobs) { + if (job.idle) + count++; + } + return (count == jobs.size()); + } + return false; + } + + @Override + public void waitTermination() { + boolean termination = false; + + if (jobs != null) + while (!termination) { + int count = 0; + for (Job job : jobs) + if (!job.live) + count++; + termination = (count >= jobs.size()); + } + } + + @Override + public synchronized void die() { + if (jobs != null) + for (Job job : jobs) { + job.live = false; + job.done = true; + } + } + + @Override + public String toString() { + String form = ""; + if (jobs != null) + form = jobs.getClass().getName(); + return " Pool=(" + name + ", " + size() + " " + form + ") "; + } + + @Override + public String getName() { + return name; + } + +} diff --git a/src/bilib/src/bilib/commons/job/callable/PoolResponder.java b/src/bilib/src/bilib/commons/job/callable/PoolResponder.java new file mode 100644 index 0000000000000000000000000000000000000000..c9d59c852789e1c2813ebe5cd26a3e65b5d83571 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/callable/PoolResponder.java @@ -0,0 +1,24 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.callable; + +import bilib.commons.job.JobEvent; + +public interface PoolResponder { + + public abstract void onEvent(Pool pool, JobEvent event); + + public abstract void onSuccess(Pool pool, JobEvent event); + + public abstract void onFailure(Pool pool, JobEvent event); +} diff --git a/src/bilib/src/bilib/commons/job/runnable/Job.java b/src/bilib/src/bilib/commons/job/runnable/Job.java new file mode 100644 index 0000000000000000000000000000000000000000..00ddb9528737e0e4a7f1a9c8fd77391065499ea4 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/runnable/Job.java @@ -0,0 +1,251 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.runnable; + +import java.util.ArrayList; + +import bilib.commons.job.JobAbstract; +import bilib.commons.job.JobEvent; +import bilib.commons.job.MonitorAbstract; +import bilib.commons.job.PoolAbstract; + +public abstract class Job implements JobAbstract, MonitorAbstract, Runnable { + + public boolean live = false; + public boolean done = false; + public boolean idle = false; + + private double chrono = -1; + private double timeoutns = -1; + private boolean stopTimeOut = false; + private ArrayList<MonitorAbstract> monitors = new ArrayList<MonitorAbstract>(); + + private PoolAbstract pool; + private String name; + + public abstract void process() throws RuntimeException; + + public Job() { + } + + public Job(MonitorAbstract monitor) { + monitors.add(monitor); + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public PoolAbstract getPool() { + return pool; + } + + @Override + public void setPool(PoolAbstract pool) { + this.pool = pool; + } + + @Override + public void setTimeOut(double timeoutms) { + this.timeoutns = timeoutms * 1000000.0; + this.stopTimeOut = true; + } + + @Override + public void abort() { + idle = false; + live = false; + done = true; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.ABORTED)); + } + + @Override + public void interrupt() { + idle = false; + live = false; + done = true; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.INTERRUPTED, "Interruption")); + } + + @Override + public void abort(String message) { + idle = false; + live = false; + done = true; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.ABORTED, message)); + } + + @Override + public void interrupt(String message) { + idle = false; + live = false; + done = true; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.INTERRUPTED, message)); + } + + @Override + public void init() { + idle = true; + live = true; + done = false; + chrono = System.nanoTime(); + } + + @Override + public void run() { + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.STARTED)); + try { + idle = false; + process(); + if (live) { + done = true; + live = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.COMPLETED)); + } + } + catch (IllegalArgumentException ex) { // Workaround a unexplained Icy exception + } + catch (RuntimeException ex) { + if (pool != null) + pool.fire(new JobEvent(this, ex, ex.getMessage())); + } + live = false; + idle = true; + } + + @Override + public boolean isNotTimeOut() { + if (!live) + return false; + if (stopTimeOut) + if ((System.nanoTime() - chrono) > timeoutns) { + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.TIMEOUT)); + live = false; + done = true; + return false; + } + return true; + } + + @Override + public boolean isJobLive() { + return live; + } + + @Override + public boolean isJobDone() { + return done; + } + + @Override + public boolean isJobIdle() { + return idle; + } + + @Override + public boolean isJobProcessing() { + return !idle; + } + + @Override + public boolean isJobIncomplete() { + return !done; + } + + @Override + public String toString() { + return "JobRunnable: " + getName(); + } + + @Override + public void rewind() { + for (MonitorAbstract monitor : monitors) + monitor.rewind(); + } + + @Override + public void print(String message) { + for (MonitorAbstract monitor : monitors) + monitor.print(message); + } + + @Override + public void error(String message) { + for (MonitorAbstract monitor : monitors) + monitor.error(message); + } + + @Override + public void warning(String message) { + for (MonitorAbstract monitor : monitors) + monitor.warning(message); + } + + @Override + public void progress(double percentage) { + for (MonitorAbstract monitor : monitors) + monitor.progress(percentage); + } + + @Override + public void progress(double percentage, String message) { + for (MonitorAbstract monitor : monitors) + monitor.progress(percentage, message); + } + + @Override + public void increment(double percentageIncrement) { + for (MonitorAbstract monitor : monitors) + monitor.increment(percentageIncrement); + } + + @Override + public void increment(double percentageIncrement, String message) { + for (MonitorAbstract monitor : monitors) + monitor.increment(percentageIncrement, message); + } + + @Override + public void addMonitor(MonitorAbstract monitor) { + monitors.add(monitor); + } + + @Override + public void removeMonitor(MonitorAbstract monitor) { + monitors.remove(monitor); + } + + @Override + public void clearMonitor() { + monitors.clear(); + } + + @Override + public ArrayList<MonitorAbstract> getMonitor() { + return monitors; + } +} diff --git a/src/bilib/src/bilib/commons/job/runnable/Pool.java b/src/bilib/src/bilib/commons/job/runnable/Pool.java new file mode 100644 index 0000000000000000000000000000000000000000..23fbd24ab1d0fe592afebd9de2b79b9f572912d6 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/runnable/Pool.java @@ -0,0 +1,286 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.runnable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import bilib.commons.job.ExecutionMode; +import bilib.commons.job.JobAbstract; +import bilib.commons.job.JobEvent; +import bilib.commons.job.PoolAbstract; + +public class Pool implements PoolAbstract { + + private ArrayList<Job> jobs; + protected String name; + protected PoolResponder responder; + + protected HashMap<String, Future<Object>> results; + + /** + * Create a new pool with one registered job (Runnable). + * + * @param job + * the job to register + * @param responder + * the responder handling the job event + */ + public Pool(Job job, PoolResponder responder) { + jobs = new ArrayList<Job>(); + results = new HashMap<String, Future<Object>>(); + this.name = job.getName(); + this.responder = responder; + register(job); + } + + /** + * Create a new pool without any registered job (Runnable). + * + * @param name + * name of the pool + * @param responder + * the responder handling the job event + */ + public Pool(String name, PoolResponder responder) { + jobs = new ArrayList<Job>(); + results = new HashMap<String, Future<Object>>(); + this.name = name; + this.responder = responder; + } + + @Override + public void fire(JobEvent event) { + + int t = event.getTypeEvent(); + if (responder != null) + responder.onEvent(this, event); + + if (t == JobEvent.EXCEPTION) { + die(); + if (responder != null) { + responder.onFailure(this, event); + } + } + else if (t == JobEvent.ABORTED) { + die(); + if (responder != null) + responder.onFailure(this, event); + } + else if (t == JobEvent.TIMEOUT) { + die(); + if (responder != null) + responder.onFailure(this, event); + } + else if (t == JobEvent.COMPLETED) { + if (isJobDone()) { + die(); + if (responder != null) + responder.onSuccess(this, event); + } + } + } + + @Override + public void fire(JobAbstract parent, JobEvent event) { + if (parent == null) + return; + if (parent.getPool() == null) + return; + if (event.getTypeEvent() == JobEvent.EXCEPTION) + parent.getPool().fire(new JobEvent(parent, event.getException(), event.getMessage())); + else + parent.getPool().fire(new JobEvent(parent, event.getTypeEvent(), event.getMessage())); + + } + + public ArrayList<Job> getRegisteredJobs() { + return jobs; + } + + public Job getRegisteredJob(int i) { + return jobs.get(i); + } + + @Override + public void execute(ExecutionMode mode) { + execute(mode, jobs.size()); + } + + @Override + @SuppressWarnings("unchecked") + public void execute(ExecutionMode mode, int nThreads) { + for (Job job : jobs) + job.init(); + if (mode == ExecutionMode.MULTITHREAD_NO) { + for (Job job : jobs) { + job.run(); + } + } + else { + if (nThreads <= 0) + nThreads = jobs.size(); + ExecutorService executor = Executors.newFixedThreadPool(nThreads); + for (Job job : jobs) { + Future<?> future = executor.submit(job); + results.put(job.getName(), (Future<Object>) future); + } + executor.shutdown(); + if (mode == ExecutionMode.MULTITHREAD_SYNCHRONIZED) + waitTermination(); + } + } + + @Override + public Future<Object> getFuture(String jobName) { + if (jobs != null) + for (int i = 0; i < jobs.size(); i++) { + if (jobs.get(i).getName().equals(jobName)) + return results.get(jobs.get(i).getName()); + } + return null; + } + + @Override + public int size() { + int s = 0; + if (jobs != null) + s += jobs.size(); + return s; + } + + @Override + public void cancel() { + if (jobs != null) + for (Job job : jobs) + results.get(job.getName()).cancel(true); + } + + @Override + public void register(JobAbstract job) { + if (jobs == null) + return; + if (job instanceof Job) + if (jobs.add((Job) job)) { + job.setName(name + "-" + jobs.size()); + job.setPool(this); + } + } + + @Override + public void register(JobAbstract job, double timeoutms) { + if (jobs == null) + return; + if (job instanceof Job) + if (jobs.add((Job) job)) { + job.setTimeOut(timeoutms); + job.setName(name + "-" + jobs.size()); + job.setPool(this); + } + } + + @Override + public void unregister(JobAbstract job) { + if (jobs == null) + return; + if (job instanceof Job) { + jobs.remove((Job) job); + job.setPool(null); + } + } + + @Override + public void unregisterAll() { + if (jobs != null) + jobs.clear(); + } + + @Override + public boolean isJobDone() { + int count = 0; + if (jobs != null) { + for (Job job : jobs) { + if (job.done) + count++; + } + return (count == jobs.size()); + } + return false; + } + + @Override + public boolean isJobLive() { + int count = 0; + if (jobs != null) { + for (Job job : jobs) { + if (job.live) + count++; + } + return (count == jobs.size()); + } + return false; + } + + @Override + public boolean isJobIdle() { + int count = 0; + if (jobs != null) { + for (Job job : jobs) { + if (job.idle) + count++; + } + return (count == jobs.size()); + } + return false; + } + + @Override + public void waitTermination() { + boolean termination = false; + + if (jobs != null) + while (!termination) { + int count = 0; + for (Job job : jobs) + if (!job.live) + count++; + termination = (count >= jobs.size()); + } + } + + @Override + public synchronized void die() { + if (jobs != null) + for (Job job : jobs) { + job.live = false; + job.done = true; + } + } + + @Override + public String toString() { + String form = ""; + if (jobs != null) + form = jobs.getClass().getName(); + return " Pool=(" + name + ", " + size() + " " + form + ") "; + } + + @Override + public String getName() { + return name; + } + +} diff --git a/src/bilib/src/bilib/commons/job/runnable/PoolResponder.java b/src/bilib/src/bilib/commons/job/runnable/PoolResponder.java new file mode 100644 index 0000000000000000000000000000000000000000..640c786413f9cb65cb79b91cf179fc4ffaccf2c0 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/runnable/PoolResponder.java @@ -0,0 +1,24 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.runnable; + +import bilib.commons.job.JobEvent; + +public interface PoolResponder { + + public abstract void onEvent(Pool pool, JobEvent event); + + public abstract void onSuccess(Pool pool, JobEvent event); + + public abstract void onFailure(Pool pool, JobEvent event); +} diff --git a/src/bilib/src/bilib/commons/job/runnable/RunnableDemo.java b/src/bilib/src/bilib/commons/job/runnable/RunnableDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..80a4340373a6210032b01ad15f8761f2b482b79d --- /dev/null +++ b/src/bilib/src/bilib/commons/job/runnable/RunnableDemo.java @@ -0,0 +1,301 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.runnable; + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; + +import bilib.commons.job.ExecutionMode; +import bilib.commons.job.JobEvent; +import bilib.commons.job.MonitorAbstract; +import bilib.commons.job.MonitorProgressBar; +import bilib.commons.job.MonitorTimedLog; +import bilib.commons.job.MonitorTimedProgressBar; +import bilib.commons.job.runnable.Pool; + +public class RunnableDemo extends JFrame implements PoolResponder, ActionListener { + + public JRadioButton rbSequential = new JRadioButton("Sequential", false); + public JRadioButton rbAsynchronized = new JRadioButton("Parallel - Asynchronized jobs (not wait)", false); + public JRadioButton rbSynchronized = new JRadioButton("Parallel - Synchronized jobs (wait termination)", true); + + public JButton execute = new JButton("Execute"); + public JTextField nthreads = new JTextField("0"); + public JTextField njobs = new JTextField("10"); + public JButton simulateAbort = new JButton("Abort"); + public JButton simulateException = new JButton("Simulate an Exception"); + public JButton simulateJobException = new JButton("Simulate an JobException"); + public JButton simulateInterruption = new JButton("Simulate an Interruption"); + public JButton simulateCancellation = new JButton("Simulate an Cancellation"); + public JButton simulateTimeOut = new JButton("Simulate an TimeOut"); + + public MonitorTimedProgressBar bar = new MonitorTimedProgressBar(); + public MonitorProgressBar bar1 = new MonitorProgressBar(); + public MonitorTimedLog log = new MonitorTimedLog(10, 10); + + private double chrono; + private MainProcessing main; + + public static void main(String args[]) { + new RunnableDemo(); + } + + public RunnableDemo() { + super("Runnable Demo"); + main = new MainProcessing(this); + + ButtonGroup bg1 = new ButtonGroup(); + bg1.add(rbSequential); + bg1.add(rbAsynchronized); + bg1.add(rbSynchronized); + + JPanel panel1 = new JPanel(new GridLayout(20, 1)); + + panel1.add(rbSequential); + panel1.add(rbAsynchronized); + panel1.add(rbSynchronized); + + panel1.add(new JLabel("Number of threads (0 = nb of jobs)")); + panel1.add(nthreads); + panel1.add(new JLabel("Number of jobs")); + panel1.add(njobs); + panel1.add(execute); + panel1.add(new JLabel("")); + panel1.add(simulateAbort); + panel1.add(simulateException); + panel1.add(simulateJobException); + panel1.add(simulateInterruption); + panel1.add(simulateCancellation); + panel1.add(simulateTimeOut); + + JPanel panel3 = new JPanel(new BorderLayout()); + panel3.add(bar, BorderLayout.NORTH); + panel3.add(bar1, BorderLayout.SOUTH); + + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + panel.add(panel1, BorderLayout.NORTH); + panel.add(panel3, BorderLayout.SOUTH); + panel.add(log, BorderLayout.CENTER); + + execute.addActionListener(this); + simulateAbort.addActionListener(this); + simulateException.addActionListener(this); + simulateJobException.addActionListener(this); + simulateInterruption.addActionListener(this); + simulateCancellation.addActionListener(this); + simulateTimeOut.addActionListener(this); + getContentPane().add(panel); + pack(); + setVisible(true); + } + + private ExecutionMode getMode() { + ExecutionMode mode = ExecutionMode.MULTITHREAD_NO; + if (rbSynchronized.isSelected()) + mode = ExecutionMode.MULTITHREAD_SYNCHRONIZED; + if (rbAsynchronized.isSelected()) + mode = ExecutionMode.MULTITHREAD_ASYNCHRONIZED; + return mode; + } + + @Override + public void actionPerformed(ActionEvent event) { + + if (event.getSource() == execute) { + main.setMode(getMode(), Integer.parseInt(nthreads.getText()), Integer.parseInt(njobs.getText())); + System.out.println("\n\n"); + Thread thread = new Thread(main); + thread.start(); + chrono = System.nanoTime(); + } + + if (event.getSource() == simulateAbort) + main.simulateAbort(); + + if (event.getSource() == simulateException) + main.simulateException(); + + if (event.getSource() == simulateJobException) + main.simulateJobException(); + + if (event.getSource() == simulateInterruption) + main.simulateInterruption(); + + if (event.getSource() == simulateCancellation) + main.simulateCancellation(); + + if (event.getSource() == simulateTimeOut) + main.simulateTimeOut(); + } + + // + // MainProcessing + // + public class MainProcessing extends Job implements PoolResponder { + private ExecutionMode mode; + private int nthreads = 0; + private int njobs; + private PoolResponder responder; + private Pool pool; + private int niter = 15; + + public MainProcessing(PoolResponder responder) { + super(); + this.responder = responder; + } + + public void setMode(ExecutionMode mode, int nthreads, int njobs) { + this.mode = mode; + this.njobs = njobs; + this.nthreads = nthreads; + } + + @Override + public void process() { + bar.rewind(); + bar1.rewind(); + log.rewind(); + pool = new Pool("my", responder); + MyRunnable p1 = new MyRunnable(niter, bar); + p1.addMonitor(log); + p1.addMonitor(bar1); + pool.register(p1); + for (int i = 0; i < njobs; i++) + pool.register(new MyRunnable(niter, bar)); + pool.execute(mode, nthreads); + System.out.println("End of main"); + } + + public void simulateAbort() { + if (pool != null) + pool.getRegisteredJob(pool.size() - 1).abort(); + } + + public void simulateCancellation() { + if (pool != null) + pool.cancel(); + } + + public void simulateException() { + if (pool != null) + ((MyRunnable) pool.getRegisteredJob(pool.size() / 2 - 1)).withException = true; + } + + public void simulateJobException() { + if (pool != null) + ((MyRunnable) pool.getRegisteredJob(pool.size() - 1)).withJobException = true; + } + + public void simulateInterruption() { + if (pool != null) + ((MyRunnable) pool.getRegisteredJob(pool.size() - 1)).withInterruption = true; + } + + public void simulateTimeOut() { + if (pool != null) + ((MyRunnable) pool.getRegisteredJob(pool.size() - 1)).withTimeOut = true; + } + + @Override + public void onEvent(Pool pool, JobEvent event) { + responder.onEvent(pool, event); + } + + @Override + public void onSuccess(Pool pool, JobEvent event) { + responder.onSuccess(pool, event); + } + + @Override + public void onFailure(Pool pool, JobEvent event) { + responder.onFailure(pool, event); + } + + } + + // + // MyRunnable + // + public class MyRunnable extends Job { + public boolean withTimeOut = false; + public boolean withInterruption = false; + public boolean withException = false; + public boolean withJobException = false; + private int niter = 15; + + public MyRunnable(int niter, MonitorAbstract monitor) { + super(monitor); + this.niter = niter; + } + + @Override + public void process() { + int i = 0; + for (i = 0; i < niter && live; i++) { + increment(2, getName() + " " + live + " " + done); + for (int j = 0; j < 600000 && live; j++) + Math.round(Math.cos(Math.exp(Math.pow(j, -3)))); + if (withJobException) + throw new RuntimeException("It is a programming exception"); + if (withInterruption) + interrupt(); + if (withTimeOut) + this.setTimeOut(1000); + if (withException) { + double a[] = new double[2]; + a[3] = 1; + } + if (!live) + return; + if (!isNotTimeOut()) { + return; + } + } + System.out.println("End of " + getName() + " iterations:" + i + " " + live + " " + done); + } + + } + + @Override + public void onEvent(Pool pool, JobEvent event) { + if (event.getTypeEvent() == JobEvent.INTERRUPTED) + System.out.println("Main side: Job Event " + event); + } + + @Override + public void onSuccess(Pool pool, JobEvent event) { + System.out.println(">>> Success " + event + " from pool " + pool.getName()); + System.out.println("Computation time: " + (System.nanoTime() - chrono) / 1000000.0); + } + + @Override + public void onFailure(Pool pool, JobEvent event) { + System.out.println(">>> Failure " + event + " from pool " + pool.getName()); + if (event.getException() != null) + event.getException().printStackTrace(); + } + + +} diff --git a/src/bilib/src/bilib/commons/job/worker/Job.java b/src/bilib/src/bilib/commons/job/worker/Job.java new file mode 100644 index 0000000000000000000000000000000000000000..f71a1216bea316e1606269558fe58825a1dead69 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/worker/Job.java @@ -0,0 +1,255 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.worker; + +import java.util.ArrayList; + +import javax.swing.SwingWorker; + +import bilib.commons.job.JobAbstract; +import bilib.commons.job.JobEvent; +import bilib.commons.job.MonitorAbstract; +import bilib.commons.job.PoolAbstract; + +public abstract class Job extends SwingWorker<Object, String> implements JobAbstract, MonitorAbstract { + + protected boolean live = false; + protected boolean done = false; + protected boolean idle = false; + + private double chrono = -1; + private double timeoutns = -1; + private boolean stopTimeOut = false; + private ArrayList<MonitorAbstract> monitors = new ArrayList<MonitorAbstract>(); + + private PoolAbstract pool; + + public abstract Object process() throws RuntimeException; + + private String name; + + public Job() { + } + + public Job(MonitorAbstract monitor) { + monitors.add(monitor); + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public PoolAbstract getPool() { + return pool; + } + + @Override + public void setPool(PoolAbstract pool) { + this.pool = pool; + } + + @Override + public void setTimeOut(double timeoutms) { + this.timeoutns = timeoutms * 1000000.0; + this.stopTimeOut = true; + } + + @Override + public void abort() { + idle = false; + live = false; + done = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.ABORTED)); + } + + @Override + public void interrupt() { + idle = false; + live = false; + done = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.INTERRUPTED)); + } + + @Override + public void abort(String message) { + idle = false; + live = false; + done = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.ABORTED, message)); + } + + @Override + public void interrupt(String message) { + idle = false; + live = false; + done = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.INTERRUPTED, message)); + } + + @Override + public void init() { + idle = true; + live = true; + done = false; + chrono = System.nanoTime(); + } + + @Override + public Object doInBackground() { + Object o = null; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.STARTED)); + try { + idle = false; + o = process(); + if (live) { + done = true; + live = false; + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.COMPLETED)); + } + } + catch (RuntimeException ex) { + if (pool != null) + pool.fire(new JobEvent(this, ex, ex.getMessage())); + } + live = false; + idle = true; + return o; + } + + @Override + public boolean isNotTimeOut() { + if (!live) + return false; + if (stopTimeOut) + if ((System.nanoTime() - chrono) > timeoutns) { + if (pool != null) + pool.fire(new JobEvent(this, JobEvent.TIMEOUT)); + live = false; + done = false; + return false; + } + return true; + } + + @Override + public boolean isJobLive() { + return live; + } + + @Override + public boolean isJobDone() { + return done; + } + + @Override + public boolean isJobIdle() { + return idle; + } + + @Override + public boolean isJobProcessing() { + return !idle; + } + + @Override + public boolean isJobIncomplete() { + return !done; + } + + @Override + public String toString() { + return "JobWorker: " + getName(); + } + + @Override + public void rewind() { + for (MonitorAbstract monitor : monitors) + monitor.rewind(); + } + + @Override + public void print(String message) { + for (MonitorAbstract monitor : monitors) + monitor.print(message); + } + + @Override + public void error(String message) { + for (MonitorAbstract monitor : monitors) + monitor.error(message); + } + + @Override + public void warning(String message) { + for (MonitorAbstract monitor : monitors) + monitor.warning(message); + } + + @Override + public void progress(double percentage) { + for (MonitorAbstract monitor : monitors) + monitor.progress(percentage); + } + + @Override + public void progress(double percentage, String message) { + for (MonitorAbstract monitor : monitors) + monitor.progress(percentage, message); + } + + @Override + public void increment(double percentageIncrement) { + for (MonitorAbstract monitor : monitors) + monitor.increment(percentageIncrement); + } + + @Override + public void increment(double percentageIncrement, String message) { + for (MonitorAbstract monitor : monitors) + monitor.increment(percentageIncrement, message); + } + + @Override + public void addMonitor(MonitorAbstract monitor) { + monitors.add(monitor); + } + + @Override + public void removeMonitor(MonitorAbstract monitor) { + monitors.remove(monitor); + } + + @Override + public void clearMonitor() { + monitors.clear(); + } + + @Override + public ArrayList<MonitorAbstract> getMonitor() { + return monitors; + } + +} diff --git a/src/bilib/src/bilib/commons/job/worker/Pool.java b/src/bilib/src/bilib/commons/job/worker/Pool.java new file mode 100644 index 0000000000000000000000000000000000000000..30fd246fedb79c93eaea39f627993bec0c229830 --- /dev/null +++ b/src/bilib/src/bilib/commons/job/worker/Pool.java @@ -0,0 +1,292 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.worker; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import bilib.commons.job.ExecutionMode; +import bilib.commons.job.JobAbstract; +import bilib.commons.job.JobEvent; +import bilib.commons.job.PoolAbstract; +import bilib.commons.job.worker.Job; +import bilib.commons.job.worker.PoolResponder; + +public class Pool implements PoolAbstract { + + private ArrayList<Job> jobs; + protected String name; + protected PoolResponder responder; + + protected HashMap<String, Future<Object>> results; + + /** + * Create a new pool with one registered job (Worker). + * + * @param job + * the job to register + * @param responder + * the responder handling the job event + */ + public Pool(Job job, PoolResponder responder) { + jobs = new ArrayList<Job>(); + results = new HashMap<String, Future<Object>>(); + this.name = job.getName(); + this.responder = responder; + register(job); + } + + /** + * Create a new pool without any registered job (Worker). + * + * @param name + * name of the pool + * @param responder + * the responder handling the job event + */ + public Pool(String name, PoolResponder responder) { + jobs = new ArrayList<Job>(); + results = new HashMap<String, Future<Object>>(); + this.name = name; + this.responder = responder; + } + + @Override + public void fire(JobEvent event) { + + int t = event.getTypeEvent(); + if (responder != null) + responder.onEvent(this, event); + + if (t == JobEvent.EXCEPTION) { + die(); + if (responder != null) { + responder.onFailure(this, event); + } + } + else if (t == JobEvent.ABORTED) { + die(); + if (responder != null) + responder.onFailure(this, event); + } + else if (t == JobEvent.TIMEOUT) { + die(); + if (responder != null) + responder.onFailure(this, event); + } + else if (t == JobEvent.COMPLETED) { + if (isJobDone()) { + die(); + if (responder != null) + responder.onSuccess(this, event); + } + } + } + + @Override + public void fire(JobAbstract parent, JobEvent event) { + if (parent == null) + return; + if (parent.getPool() == null) + return; + if (event.getTypeEvent() == JobEvent.EXCEPTION) + parent.getPool().fire(new JobEvent(parent, event.getException(), event.getMessage())); + else + parent.getPool().fire(new JobEvent(parent, event.getTypeEvent(), event.getMessage())); + + } + + public ArrayList<Job> getRegisteredJobs() { + return jobs; + } + + public Job getRegisteredJob(int i) { + return jobs.get(i); + } + + @Override + public void execute(ExecutionMode mode) { + execute(mode, jobs.size()); + } + + @SuppressWarnings("unchecked") + @Override + public void execute(ExecutionMode mode, int nThreads) { + for (Job job : jobs) + job.init(); + if (mode == ExecutionMode.MULTITHREAD_NO) { + try { + for (Job job : jobs) + job.doInBackground(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + else { + if (nThreads <= 0) + nThreads = jobs.size(); + ExecutorService executor = Executors.newFixedThreadPool(nThreads); + for (Job job : jobs) { + Future<?> future = executor.submit(job); + results.put(job.getName(), (Future<Object>) future); + } + executor.shutdown(); + if (mode == ExecutionMode.MULTITHREAD_SYNCHRONIZED) + waitTermination(); + } + } + + @Override + public Future<Object> getFuture(String jobName) { + if (jobs != null) + for (int i = 0; i < jobs.size(); i++) { + if (jobs.get(i).getName().equals(jobName)) + return results.get(jobs.get(i).getName()); + } + return null; + } + + @Override + public int size() { + int s = 0; + if (jobs != null) + s += jobs.size(); + return s; + } + + @Override + public void cancel() { + if (jobs != null) + for (Job job : jobs) + results.get(job.getName()).cancel(true); + } + + @Override + public void register(JobAbstract job) { + if (jobs == null) + return; + if (job instanceof Job) + if (jobs.add((Job) job)) { + job.setName(name + "-" + jobs.size()); + job.setPool(this); + } + } + + @Override + public void register(JobAbstract job, double timeoutms) { + if (jobs == null) + return; + if (job instanceof Job) + if (jobs.add((Job) job)) { + job.setTimeOut(timeoutms); + job.setName(name + "-" + jobs.size()); + job.setPool(this); + } + } + + @Override + public void unregister(JobAbstract job) { + if (jobs == null) + return; + if (job instanceof Job) { + jobs.remove((Job) job); + job.setPool(null); + } + } + + @Override + public void unregisterAll() { + if (jobs != null) + jobs.clear(); + } + + @Override + public boolean isJobDone() { + int count = 0; + if (jobs != null) { + for (Job job : jobs) { + if (job.done) + count++; + } + return (count == jobs.size()); + } + return false; + } + + @Override + public boolean isJobLive() { + int count = 0; + if (jobs != null) { + for (Job job : jobs) { + if (job.live) + count++; + } + return (count == jobs.size()); + } + return false; + } + + @Override + public boolean isJobIdle() { + int count = 0; + if (jobs != null) { + for (Job job : jobs) { + if (job.idle) + count++; + } + return (count == jobs.size()); + } + return false; + } + + @Override + public void waitTermination() { + boolean termination = false; + + if (jobs != null) + while (!termination) { + int count = 0; + for (Job job : jobs) + if (!job.live) + count++; + termination = (count >= jobs.size()); + } + } + + @Override + public synchronized void die() { + if (jobs != null) + for (Job job : jobs) { + job.live = false; + job.done = true; + } + } + + @Override + public String toString() { + String form = ""; + if (jobs != null) + form = jobs.getClass().getName(); + return " Pool=(" + name + ", " + size() + " " + form + ") "; + } + + @Override + public String getName() { + return name; + } + +} diff --git a/src/bilib/src/bilib/commons/job/worker/PoolResponder.java b/src/bilib/src/bilib/commons/job/worker/PoolResponder.java new file mode 100644 index 0000000000000000000000000000000000000000..b5c23ade9ed98f93cba08ded8c19ca9924ecfdfd --- /dev/null +++ b/src/bilib/src/bilib/commons/job/worker/PoolResponder.java @@ -0,0 +1,24 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.worker; + +import bilib.commons.job.JobEvent; + +public interface PoolResponder { + + public abstract void onEvent(Pool pool, JobEvent event); + + public abstract void onSuccess(Pool pool, JobEvent event); + + public abstract void onFailure(Pool pool, JobEvent event); +} diff --git a/src/bilib/src/bilib/commons/job/worker/WorkerDemo.java b/src/bilib/src/bilib/commons/job/worker/WorkerDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..4a76d0356689ed8a81c96167be5a41d2a35a876c --- /dev/null +++ b/src/bilib/src/bilib/commons/job/worker/WorkerDemo.java @@ -0,0 +1,303 @@ +//==================================================================================================== +// Project: Bilib Job +// +// Authors: Daniel Sage +// Organization: Biomedical Imaging Group (BIG), Ecole Polytechnique Federale de Lausanne +// Address: EPFL-STI-IMT-LIB, 1015 Lausanne, Switzerland +// +// Conditions of use: +// You'll be free to use this software for research purposes, but you should not redistribute +// it without our consent. In addition, we expect you to include a citation whenever you +// present or publish results that are based on it. +//==================================================================================================== +package bilib.commons.job.worker; + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; + +import bilib.commons.job.ExecutionMode; +import bilib.commons.job.JobEvent; +import bilib.commons.job.MonitorAbstract; +import bilib.commons.job.MonitorProgressBar; +import bilib.commons.job.MonitorTimedLog; +import bilib.commons.job.MonitorTimedProgressBar; +import bilib.commons.job.worker.PoolResponder; +import bilib.commons.job.worker.Job; + +public class WorkerDemo extends JFrame implements PoolResponder, ActionListener { + + public JRadioButton rbSequential = new JRadioButton("Sequential", false); + public JRadioButton rbAsynchronized = new JRadioButton("Parallel - Asynchronized jobs (not wait)", false); + public JRadioButton rbSynchronized = new JRadioButton("Parallel - Synchronized jobs (wait termination)", true); + + public JButton execute = new JButton("Execute"); + public JTextField nthreads = new JTextField("0"); + public JTextField njobs = new JTextField("10"); + public JButton simulateAbort = new JButton("Abort"); + public JButton simulateException = new JButton("Simulate an Exception"); + public JButton simulateJobException = new JButton("Simulate an JobException"); + public JButton simulateInterruption = new JButton("Simulate an Interruption"); + public JButton simulateCancellation = new JButton("Simulate an Cancellation"); + public JButton simulateTimeOut = new JButton("Simulate an TimeOut"); + + public MonitorTimedProgressBar bar = new MonitorTimedProgressBar(); + public MonitorProgressBar bar1 = new MonitorProgressBar(); + public MonitorTimedLog log = new MonitorTimedLog(10, 10); + + private double chrono; + private MainProcessing main; + + public static void main(String args[]) { + new WorkerDemo(); + } + + public WorkerDemo() { + super("Worker Demo"); + main = new MainProcessing(this); + + ButtonGroup bg1 = new ButtonGroup(); + bg1.add(rbSequential); + bg1.add(rbAsynchronized); + bg1.add(rbSynchronized); + + JPanel panel1 = new JPanel(new GridLayout(20, 1)); + + panel1.add(rbSequential); + panel1.add(rbAsynchronized); + panel1.add(rbSynchronized); + + panel1.add(new JLabel("Number of threads (0 = nb of jobs)")); + panel1.add(nthreads); + panel1.add(new JLabel("Number of jobs")); + panel1.add(njobs); + panel1.add(execute); + panel1.add(new JLabel("")); + panel1.add(simulateAbort); + panel1.add(simulateException); + panel1.add(simulateJobException); + panel1.add(simulateInterruption); + panel1.add(simulateCancellation); + panel1.add(simulateTimeOut); + + JPanel panel3 = new JPanel(new BorderLayout()); + panel3.add(bar, BorderLayout.NORTH); + panel3.add(bar1, BorderLayout.SOUTH); + + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); + panel.add(panel1, BorderLayout.NORTH); + panel.add(panel3, BorderLayout.SOUTH); + panel.add(log, BorderLayout.CENTER); + + execute.addActionListener(this); + simulateAbort.addActionListener(this); + simulateException.addActionListener(this); + simulateJobException.addActionListener(this); + simulateInterruption.addActionListener(this); + simulateCancellation.addActionListener(this); + simulateTimeOut.addActionListener(this); + getContentPane().add(panel); + pack(); + setVisible(true); + } + + private ExecutionMode getMode() { + ExecutionMode mode = ExecutionMode.MULTITHREAD_NO; + if (rbSynchronized.isSelected()) + mode = ExecutionMode.MULTITHREAD_SYNCHRONIZED; + if (rbAsynchronized.isSelected()) + mode = ExecutionMode.MULTITHREAD_ASYNCHRONIZED; + return mode; + } + + @Override + public void actionPerformed(ActionEvent event) { + + if (event.getSource() == execute) { + main.setMode(getMode(), Integer.parseInt(nthreads.getText()), Integer.parseInt(njobs.getText())); + System.out.println("\n\n"); + Pool pool = new Pool("Main", this); + pool.register(main); + pool.execute(ExecutionMode.MULTITHREAD_ASYNCHRONIZED); + chrono = System.nanoTime(); + } + + if (event.getSource() == simulateAbort) + main.simulateAbort(); + + if (event.getSource() == simulateException) + main.simulateException(); + + if (event.getSource() == simulateJobException) + main.simulateJobException(); + + if (event.getSource() == simulateInterruption) + main.simulateInterruption(); + + if (event.getSource() == simulateCancellation) + main.simulateCancellation(); + + if (event.getSource() == simulateTimeOut) + main.simulateTimeOut(); + } + + // + // MainProcessing + // + public class MainProcessing extends Job implements PoolResponder { + private ExecutionMode mode; + private int nthreads = 0; + private int njobs; + private PoolResponder responder; + private Pool pool; + private int niter = 15; + + public MainProcessing(PoolResponder responder) { + super(); + this.responder = responder; + } + + public void setMode(ExecutionMode mode, int nthreads, int njobs) { + this.mode = mode; + this.njobs = njobs; + this.nthreads = nthreads; + } + + @Override + public Object process() { + bar.rewind(); + bar1.rewind(); + log.rewind(); + + pool = new Pool("my", responder); + MyWorker p1 = new MyWorker(niter, bar); + p1.addMonitor(log); + p1.addMonitor(bar1); + pool.register(p1); + for (int i = 0; i < njobs; i++) + pool.register(new MyWorker(niter, bar)); + pool.execute(mode, nthreads); + + System.out.println("End of main"); + return "End"; + + } + + public void simulateAbort() { + if (pool != null) + pool.getRegisteredJob(pool.size() - 1).abort(); + } + + public void simulateCancellation() { + if (pool != null) + pool.cancel(); + } + + public void simulateException() { + if (pool != null) + ((MyWorker) pool.getRegisteredJob(pool.size() / 2 - 1)).withException = true; + } + + public void simulateJobException() { + if (pool != null) + ((MyWorker) pool.getRegisteredJob(pool.size() - 1)).withJobException = true; + } + + public void simulateInterruption() { + if (pool != null) + ((MyWorker) pool.getRegisteredJob(pool.size() - 1)).withInterruption = true; + } + + public void simulateTimeOut() { + if (pool != null) + ((MyWorker) pool.getRegisteredJob(pool.size() - 1)).withTimeOut = true; + } + + @Override + public void onEvent(Pool pool, JobEvent event) { + responder.onEvent(pool, event); + } + + @Override + public void onSuccess(Pool pool, JobEvent event) { + responder.onSuccess(pool, event); + } + + @Override + public void onFailure(Pool pool, JobEvent event) { + responder.onFailure(pool, event); + } + + } + + // + // MyWorker + // + public class MyWorker extends Job { + public boolean withTimeOut = false; + public boolean withInterruption = false; + public boolean withException = false; + public boolean withJobException = false; + private int niter = 15; + + public MyWorker(int niter, MonitorAbstract monitor) { + super(monitor); + this.niter = niter; + } + + @Override + public Object process() throws RuntimeException { + int i = 0; + for (i = 0; i < niter && live; i++) { + increment(2, getName() + " " + live + " " + done); + for (int j = 0; j < 600000 && live; j++) + Math.round(Math.cos(Math.exp(Math.pow(j, -3)))); + if (withJobException) + throw new RuntimeException("It is a programming exception"); + if (withInterruption) + interrupt(); + if (withTimeOut) + niter += 2; + if (withException) { + double a[] = new double[2]; + a[3] = 1; + } + if (!live) + return "KO"; + } + System.out.println("End of " + getName() + " iterations:" + i + " " + live + " " + done); + return "End of " + getName() + " iterations:" + i + " " + live + " " + done; + } + } + + @Override + public void onEvent(Pool pool, JobEvent event) { + if (event.getTypeEvent() == JobEvent.INTERRUPTED) + System.out.println("Main side: Job Event " + event); + } + + @Override + public void onSuccess(Pool pool, JobEvent event) { + System.out.println(">>> Success " + event + " from pool " + pool.getName()); + System.out.println("Computation time: " + (System.nanoTime() - chrono) / 1000000.0); + } + + @Override + public void onFailure(Pool pool, JobEvent event) { + System.out.println(">>> Failure " + event + " from pool " + pool.getName()); + if (event.getException() != null) + event.getException().printStackTrace(); + } + +} diff --git a/src/bilib/src/bilib/commons/math/.DS_Store b/src/bilib/src/bilib/commons/math/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c9486404a74a7352f8b49aa3dd1e300876d9d298 Binary files /dev/null and b/src/bilib/src/bilib/commons/math/.DS_Store differ diff --git a/src/bilib/src/bilib/commons/math/bessel/Bessel.java b/src/bilib/src/bilib/commons/math/bessel/Bessel.java new file mode 100644 index 0000000000000000000000000000000000000000..c0bb9870d027051e0c8b268ade63c3017237eb69 --- /dev/null +++ b/src/bilib/src/bilib/commons/math/bessel/Bessel.java @@ -0,0 +1,82 @@ +package bilib.commons.math.bessel; + +/** + * This class evaluates the Bessel function J0(x). It uses the polynomial + * approximations on p. 369-70 of Abramowitz & Stegun. The error in J0 is + * supposed to be less than or equal to 5 x 10^-8. The error in J1 is supposed + * to be less than or equal to 4 x 10^-8, relative to the value of x. The error + * in J2 depends on the error of J0 and J1, as J2 = 2*J1/x + J0. + * + * @author Hagai Kirshner, Biomedical Imaging Group, Ecole Polytechnique + * Federale de Lausanne (EPFL) + */ + +public class Bessel { + + /** + * Constants for Bessel function approximation according Abramowitz & Stegun + */ + private static double[] tJ0 = { 1.0, -2.2499997, 1.2656208, -0.3163866, 0.0444479, -0.0039444, 0.0002100 }; + private static double[] pJ0 = { -.78539816, -.04166397, -.00003954, 0.00262573, -.00054125, -.00029333, .00013558 }; + private static double[] fJ0 = { .79788456, -0.00000077, -.00552740, -.00009512, 0.00137237, -0.00072805, 0.00014476 }; + + private static double[] tJ1 = { 0.5, -0.56249985, 0.21093573, -0.03954289, 0.0443319, -0.00031761, 0.0001109 }; + private static double[] pJ1 = { -2.35619449, 0.12499612, 0.00005650, -0.00637879, 0.00074348, 0.00079824, -0.00029166 }; + private static double[] fJ1 = { 0.79788456, 0.00000156, 0.01689667, 0.00017105, -0.00249511, 0.00113653, -0.00020033 }; + + /** + * Returns the value of the Bessel function of the first kind of order zero + * (J0) at x. + */ + public static double J0(double x) { + if (x < 0.0) + x *= -1.0; + if (x <= 3.0) { + double y = x * x / 9.0; + return tJ0[0] + y * (tJ0[1] + y * (tJ0[2] + y * (tJ0[3] + y * (tJ0[4] + y * (tJ0[5] + y * tJ0[6]))))); + } + + double y = 3.0 / x; + double theta0 = x + pJ0[0] + y * (pJ0[1] + y * (pJ0[2] + y * (pJ0[3] + y * (pJ0[4] + y * (pJ0[5] + y * pJ0[6]))))); + double f0 = fJ0[0] + y * (fJ0[1] + y * (fJ0[2] + y * (fJ0[3] + y * (fJ0[4] + y * (fJ0[5] + y * fJ0[6]))))); + return Math.sqrt(1.0 / x) * f0 * Math.cos(theta0); + } + + /** + * Returns the value of the Bessel function of the first kind of order one + * (J1) at x. + */ + public static double J1(double x) { + + int sign = 1; + + if (x < 0.0) { + x *= -1.0; + sign = -1; + } + + if (x <= 3.0) { + double y = x * x / 9.0; + return sign * x * (tJ1[0] + y * (tJ1[1] + y * (tJ1[2] + y * (tJ1[3] + y * (tJ1[4] + y * (tJ1[5] + y * tJ1[6])))))); + } + + double y = 3.0 / x; + double theta1 = x + pJ1[0] + y * (pJ1[1] + y * (pJ1[2] + y * (pJ1[3] + y * (pJ1[4] + y * (pJ1[5] + y * pJ1[6]))))); + double f1 = fJ1[0] + y * (fJ1[1] + y * (fJ1[2] + y * (fJ1[3] + y * (fJ1[4] + y * (fJ1[5] + y * fJ1[6]))))); + return sign * Math.sqrt(1.0 / x) * f1 * Math.cos(theta1); + } + + /** + * Returns the value of the Bessel function of the first kind of order two + * (J2) at x. + */ + public static double J2(double x) { + + double value0 = J0(x); + double value1 = J1(x); + if (x == 0.0) + return 0.0; + else + return 2.0 * value1 / x + value0; + } +} \ No newline at end of file diff --git a/src/bilib/src/bilib/commons/math/windowing/Windowing.java b/src/bilib/src/bilib/commons/math/windowing/Windowing.java new file mode 100644 index 0000000000000000000000000000000000000000..de517f2a797591eb0a22f20ec7985752d104a525 --- /dev/null +++ b/src/bilib/src/bilib/commons/math/windowing/Windowing.java @@ -0,0 +1,177 @@ +package bilib.commons.math.windowing; + +public class Windowing { + + static public double rectangle(double x, double N) { + return elliptical(x, N); + } + + static public double elliptical(double x, double N) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + return 1.0; + } + + static public double bartlett(double x, double N) { + return triangle(x, N); + } + + static public double triangle(double x, double N) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + return 1.0 - Math.abs(2.0 * x / N); + } + + static public double gaussian(double x, double N, double sigma) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + return Math.exp(-0.5 * x * x / (sigma * sigma)); + } + + static public double gaussian(double x, double N) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + double sigma = N / 3.0; + return Math.exp(-0.5 * x * x / (sigma * sigma)); + } + + static public double supergaussian(double x, double N, double sigma) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + return Math.exp(-0.5 * x * x * x * x * x * x / (sigma * sigma)); + } + + static public double supergaussian(double x, double N) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + double sigma = N / 3.0; + return Math.exp(-0.5 * x * x * x * x * x * x / (sigma * sigma)); + } + + static public double cosine(double x, double N) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + double t = 2.0 * x / N; + return Math.cos(Math.PI * 0.5 * t); + } + + static public double raisedcosine(double x, double N, double power) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + double t = 2.0 * x / N; + return Math.pow(Math.cos(Math.PI * 0.5 * t), power); + } + + static public double cubicspline(double x, double N) { + double t = 2.0 * x / (0.5 * N); + if (t < -2.0) + return 0.0; + if (t < -1.0) + return 0.25 * (t + 2.0) * (t + 2.0) * (t + 2.0); + if (t < 0.0) + return 0.25 * (-3.0 * t * t * t - 6.0 * t * t + 4.0); + if (t < 1.0) + return 0.25 * (3.0 * t * t * t - 6.0 * t * t + 4.0); + if (t < 2.0) + return 0.25 * (2.0 - t) * (2.0 - t) * (2.0 - t); + return 0; + } + + static public double parzen(double x, double N) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + double t = 2.0 * (x < 0 ? -x : x) / N; + if (t < 0.5) + return 1.0 - 6.0 * t * t + 6.0 * t * t * t; + if (t < 1.0) + return 2.0 * (1.0 - t) * (1.0 - t) * (1.0 - t); + return 0; + } + + static public double sigmoid(double x, double N, double slope) { + return 1.0 / (1.0 + Math.exp(-slope * (x + N * 0.5))) - 1.0 / (1.0 + Math.exp(-slope * (x - N * 0.5))); + } + + static public double hann(double x, double N) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + double t = 2.0 * x / N; + return Math.cos(0.5 * Math.PI * t); + } + + static public double hamming(double x, double N, double alpha) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + double t = 2.0 * x / N; + return alpha + (1.0 - alpha) * Math.cos(Math.PI * t); + } + + static public double tukey(double x, double N, double alpha) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + if (x > -0.5 * N + alpha && x < 0.5 * N - alpha) + return 1.0; + return Math.cos(Math.PI * ((2 * x - N) / (4 * alpha) + 0.5)); + } + + static public double exponential(double x, double N) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + double k = 4.60517018599 / N; + return Math.exp(-((x < 0 ? -x : x)) * k); + } + + static public double lanczos(double x, double N) { + if (x < -0.5 * N) + return 0; + if (x > 0.5 * N) + return 0; + double t = 2.0 * x / N; + if (t == 0) + return 1.0; + return Math.sin(Math.PI * t) / (Math.PI * t); + } + + public static void main(String args[]) { + + double N = 20; + + String title = "t\trectangle\ttriangle\tgaussian3\tgaussian\tsupergaussian3\tsupergaussian\tcosine\traisedcosine\tcubicspline\tparzen\tsigmoid\thann\thamming\ttukey\texponential\tlanczos"; + System.out.println(title); + for (double x = -25; x < 25; x += 0.1) { + double[] results = new double[] { x, rectangle(x, N), triangle(x, N), gaussian(x, N, 3), gaussian(x, N), supergaussian(x, N, 3), supergaussian(x, N), cosine(x, N), + raisedcosine(x, N, 6), cubicspline(x, N), parzen(x, N), sigmoid(x, N, 10), hann(x, N), hamming(x, N, 0.5), tukey(x, N, 2), exponential(x, N), lanczos(x, N) }; + String s = ""; + for (int i = 0; i < results.length; i++) + s += String.format("%2.3f\t ", results[i]); + System.out.println(s); + } + } + +} diff --git a/src/bilib/src/bilib/commons/random/Noise.java b/src/bilib/src/bilib/commons/random/Noise.java new file mode 100644 index 0000000000000000000000000000000000000000..e33bf7a93bc43eb858808e174c8125032355f7cf --- /dev/null +++ b/src/bilib/src/bilib/commons/random/Noise.java @@ -0,0 +1,29 @@ +package bilib.commons.random; + +import java.util.Random; + +import javax.swing.JPanel; + +import bilib.commons.settings.Settings; + +public abstract class Noise { + + public Random random = new Random(); + + public abstract void fetchParameters(); + + public abstract String getName(); + + public abstract double nextValue(); + + public abstract JPanel buildPanel(Settings settings); + + public void load(Settings settings) { + settings.loadRecordedItems(); + } + + public void store(Settings settings) { + settings.storeRecordedItems(); + } + +} diff --git a/src/bilib/src/bilib/commons/random/NoiseExponential.java b/src/bilib/src/bilib/commons/random/NoiseExponential.java new file mode 100644 index 0000000000000000000000000000000000000000..ecb1be2bdeda74bf40b64162f01afee66f2b0b7a --- /dev/null +++ b/src/bilib/src/bilib/commons/random/NoiseExponential.java @@ -0,0 +1,50 @@ +package bilib.commons.random; + +import javax.swing.JPanel; + +import bilib.commons.components.GridPanel; +import bilib.commons.components.SpinnerRangeDouble; +import bilib.commons.settings.Settings; + +public class NoiseExponential extends Noise { + + private double mean = 0.0; + private double stdev = 1.0; + private SpinnerRangeDouble spnMean = new SpinnerRangeDouble(0, -Double.MAX_VALUE, Double.MAX_VALUE, 1, "0.000"); + private SpinnerRangeDouble spnStd = new SpinnerRangeDouble(1, 0, Double.MAX_VALUE, 0.5, "0.000"); + + public NoiseExponential(double mean, double stdev) { + this.mean = mean; + this.stdev = stdev; + } + + @Override + public String getName() { + return "Exponential"; + } + + @Override + public void fetchParameters() { + this.mean = spnMean.get(); + this.stdev = spnStd.get(); + } + + @Override + public double nextValue() { + return mean + stdev * random.nextGaussian(); + } + + @Override + public JPanel buildPanel(Settings settings) { + GridPanel panel = new GridPanel(false); + panel.place(1, 0, "Mean"); + panel.place(1, 1, spnMean); + panel.place(2, 0, "Standard deviation"); + panel.place(2, 1, spnStd); + settings.record("random-" + getName() + "-mean", spnMean, "0"); + settings.record("random-" + getName() + "-stdev", spnStd, "1"); + settings.loadRecordedItems(); + return panel; + } + +} diff --git a/src/bilib/src/bilib/commons/random/NoiseGaussian.java b/src/bilib/src/bilib/commons/random/NoiseGaussian.java new file mode 100644 index 0000000000000000000000000000000000000000..f8d4b2ab4f32833559171c1969b02c47d2e14bea --- /dev/null +++ b/src/bilib/src/bilib/commons/random/NoiseGaussian.java @@ -0,0 +1,50 @@ +package bilib.commons.random; + +import javax.swing.JPanel; + +import bilib.commons.components.GridPanel; +import bilib.commons.components.SpinnerRangeDouble; +import bilib.commons.settings.Settings; + +public class NoiseGaussian extends Noise { + + private double mean = 0.0; + private double stdev = 1.0; + private SpinnerRangeDouble spnMean = new SpinnerRangeDouble(0, -Double.MAX_VALUE, Double.MAX_VALUE, 1); + private SpinnerRangeDouble spnStd = new SpinnerRangeDouble(1, 0, Double.MAX_VALUE, 0.5); + + public NoiseGaussian(double mean, double stdev) { + this.mean = mean; + this.stdev = stdev; + } + + @Override + public String getName() { + return "Gaussian"; + } + + @Override + public void fetchParameters() { + this.mean = spnMean.get(); + this.stdev = spnStd.get(); + } + + @Override + public double nextValue() { + return mean + stdev * random.nextGaussian(); + } + + @Override + public JPanel buildPanel(Settings settings) { + GridPanel panel = new GridPanel(false); + panel.place(1, 0, "Mean"); + panel.place(1, 1, spnMean); + panel.place(2, 0, "Standard deviation"); + panel.place(2, 1, spnStd); + settings.record("random-" + getName() + "-mean", spnMean, "0"); + settings.record("random-" + getName() + "-stdev", spnStd, "1"); + settings.loadRecordedItems(); + return panel; + } + +} diff --git a/src/bilib/src/bilib/commons/random/NoisePoisson.java b/src/bilib/src/bilib/commons/random/NoisePoisson.java new file mode 100644 index 0000000000000000000000000000000000000000..930d666190819562b2dcf171fc4286f024369cae --- /dev/null +++ b/src/bilib/src/bilib/commons/random/NoisePoisson.java @@ -0,0 +1,98 @@ +package bilib.commons.random; + +import javax.swing.JPanel; + +import bilib.commons.components.GridPanel; +import bilib.commons.components.SpinnerRangeDouble; +import bilib.commons.settings.Settings; + +public class NoisePoisson extends Noise { + + private double mean = 0.0; + private SpinnerRangeDouble spnMean = new SpinnerRangeDouble(1, -Double.MAX_VALUE, Double.MAX_VALUE, 1, "0.000"); + + public NoisePoisson(double mean) { + this.mean = mean; + } + + @Override + public String getName() { + return "Poisson"; + } + + @Override + public void fetchParameters() { + this.mean = spnMean.get(); + } + + @Override + public double nextValue() { + return poidev(mean); + } + + @Override + public JPanel buildPanel(Settings settings) { + GridPanel panel = new GridPanel(false); + panel.place(1, 0, "Mean/Variance"); + panel.place(1, 1, spnMean); + settings.record("random-" + getName() + "-mean", spnMean, "1"); + settings.loadRecordedItems(); + return panel; + } + + private double poidev(double xm) { + + double sq = 0, alxm = 0, g = 0, oldm = (-1.0); + double em, t, y; + if (xm < 12.0) { + if (xm != oldm) { + oldm = xm; + g = Math.exp(-xm); + } + em = -1; + t = 1.0; + do { + ++em; + t *= random.nextDouble(); + ; + } + while (t > g); + } + else { + if (xm != oldm) { + oldm = xm; + sq = Math.sqrt(2.0 * xm); + alxm = Math.log(xm); + g = xm * alxm - gammln(xm + 1.0); + } + do { + do { + y = Math.tan(Math.PI * random.nextDouble()); + em = sq * y + xm; + } + while (em < 0.0); + em = Math.floor(em); + t = 0.9 * (1.0 + y * y) * Math.exp(em * alxm - gammln(em + 1.0) - g); + + } + while (random.nextDouble() > t); + } + return em; + } + + // Internal arithmetic will be done in double precision, a nicety that you + // can omit if five-figure + // accuracy is good enough. + double gammln(double xx) { + double x, y, tmp, ser; + double cof[] = new double[] { 76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5 }; + int j; + y = x = xx; + tmp = x + 5.5; + tmp -= (x + 0.5) * Math.log(tmp); + ser = 1.000000000190015; + for (j = 0; j <= 5; j++) + ser += cof[j] / ++y; + return -tmp + Math.log(2.5066282746310005 * ser / x); + } +} diff --git a/src/bilib/src/bilib/commons/random/NoiseRayleigh.java b/src/bilib/src/bilib/commons/random/NoiseRayleigh.java new file mode 100644 index 0000000000000000000000000000000000000000..c547f63a528a439f63bb2c5f0578e3d9cffd0ef6 --- /dev/null +++ b/src/bilib/src/bilib/commons/random/NoiseRayleigh.java @@ -0,0 +1,43 @@ +package bilib.commons.random; + +import javax.swing.JPanel; + +import bilib.commons.components.GridPanel; +import bilib.commons.components.SpinnerRangeDouble; +import bilib.commons.settings.Settings; + +public class NoiseRayleigh extends Noise { + + private double sigma = 1.0; + private SpinnerRangeDouble spnSigma = new SpinnerRangeDouble(1, -Double.MAX_VALUE, Double.MAX_VALUE, 1); + + public NoiseRayleigh(double sigma) { + this.sigma = sigma; + } + + @Override + public String getName() { + return "Rayleigh"; + } + + @Override + public void fetchParameters() { + this.sigma = spnSigma.get(); + } + + @Override + public double nextValue() { + return Math.sqrt(-2.0D * Math.log(1.0D - random.nextDouble())) * sigma; + } + + @Override + public JPanel buildPanel(Settings settings) { + GridPanel panel = new GridPanel(false); + panel.place(1, 0, "Sigma"); + panel.place(1, 1, spnSigma); + settings.record("random-" + getName() + "-sigma", spnSigma, "1"); + settings.loadRecordedItems(); + return panel; + } + +} diff --git a/src/bilib/src/bilib/commons/random/NoiseUniform.java b/src/bilib/src/bilib/commons/random/NoiseUniform.java new file mode 100644 index 0000000000000000000000000000000000000000..f3f1fbbcd5237269761d5cf363f0c4cafe3335d9 --- /dev/null +++ b/src/bilib/src/bilib/commons/random/NoiseUniform.java @@ -0,0 +1,51 @@ +package bilib.commons.random; + +import javax.swing.JPanel; + +import bilib.commons.components.GridPanel; +import bilib.commons.components.SpinnerRangeDouble; +import bilib.commons.settings.Settings; + +public class NoiseUniform extends Noise { + + private double lower = 0.0; + private double upper = 1.0; + private SpinnerRangeDouble spnLower = new SpinnerRangeDouble(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 1, "0.000"); + private SpinnerRangeDouble spnUpper = new SpinnerRangeDouble(1.0, -Double.MAX_VALUE, Double.MAX_VALUE, 1, "0.000"); + + public NoiseUniform(double lower, double upper) { + this.lower = lower; + this.upper = upper; + } + + @Override + public String getName() { + return "Uniform"; + } + + @Override + public void fetchParameters() { + this.lower = spnLower.get(); + this.upper = spnUpper.get(); + } + + @Override + public double nextValue() { + return (upper - lower) * random.nextDouble() + upper; + } + + @Override + public JPanel buildPanel(Settings settings) { + GridPanel panel = new GridPanel(false); + panel.place(1, 0, "Lower value"); + panel.place(1, 1, spnLower); + panel.place(2, 0, "Upper value"); + panel.place(2, 1, spnUpper); + settings.record("random-" + getName() + "-lower", spnLower, "0"); + settings.record("random-" + getName() + "-upper", spnUpper, "1"); + settings.loadRecordedItems(); + + return panel; + } + +} diff --git a/src/bilib/src/bilib/commons/settings/Settings.java b/src/bilib/src/bilib/commons/settings/Settings.java new file mode 100644 index 0000000000000000000000000000000000000000..489b45288075498715fe197f0a836f34f5e2b3ae --- /dev/null +++ b/src/bilib/src/bilib/commons/settings/Settings.java @@ -0,0 +1,430 @@ +package bilib.commons.settings; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.Properties; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JSlider; +import javax.swing.JSpinner; +import javax.swing.JTextField; +import javax.swing.JToggleButton; + +import bilib.commons.components.SpinnerRangeDouble; +import bilib.commons.components.SpinnerRangeFloat; +import bilib.commons.components.SpinnerRangeInteger; + +/** + * This class allows to store and load key-associated values in a text file. The + * class has methods to load and store single value linked to a string key + * describing the value. Furthermore, this class has methods to record a GUI + * component to a specified key. By this way this class allows to load and store + * all recorded items. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class Settings { + + private String filename; + private String project; + private ArrayList<Item> items; + private Properties props; + + /** + * Constructors a Settings abject for a given project name and a given + * filename. + * + * @param project + * a string describing the project + * @param filename + * a string give the full name of the file, including the path + */ + public Settings(String project, String filename) { + this.filename = filename; + this.project = project; + items = new ArrayList<Item>(); + props = new Properties(); + } + + public String getProject() { + return project; + } + + public String getFilename() { + return filename; + } + + /** + * Records a JTextField component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JTextField component, String defaultValue) { + Item item = new Item(key, component, defaultValue); + items.add(item); + } + + /** + * Records a JComboBox component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JComboBox component, String defaultValue) { + Item item = new Item(key, component, defaultValue); + items.add(item); + } + + /** + * Records a JSpinner component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JSpinner component, String defaultValue) { + Item item = new Item(key, component, defaultValue); + items.add(item); + } + + /** + * Records a JToggleButton component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JToggleButton component, boolean defaultValue) { + Item item = new Item(key, component, (defaultValue ? "on" : "off")); + items.add(item); + } + + /** + * Records a JCheckBox component to store/load automatically. + * + * @param key + * a string describing the value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JCheckBox component, boolean defaultValue) { + Item item = new Item(key, component, (defaultValue ? "on" : "off")); + items.add(item); + } + + /** + * Records a JSlider component to store/load automatically. + * + * @param key + * a int value + * @param component + * the component to record + * @param defaultValue + * the default value + */ + public void record(String key, JSlider component, String defaultValue) { + Item item = new Item(key, component, defaultValue); + items.add(item); + } + + /** + * Load an individual double value given a specified key + * + * @param key + * a string describing the value + * @param defaultValue + * the default value + * @return the value get from the file + */ + public String loadValue(String key, String defaultValue) { + String s = ""; + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + s = props.getProperty(key, "" + defaultValue); + } + catch (Exception e) { + s = defaultValue; + } + return s; + } + + /** + * Load an individual double value given a specified key + * + * @param key + * a string describing the value + * @param defaultValue + * the default value + * @return the value get from the file + */ + public double loadValue(String key, double defaultValue) { + double d = 0; + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + String value = props.getProperty(key, "" + defaultValue); + d = (new Double(value)).doubleValue(); + } + catch (Exception e) { + d = defaultValue; + } + return d; + } + + /** + * Load an individual integer value given a specified key + * + * @param key + * a string describing the value + * @param defaultValue + * the default value + * @return the value get from the file + */ + public int loadValue(String key, int defaultValue) { + int i = 0; + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + String value = props.getProperty(key, "" + defaultValue); + i = (new Integer(value)).intValue(); + } + catch (Exception e) { + i = defaultValue; + } + return i; + } + + /** + * Load an individual boolean value given a specified key + * + * @param key + * a string describing the value + * @param defaultValue + * the default value + * @return the value get from the file + */ + public boolean loadValue(String key, boolean defaultValue) { + boolean b = false; + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + String value = props.getProperty(key, "" + defaultValue); + b = (new Boolean(value)).booleanValue(); + } + catch (Exception e) { + b = defaultValue; + } + return b; + } + + /** + * Store an individual double value given a specified key + * + * @param key + * a string describing the value + * @param value + * the value to store + */ + public void storeValue(String key, String value) { + props.setProperty(key, value); + try { + FileOutputStream out = new FileOutputStream(filename); + props.store(out, project); + } + catch (Exception e) { + System.out.println(project + ": Impossible to store settings in (" + filename + ")"); + } + } + + /** + * Store an individual double value given a specified key + * + * @param key + * a string describing the value + * @param value + * the value to store + */ + public void storeValue(String key, double value) { + props.setProperty(key, "" + value); + try { + FileOutputStream out = new FileOutputStream(filename); + props.store(out, project); + } + catch (Exception e) { + System.out.println(project + ": Impossible to store settings in (" + filename + ")"); + } + } + + /** + * Store an individual integer value given a specified key + * + * @param key + * a string describing the value + * @param value + * the value to store + */ + public void storeValue(String key, int value) { + props.setProperty(key, "" + value); + try { + FileOutputStream out = new FileOutputStream(filename); + props.store(out, project); + } + catch (Exception e) { + System.out.println(project + ": Impossible to store settings in (" + filename + ")"); + } + } + + /** + * Store an individual boolean value given a specified key + * + * @param key + * a string describing the value + * @param value + * the value to store + */ + public void storeValue(String key, boolean value) { + props.setProperty(key, "" + value); + try { + FileOutputStream out = new FileOutputStream(filename); + props.store(out, project); + } + catch (Exception e) { + System.out.println(project + ": Impossible to store settings in (" + filename + ")"); + } + } + + /** + * Load all recorded values. + */ + public void loadRecordedItems() { + loadRecordedItems(filename); + } + + /** + * Load all recorded values from a specified filename. + */ + public void loadRecordedItems(String fname) { + try { + FileInputStream in = new FileInputStream(fname); + props.load(in); + } + catch (Exception e) { + props = new Properties(); + } + + for (int i = 0; i < items.size(); i++) { + Item item = (Item) items.get(i); + String value = props.getProperty(item.key, item.defaultValue); + if (item.component instanceof JTextField) { + ((JTextField) item.component).setText(value); + } + else if (item.component instanceof JComboBox) { + ((JComboBox) item.component).setSelectedItem(value); + } + else if (item.component instanceof JCheckBox) { + ((JCheckBox) item.component).setSelected(value.equals("on") ? true : false); + } + else if (item.component instanceof JToggleButton) { + ((JToggleButton) item.component).setSelected(value.equals("on") ? true : false); + } + else if (item.component instanceof SpinnerRangeInteger) { + ((SpinnerRangeInteger) item.component).set(Math.round((new Double(value)).intValue())); + } + else if (item.component instanceof SpinnerRangeDouble) { + ((SpinnerRangeDouble) item.component).set((new Double(value)).doubleValue()); + } + else if (item.component instanceof SpinnerRangeFloat) { + ((SpinnerRangeFloat) item.component).set((new Float(value)).floatValue()); + } + else if (item.component instanceof JSlider) { + ((JSlider) item.component).setValue((new Integer(value)).intValue()); + } + } + } + + /** + * Store all recorded values. + */ + public void storeRecordedItems() { + storeRecordedItems(filename); + } + + /** + * Store all recorded values into a specified filename + */ + public void storeRecordedItems(String fname) { + + for (int i = 0; i < items.size(); i++) { + Item item = (Item) items.get(i); + if (item.component instanceof JTextField) { + String value = ((JTextField) item.component).getText(); + props.setProperty(item.key, value); + } + else if (item.component instanceof JComboBox) { + String value = (String) ((JComboBox) item.component).getSelectedItem(); + props.setProperty(item.key, value); + } + else if (item.component instanceof JCheckBox) { + String value = (((JCheckBox) item.component).isSelected() ? "on" : "off"); + props.setProperty(item.key, value); + } + else if (item.component instanceof JToggleButton) { + String value = (((JToggleButton) item.component).isSelected() ? "on" : "off"); + props.setProperty(item.key, value); + } + else if (item.component instanceof JSpinner) { + String value = "" + ((JSpinner) item.component).getValue(); + props.setProperty(item.key, value); + } + else if (item.component instanceof JSlider) { + String value = "" + ((JSlider) item.component).getValue(); + props.setProperty(item.key, value); + } + } + + try { + FileOutputStream out = new FileOutputStream(fname); + props.store(out, project); + } + catch (Exception e) { + System.out.println(project + ": Impossible to store settings in (" + fname + ")"); + } + } + + /** + * Private class to store one component and its key. + */ + private class Item { + public Object component; + public String defaultValue; + public String key; + + public Item(String key, Object component, String defaultValue) { + this.component = component; + this.defaultValue = defaultValue; + this.key = key; + } + } + +} diff --git a/src/bilib/src/bilib/commons/settings/SettingsFileDialog.java b/src/bilib/src/bilib/commons/settings/SettingsFileDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..3fda912489d431ac376782e802e515a7a91e96df --- /dev/null +++ b/src/bilib/src/bilib/commons/settings/SettingsFileDialog.java @@ -0,0 +1,107 @@ +package bilib.commons.settings; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.filechooser.FileNameExtensionFilter; + +public class SettingsFileDialog extends JDialog implements ActionListener { + private JTextField txt; + private JButton bnCancel = new JButton("Cancel"); + private JButton bnReset = new JButton("Default"); + private JButton bnSaveAs = new JButton("Save As"); + private JButton bnLoad = new JButton("Load"); + private JButton bnSave = new JButton("Save"); + + private Settings settings; + + public SettingsFileDialog(Settings settings) { + super(new JFrame(), "Settings of " + settings.getProject()); + this.settings = settings; + txt = new JTextField(settings.getFilename()); + + txt.setEditable(false); + Container contentPane = getContentPane(); + contentPane.setLayout(new BorderLayout()); + + JPanel pn1 = new JPanel(new FlowLayout()); + pn1.add(txt); + + JPanel pn2 = new JPanel(new FlowLayout()); + pn2.add(bnCancel); + pn2.add(bnReset); + pn2.add(bnSave); + pn2.add(bnSaveAs); + pn2.add(bnLoad); + + contentPane.add(pn1, BorderLayout.NORTH); + contentPane.add(pn2, BorderLayout.SOUTH); + bnCancel.addActionListener(this); + bnReset.addActionListener(this); + bnSaveAs.addActionListener(this); + bnSave.addActionListener(this); + bnLoad.addActionListener(this); + pack(); + + setModalityType(JDialog.ModalityType.APPLICATION_MODAL); + setResizable(false); + Dimension dim = getToolkit().getScreenSize(); + Rectangle abounds = getBounds(); + setLocation((dim.width - abounds.width) / 2, (dim.height - abounds.height) / 2); + setVisible(true); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == bnSaveAs) { + JFileChooser chooser = new JFileChooser(txt.getText()); + chooser.setSelectedFile(new File("config.txt")); + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + chooser.setFileFilter(new FileNameExtensionFilter("Configuration file", "txt")); + int returnVal = chooser.showSaveDialog(new JFrame()); + if (returnVal == JFileChooser.APPROVE_OPTION) { + String name = chooser.getSelectedFile().getAbsolutePath(); + if (!name.endsWith(".txt")) + name += ".txt"; + txt.setText(name); + settings.storeRecordedItems(txt.getText()); + } + } + else if (e.getSource() == bnLoad) { + JFileChooser chooser = new JFileChooser(txt.getText()); + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + chooser.setFileFilter(new FileNameExtensionFilter("Configuration file", "txt")); + int returnVal = chooser.showOpenDialog(new JFrame()); + if (returnVal == JFileChooser.APPROVE_OPTION) { + String name = chooser.getSelectedFile().getAbsolutePath(); + txt.setText(name); + } + settings.loadRecordedItems(txt.getText()); + } + else if (e.getSource() == bnSave) { + settings.storeRecordedItems(txt.getText()); + } + else if (e.getSource() == bnReset) { + settings.loadRecordedItems("default-no-file"); + } + + bnCancel.removeActionListener(this); + bnReset.removeActionListener(this); + bnLoad.removeActionListener(this); + bnSave.removeActionListener(this); + bnSaveAs.removeActionListener(this); + dispose(); + } +} \ No newline at end of file diff --git a/src/bilib/src/bilib/commons/table/CustomizedColumn.java b/src/bilib/src/bilib/commons/table/CustomizedColumn.java new file mode 100644 index 0000000000000000000000000000000000000000..f37537a32efe6e022f567576d2d7d9ddde699905 --- /dev/null +++ b/src/bilib/src/bilib/commons/table/CustomizedColumn.java @@ -0,0 +1,102 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.table; + +/** + * This class allows to customized the columns of the CustomizedTable tables. + * + * @author Daniel Sage + * + */ +public class CustomizedColumn { + + private Class<?> columnClasse; // usually it is a String + private String header; + private boolean editable; + private int width; + private String[] choices; // ComboBox + private String button; // Button + private String tooltip; + + public CustomizedColumn(String header, Class<?> columnClasse, int width, boolean editable) { + this.columnClasse = columnClasse; + this.header = header; + this.width = width; + this.editable = editable; + } + + public CustomizedColumn(String header, Class<?> classe, int width, String[] choices, String tooltip) { + this.columnClasse = classe; + this.header = header; + this.width = width; + this.editable = true; + this.choices = choices; + this.tooltip = tooltip; + } + + public CustomizedColumn(String header, Class<?> columnClasse, int width, String button, String tooltip) { + this.columnClasse = columnClasse; + this.header = header; + this.width = width; + this.editable = false; + this.button = button; + this.tooltip = tooltip; + } + + public Class<?> getColumnClass() { + return columnClasse; + } + + public String getHeader() { + return header; + } + + public boolean isEditable() { + return editable; + } + + public int getWidth() { + return width; + } + + public String[] getChoices() { + return choices; + } + + public String getButton() { + return button; + } + + public String getTooltip() { + return tooltip; + } +} diff --git a/src/bilib/src/bilib/commons/table/CustomizedTable.java b/src/bilib/src/bilib/commons/table/CustomizedTable.java new file mode 100644 index 0000000000000000000000000000000000000000..9f8dfa77484a61d550b26e8a4a411df46dcfe215 --- /dev/null +++ b/src/bilib/src/bilib/commons/table/CustomizedTable.java @@ -0,0 +1,336 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.table; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.Rectangle; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; + +import javax.swing.DefaultCellEditor; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; + +/** + * This class build a table by extending JTable. Usually the contructor expects + * a list of CustomizedColumn objects that defines the columns of the table. + * + * @author Daniel Sage + * + */ + +public class CustomizedTable extends JTable { + + private JScrollPane pane = null; + private ArrayList<CustomizedColumn> columns; + + public CustomizedTable(ArrayList<CustomizedColumn> columns, boolean sortable) { + create(columns); + setAutoCreateRowSorter(sortable); + setRowHeight(20); + } + + + public CustomizedTable(String headers[], boolean sortable) { + ArrayList<CustomizedColumn> colums = new ArrayList<CustomizedColumn>(); + for (int i = 0; i < headers.length; i++) + colums.add(new CustomizedColumn(headers[i], String.class, 150, false)); + create(colums); + setAutoCreateRowSorter(sortable); + setRowHeight(20); + } + + private void create(ArrayList<CustomizedColumn> column) { + columns = column; + DefaultTableModel model = new DefaultTableModel() { + @Override + public boolean isCellEditable(int row, int col) { + return columns.get(col).isEditable(); + } + + @Override + public Class<?> getColumnClass(int col) { + return columns.get(col).getColumnClass(); + } + }; + + setModel(model); + int n = columns.size(); + String headers[] = new String[n]; + for (int col = 0; col < n; col++) + headers[col] = columns.get(col).getHeader(); + + model.setColumnIdentifiers(headers); + setFillsViewportHeight(true); + + for (int col = 0; col < n; col++) { + TableColumn tc = getColumnModel().getColumn(col); + tc.setPreferredWidth(columns.get(col).getWidth()); + + if (columns.get(col).getChoices() != null) { + JComboBox cmb = new JComboBox(); + for (String p : columns.get(col).getChoices()) { + cmb.addItem(p); + cmb.setToolTipText(columns.get(col).getTooltip()); + tc.setCellEditor(new DefaultCellEditor(cmb)); + } + } + if (columns.get(col).getButton() != null) { + ButtonRenderer bn = new ButtonRenderer(); + bn.setToolTipText(columns.get(col).getTooltip()); + tc.setCellRenderer(bn); + } + } + getTableHeader().setReorderingAllowed(false); + } + + public void setPreferredSize(int width, int height) { + if (pane != null) + pane.setPreferredSize(new Dimension(width, height)); + } + + /** + * Removes one specify row from the table. + * + * @param row Row to remove + */ + public void removeRow(int row) { + if (row >= 0 && row < getRowCount()) + ((DefaultTableModel) getModel()).removeRow(row); + } + + /** + * Removes all rows of the table. + */ + public void removeRows() { + while (getRowCount() > 0) + ((DefaultTableModel) getModel()).removeRow(0); + } + + public String[] getRow(int row) { + if (row >= 0) { + int ncol = getColumnCount(); + String items[] = new String[ncol]; + for (int col = 0; col < ncol; col++) + items[col] = (String) getModel().getValueAt(row, col); + return items; + } + return new String[1]; + } + + public String getCell(int row, int col) { + if (row >= 0 && col >= 0) { + return (String) getModel().getValueAt(row, col); + } + return ""; + } + + public void setCell(int row, int col, String value) { + if (row >= 0 && col >= 0) { + getModel().setValueAt(value, row, col); + } + } + + public String getRowCSV(int row, String seperator) { + if (row >= 0) { + int ncol = getColumnCount(); + String items = ""; + for (int col = 0; col < ncol - 1; col++) { + if ((String) getModel().getValueAt(row, col) == null) + items += "" + seperator; + else + items += (String) getModel().getValueAt(row, col) + seperator; + } + if (ncol >= 1) + items += (String) getModel().getValueAt(row, ncol - 1); + return items; + } + return ""; + } + + /** + * Saves the table in a CSV file + * + * @param filename Complete path and filename + */ + public void storeCSV(String filename) { + File file = new File(filename); + try { + BufferedWriter buffer = new BufferedWriter(new FileWriter(file)); + int nrows = getRowCount(); + int ncols = getColumnCount(); + + String row = ""; + for (int c = 0; c < columns.size(); c++) + row += columns.get(c).getHeader() + (c == columns.size() - 1 ? "" : ", "); + buffer.write(row + "\n"); + + for (int r = 0; r < nrows; r++) { + row = ""; + for (int c = 0; c < ncols; c++) + row += this.getCell(r, c) + (c == ncols - 1 ? "" : ", "); + buffer.write(row + "\n"); + } + buffer.close(); + } + catch (IOException ex) { + } + } + + public String getSelectedAtColumn(int col) { + int row = getSelectedRow(); + if (row >= 0) + return (String) getModel().getValueAt(row, col); + else + return ""; + } + + public void setSelectedAtColumn(int col, String selection) { + int nrows = this.getRowCount(); + for (int i = 0; i < nrows; i++) { + String name = (String) getModel().getValueAt(i, col); + if (name.equals(selection)) + this.setRowSelectionInterval(i, i + 1); + } + } + + /** + * Add a row at the end of the table. + * + * @param row + */ + public void append(Object[] row) { + DefaultTableModel model = (DefaultTableModel) getModel(); + int i = 0; + try { + model.addRow(row); + i = getRowCount() - 1; + if (i >= 0) { + getSelectionModel().setSelectionInterval(i, i); + scrollRectToVisible(new Rectangle(getCellRect(i, 0, true))); + } + } + catch (Exception e) { + } + repaint(); + } + + /** + * Add a row at the top of the table. + * + * @param row + */ + public void insert(Object[] row) { + DefaultTableModel model = (DefaultTableModel) getModel(); + int i = 0; + try { + model.insertRow(0, row); + getSelectionModel().setSelectionInterval(i, i); + scrollRectToVisible(new Rectangle(getCellRect(i, 0, true))); + } + catch (Exception e) { + } + repaint(); + } + + @Override + public int getSelectedRow() { + int row = super.getSelectedRow(); + if (row < 0) { + if (getRowCount() > 0) { + setRowSelectionInterval(0, 0); + row = super.getSelectedRow(); + } + return row; + } + return row; + } + + /** + * Replaces all the content of the table by a content private as list of String[]. + * + * @param data + */ + public void update(ArrayList<String[]> data) { + DefaultTableModel model = (DefaultTableModel) getModel(); + model.getDataVector().removeAllElements(); + for (String[] row : data) + model.addRow(row); + repaint(); + } + + public JScrollPane getPane(int width, int height) { + setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + setPreferredScrollableViewportSize(new Dimension(width, height)); + setFillsViewportHeight(true); + pane = new JScrollPane(this); + return pane; + } + + public JScrollPane getMinimumPane(int width, int height) { + setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + setMinimumSize(new Dimension(width, height)); + setShowVerticalLines(true); + setPreferredScrollableViewportSize(new Dimension(width, height)); + setFillsViewportHeight(true); + return new JScrollPane(this); + } + + public JFrame show(String title, int w, int h) { + JFrame frame = new JFrame(title); + frame.add(getPane(w, h)); + frame.pack(); + frame.setVisible(true); + return frame; + } + + public class ButtonRenderer extends JButton implements TableCellRenderer { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + setText((String) value); + setMargin(new Insets(1, 1, 1, 1)); + return this; + } + } + +} diff --git a/src/bilib/src/bilib/commons/utils/Chrono.java b/src/bilib/src/bilib/commons/utils/Chrono.java new file mode 100644 index 0000000000000000000000000000000000000000..516d09320d1d9b46d2fe006020e177bac258b806 --- /dev/null +++ b/src/bilib/src/bilib/commons/utils/Chrono.java @@ -0,0 +1,91 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.utils; + +import java.text.DecimalFormat; + +/** + * This class provides static methods to measures the elapsed time. It is a + * equivalent to the function tic and toc of Matlab. + * + * @author Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland. + * + */ +public class Chrono { + + static private double chrono = 0; + + /** + * Register the current time. + */ + public static void tic() { + chrono = System.nanoTime(); + } + + /** + * Returns a string that indicates the elapsed time since the last tic() + * call. + */ + public static String toc() { + return toc(""); + } + + /** + * Returns a string that indicates the elapsed time since the last tic() + * call. + * + * @param msg + * message to print + */ + public static String toc(String msg) { + double te = System.nanoTime() - chrono; + String s = msg + " "; + DecimalFormat df = new DecimalFormat("####.##"); + if (te < 1000.0) + return s + df.format(te) + " ns"; + te /= 1000; + if (te < 1000.0) + return s + df.format(te) + " us"; + te /= 1000; + if (te < 3000.0) + return s + df.format(te) + " ms"; + te /= 1000; + if (te < 600.1) + return s + df.format(te) + " s"; + te /= 60; + if (te < 600.1) + return s + df.format(te) + " min."; + te /= 60; + return s + df.format(te) + " h."; + } + +} diff --git a/src/bilib/src/bilib/commons/utils/Files.java b/src/bilib/src/bilib/commons/utils/Files.java new file mode 100644 index 0000000000000000000000000000000000000000..786228c2ed7dd51704de2a73ea555c96e5786d92 --- /dev/null +++ b/src/bilib/src/bilib/commons/utils/Files.java @@ -0,0 +1,84 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.utils; + +import java.io.File; + +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileSystemView; + +public class Files { + + public static String getWorkingDirectory() { + return System.getProperty("user.dir"); + } + + public static String getHomeDirectory() { + return FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator; + } + + public static String getDesktopDirectory() { + return getHomeDirectory() + "Desktop" + File.separator; + } + + public static File browseFile(String path) { + JFileChooser fc = new JFileChooser(); + fc.setFileSelectionMode(JFileChooser.FILES_ONLY); + File dir = new File(path); + if (dir.exists()) + fc.setCurrentDirectory(dir); + + int ret = fc.showOpenDialog(null); + if (ret == JFileChooser.APPROVE_OPTION) { + File file = new File(fc.getSelectedFile().getAbsolutePath()); + if (file.exists()) + return file; + } + return null; + } + + public static File browseDirectory(String path) { + JFileChooser fc = new JFileChooser(); + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + File dir = new File(path); + if (dir.exists()) + fc.setCurrentDirectory(dir); + + int ret = fc.showOpenDialog(null); + if (ret == JFileChooser.APPROVE_OPTION) { + File file = new File(fc.getSelectedFile().getAbsolutePath()); + if (file.exists()) + return file; + } + return null; + } +} diff --git a/src/bilib/src/bilib/commons/utils/Log.java b/src/bilib/src/bilib/commons/utils/Log.java new file mode 100644 index 0000000000000000000000000000000000000000..379049f16cc6e3d8c5fd9bb55afbc3c3709cddb5 --- /dev/null +++ b/src/bilib/src/bilib/commons/utils/Log.java @@ -0,0 +1,59 @@ +package bilib.commons.utils; + +public class Log { + + static public void dash() { + System.out.println("------------------------------------------"); + } + + static public void print() { + System.out.println(""); + } + + static public void print(String a) { + System.out.println(">" + a); + } + + static public void print(double a) { + System.out.println(">" + a); + } + + static public void print(float a) { + System.out.println(">" + a); + } + + static public void print(long a) { + System.out.println(">" + a); + } + + static public void print(int a) { + System.out.println(">" + a); + } + + static public void print(short a) { + System.out.println(">" + a); + } + + static public void print(byte a) { + System.out.println(">" + a); + } + + static public void print(double a[]) { + if (a == null) { + System.out.println("> null double 1D array"); + return; + } + + if (a.length < 10) { + for (int i = 0; i < a.length; i++) + System.out.println("> [" + i + "] = " + a[i]); + return; + } + for (int i = 0; i < 4; i++) + System.out.println("> [" + i + "] = " + a[i]); + System.out.println("> ......"); + for (int i = a.length - 4; i < a.length; i++) + System.out.println("> [" + i + "] = " + a[i]); + } + +} diff --git a/src/bilib/src/bilib/commons/utils/NumFormat.java b/src/bilib/src/bilib/commons/utils/NumFormat.java new file mode 100644 index 0000000000000000000000000000000000000000..1773cb2dcb7109169b7dfd54911c2eabfbb1fdbb --- /dev/null +++ b/src/bilib/src/bilib/commons/utils/NumFormat.java @@ -0,0 +1,157 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.utils; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class NumFormat { + + public static double parseNumber(String line, double def) { + double[] numbers = parseNumbers(line); + if (numbers.length >= 1) + return numbers[0]; + else + return def; + } + + public static double[] parseNumbersAfter(String keyword, String line) { + String parts[] = line.trim().toLowerCase().split(keyword.toLowerCase()); + if (parts.length == 2) + return parseNumbers(parts[1]); + else + return new double[0]; + } + + public static double[] parseNumbers(String line) { + ArrayList<String> num = new ArrayList<String>(); + Pattern p = Pattern.compile("[-+]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?"); + Matcher m = p.matcher(line); + while (m.find()) { + num.add(m.group()); + } + double number[] = new double[num.size()]; + for (int i = 0; i < num.size(); i++) + number[i] = Double.parseDouble(num.get(i)); + return number; + } + + public static String sci(double a) { + double b = Math.abs(a); + String n = a < 0 ? "-" : ""; + if (a == 0) + return "0.0"; + if (b > 3000.0) + return String.format(n + "%6.3E", b); + if (b > 300.0) + return String.format(n + "%4.1f", b); + if (b > 30.0) + return String.format(n + "%3.2f", b); + if (b > 3.0) + return String.format(n + "%2.4f", b); + if (b > 0.003) + return String.format(n + "%1.4f", b); + + return String.format(n + "%6.3E", b).trim(); + } + + public static String unit(int n, String unit) { + double dn = n; + if (dn < 0.000000001) + return new DecimalFormat("0.00 p").format(dn*1000000000.) + unit; + if (dn < 0.000001) + return new DecimalFormat("0.00 n").format(dn*1000000.) + unit; + if (dn < 0.001) + return new DecimalFormat("0.00 m").format(dn*1000.) + unit; + if (dn < 1) + return new DecimalFormat("0.00 ").format(dn) + unit; + if (dn < 1000.) + return new DecimalFormat("0.00 K").format(dn*0.001) + unit; + if (dn < 1000000.) + return new DecimalFormat("0.00 M").format(dn*0.000001) + unit; + if (dn < 1000000000.) + return new DecimalFormat("0.00 G").format(dn*0.000000001) + unit; + return new DecimalFormat("0.00 T").format(dn*0.000000000001) + unit; + } + + public static String seconds(double ns) { + return String.format("%5.1f s", ns * 1e-9); + } + + public static String time(double ns) { + if (ns < 3000.0) + return String.format("%3.2f ns", ns); + ns *= 0.001; + if (ns < 3000.0) + return String.format("%3.2f us", ns); + ns *= 0.001; + if (ns < 3000.0) + return String.format("%3.2f ms", ns); + ns *= 0.001; + if (ns < 3600.0 * 3) + return String.format("%3.2f s", ns); + ns /= 3600; + return String.format("%3.2f h", ns); + } + + public static String bytes(double bytes) { + if (bytes < 3000) + return String.format("%3.0f", bytes); + bytes /= 1024.0; + if (bytes < 3000) + return String.format("%3.1f Kb", bytes); + bytes /= 1024.0; + if (bytes < 3000) + return String.format("%3.1f Mb", bytes); + bytes /= 1024.0; + if (bytes < 3000) + return String.format("%3.1f Gb", bytes); + bytes /= 1024.0; + return String.format("%3.1f Tb", bytes); + } + + public static String toPercent(String value) { + try { + return toPercent(Double.parseDouble(value)); + } + catch (Exception ex) { + } + return value; + } + + public static String toPercent(double value) { + return String.format("%5.3f", value * 100) + "%"; + } + +} diff --git a/src/bilib/src/bilib/commons/utils/WebBrowser.java b/src/bilib/src/bilib/commons/utils/WebBrowser.java new file mode 100644 index 0000000000000000000000000000000000000000..70fef852acd54d8a7c12dea7b23de96b752782b3 --- /dev/null +++ b/src/bilib/src/bilib/commons/utils/WebBrowser.java @@ -0,0 +1,74 @@ +/* + * bilib --- Java Bioimaging Library --- + * + * Author: Daniel Sage, Biomedical Imaging Group, EPFL, Lausanne, Switzerland + * + * Conditions of use: You are free to use this software for research or + * educational purposes. In addition, we expect you to include adequate + * citations and acknowledgments whenever you present or publish results that + * are based on it. + * + * Reference: D. Sage, M. Unser, "Teaching Image-Processing Programming in Java" + * IEEE Signal Processing Magazine, vol. 20, pp. 43-52, November 2003. + * http://bigwww.epfl.ch/publications/sage0303.html + */ + +/* + * Copyright 2007-2017 Biomedical Imaging Group at the EPFL. + * + * bilib is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * bilib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * bilib. If not, see <http://www.gnu.org/licenses/>. + */ + +package bilib.commons.utils; + +import java.awt.Desktop; +import java.net.URL; + +import javax.swing.JFrame; +import javax.swing.JLabel; + +public class WebBrowser { + + public static boolean open(String url) { + Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; + if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) { + try { + desktop.browse(new URL(url).toURI()); + return true; + } + catch (Exception e) { + e.printStackTrace(); + } + } + return false; + } + + public static boolean openInFrame(String url) { + Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; + if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) { + try { + desktop.browse(new URL(url).toURI()); + return true; + } + catch (Exception e) { + e.printStackTrace(); + } + } + JFrame frame = new JFrame("Help"); + JLabel lbl = new JLabel(url); + frame.add(lbl); + frame.pack(); + frame.setVisible(true); + return false; + } +} diff --git a/src/bilib/src/bilib/fft/AcademicFourierTransform.java b/src/bilib/src/bilib/fft/AcademicFourierTransform.java new file mode 100644 index 0000000000000000000000000000000000000000..e37a53e274d853e464b8260a5f644367e247732c --- /dev/null +++ b/src/bilib/src/bilib/fft/AcademicFourierTransform.java @@ -0,0 +1,21796 @@ +package bilib.fft; + +/*==================================================================== +| Version: May 31, 2014 +\===================================================================*/ + +/*==================================================================== +| Philippe Thevenaz +| EPFL/STI/IMT-LS/LIB/BM.4.137 +| Station 17 +| CH-1015 Lausanne VD +| Switzerland +| +| phone (CET): +41(21)693.51.61 +| fax: +41(21)693.37.01 +| RFC-822: philippe.thevenaz@epfl.ch +| X-400: /C=ch/A=400net/P=switch/O=epfl/S=thevenaz/G=philippe/ +| URL: http://bigwww.epfl.ch/ +\===================================================================*/ + +// import ij.IJ; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.TreeMap; +import java.util.Vector; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static java.lang.Math.PI; +import static java.lang.Math.atan2; +import static java.lang.Math.cos; +import static java.lang.Math.floor; +import static java.lang.Math.sin; +import static java.lang.Math.sqrt; + +/********************************************************************* + <p> + The purpose of this class is to encapsulate operations related to the + discrete Fourier transform of periodic sequences, images, and + volumes. If <i>x</i> is a discrete sequence assumed to be periodic + over <i>K</i> samples, then its discrete Fourier transform is <i>X</i> + while the inverse discrete Fourier transform of <i>X</i> is <i>x</i>. + The transforms are defined as the pair + </p> + <ul> + <li>∀<i>n</i> ∈ [0…<i>K</i> − 1]: + <i>X</i>[<i>n</i>] = ℱ{<i>x</i>}[<i>n</i>] + = ∑<sub><i>k</i> ∈ [0…<i>K</i> − 1]</sub> + <i>x</i>[<i>k</i>] + e<sup>−j <i>n</i> (2 π ∕ <i>K</i>) <i>k</i></sup></li> + <li>∀<i>k</i> ∈ [0…<i>K</i> − 1]: + <i>x</i>[<i>k</i>] = ℱ<sup>−1</sup>{<i>X</i>}[<i>k</i>] + = (1 ∕ <i>K</i>) + ∑<sub><i>n</i> ∈ [0…<i>K</i> − 1]</sub> + <i>X</i>[<i>n</i>] + e<sup>j <i>n</i> (2 π ∕ <i>K</i>) <i>k</i></sup></li> + </ul> + <p> + A few relevant relations are + </p> + <ul> + <li>j<sup>2</sup> = −1</li> + <li>∀<i>k</i>, <i>n</i> ∈ [0…<i>K</i> − 1], + <i>m</i> ∈ ℤ: + <i>x</i>[<i>k</i>] = <i>x</i>[<i>k</i> + <i>m</i> <i>K</i>], + <i>X</i>[<i>n</i>] = <i>X</i>[<i>n</i> + <i>m</i> <i>K</i>]</li> + <li>∀<i>λ</i> ∈ ℂ: ℱ{<i>λ</i> <i>x</i> + <i>y</i>} + = <i>λ</i> <i>X</i> + <i>Y</i></li> + <li>ℱ{<i>X</i>}[0] = <i>x</i>[0]; + <i>m</i> ∈ [1…<i>K</i> − 1]: + ℱ{<i>X</i>}[<i>m</i>] = <i>x</i>[<i>K</i> − <i>m</i>]</li> + <li><i>k</i><sub>0</sub> ∈ [1…<i>K</i> − 1]: + ((<i>k</i> ∈ [0…<i>k</i><sub>0</sub> − 1]: + <i>y</i>[<i>k</i>] = <i>x</i>[<i>K</i> + <i>k</i> + − <i>k</i><sub>0</sub>]), + (<i>k</i> ∈ [<i>k</i><sub>0</sub>…<i>K</i> − 1]: + <i>y</i>[<i>k</i>] = <i>x</i>[<i>k</i> − <i>k</i><sub>0</sub>])); + <i>Y</i>[<i>n</i>] = e<sup>−j <i>k</i><sub>0</sub> + (2 π ∕ <i>K</i>) <i>n</i></sup> <i>X</i>[<i>n</i>]</li> + <li><i>n</i> ∈ [0…<i>K</i> − 1]: + (<i>k</i><sub>0</sub> ∈ [0…<i>K</i> − 2]: + (<i>x</i> ∗ <i>y</i>)[<i>k</i><sub>0</sub>] + = ∑<sub><i>k</i> ∈ [0…<i>k</i><sub>0</sub>]</sub> + <i>x</i>[<i>k</i>] <i>y</i>[<i>k</i><sub>0</sub> − <i>k</i>] + + ∑<sub><i>k</i> ∈ [<i>k</i><sub>0</sub> + 1…<i>K</i> − 1]</sub> + <i>x</i>[<i>k</i>] <i>y</i>[<i>K</i> + <i>k</i><sub>0</sub> − <i>k</i>]), + ((<i>x</i> ∗ <i>y</i>)[<i>K</i> − 1] + = ∑<sub><i>k</i> ∈ [0…<i>K</i> − 1]</sub> + <i>x</i>[<i>k</i>] <i>y</i>[<i>K</i> − 1 − <i>k</i>]); + ℱ{<i>x</i> ∗ <i>y</i>}[<i>n</i>] + = <i>X</i>[<i>n</i>] <i>Y</i>[<i>n</i>]</li> + <li>〈<i>x</i>, <i>y</i>〉 + = ∑<sub><i>k</i> ∈ [0…<i>K</i> − 1]</sub> + <i>x</i>[<i>k</i>] (<i>y</i>[<i>k</i>])<sup>*</sup> + = (1 ∕ <i>K</i>) 〈<i>X</i>, <i>Y</i>〉 + = (1 ∕ <i>K</i>) ∑<sub><i>n</i> ∈ [0…<i>K</i> − 1]</sub> + <i>X</i>[<i>n</i>] (<i>Y</i>[<i>n</i>])<sup>*</sup></li> + <li><i>x</i>[0] = 1, <i>k</i> ∈ [1…<i>K</i> − 1]: + <i>x</i>[<i>k</i>] = 0; <i>n</i> ∈ [0…<i>K</i> − 1]: + <i>X</i>[<i>n</i>] = 1</li> + <li><i>k</i> ∈ [0…<i>K</i> − 1]: + <i>x</i>[<i>k</i>] = 1; <i>X</i>[0] = <i>K</i>, + <i>n</i> ∈ [1…<i>K</i> − 1]: <i>X</i>[<i>n</i>] = 0</li> + <li><i>x</i> = ℜ(<i>x</i>); ℑ(<i>X</i>[0]) = 0, + (2 ∣ <i>K</i>: ℑ(<i>X</i>[<i>K</i> ∕ 2]) = 0), + <i>n</i> ∈ [1…<i>K</i> − 1]: <i>X</i>[<i>n</i>] + = (<i>X</i>[<i>K</i> − <i>n</i>])<sup>*</sup></li> + <li><i>x</i> = ℜ(<i>x</i>); <i>y</i> = ℜ(<i>y</i>); + F = ℱ{<i>x</i> + j <i>y</i>}; <i>X</i>[0] = ℜ(<i>F</i>[0]); + <i>Y</i>[0] = ℑ(<i>F</i>[0]); + <i>n</i> ∈ [1…<i>K</i> − 1]: <i>X</i>[<i>n</i>] + = (<i>F</i>[<i>n</i>] + (<i>F</i>[<i>K</i> − <i>n</i>])<sup>*</sup>) + ∕ 2, <i>Y</i>[<i>n</i>] = −j (<i>F</i>[<i>n</i>] + − (<i>F</i>[<i>K</i> − <i>n</i>])<sup>*</sup>) ∕ 2</li> + </ul> + <p> + In two dimensions + </p> + <ul> + <li>ℱ{<i>x</i>}[<i>n</i><sub>1</sub>, <i>n</i><sub>2</sub>] + = ℱ<sub><i>k</i><sub>2</sub></sub>{ℱ<sub><i>k</i><sub>1</sub></sub>{<i>x</i>[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>]}[<i>n</i><sub>1</sub>, <i>k</i><sub>2</sub>]}[<i>n</i><sub>1</sub>, + <i>n</i><sub>2</sub>] + = ℱ<sub><i>k</i><sub>1</sub></sub>{ℱ<sub><i>k</i><sub>2</sub></sub>{<i>x</i>[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>]}[<i>k</i><sub>1</sub>, + <i>n</i><sub>2</sub>]}[<i>n</i><sub>1</sub>, <i>n</i><sub>2</sub>]</li> + </ul> + <p> + In three dimensions + </p> + <ul> + <li>ℱ{<i>x</i>}[<i>n</i><sub>1</sub>, <i>n</i><sub>2</sub>, <i>n</i><sub>3</sub>] + = ℱ<sub><i>k</i><sub>3</sub></sub>{ℱ<sub><i>k</i><sub>2</sub></sub>{ℱ<sub><i>k</i><sub>1</sub></sub>{<i>x</i>[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>n</i><sub>3</sub>] + = ℱ<sub><i>k</i><sub>3</sub></sub>{ℱ<sub><i>k</i><sub>1</sub></sub>{ℱ<sub><i>k</i><sub>2</sub></sub>{<i>x</i>[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>k</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>n</i><sub>3</sub>] + = ℱ<sub><i>k</i><sub>2</sub></sub>{ℱ<sub><i>k</i><sub>3</sub></sub>{ℱ<sub><i>k</i><sub>1</sub></sub>{<i>x</i>[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>n</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>n</i><sub>3</sub>] + = ℱ<sub><i>k</i><sub>2</sub></sub>{ℱ<sub><i>k</i><sub>1</sub></sub>{ℱ<sub><i>k</i><sub>3</sub></sub>{<i>x</i>[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>n</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>n</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>n</i><sub>3</sub>] + = ℱ<sub><i>k</i><sub>1</sub></sub>{ℱ<sub><i>k</i><sub>3</sub></sub>{ℱ<sub><i>k</i><sub>2</sub></sub>{<i>x</i>[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>k</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>k</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>n</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>n</i><sub>3</sub>] + = ℱ<sub><i>k</i><sub>1</sub></sub>{ℱ<sub><i>k</i><sub>2</sub></sub>{ℱ<sub><i>k</i><sub>3</sub></sub>{<i>x</i>[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>k</i><sub>3</sub>]}[<i>k</i><sub>1</sub>, + <i>k</i><sub>2</sub>, <i>n</i><sub>3</sub>]}[<i>k</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>n</i><sub>3</sub>]}[<i>n</i><sub>1</sub>, + <i>n</i><sub>2</sub>, <i>n</i><sub>3</sub>]</li> + </ul> + <p> + Data are provided as the pair (real part, imaginary part). The real + part is assumed to be provided as an array that contains raster data, + with the convention that the indexing for the horizontal dimension is + faster than the indexing for the vertical dimension, itself faster + than the indexing for the depth dimension. The imaginary part follows + the same organization. + </p> + <p> + The two buffers that are provided to some methods must have the same + length as the data. They are used internally as temporary storage for + the computations. They are there as a convenience to avoid repeated + allocations. + </p> + ********************************************************************/ +public class AcademicFourierTransform + +{ /* begin class SlowFourierTransform */ + +/*.................................................................... + SlowFourierTransform public enum constants +....................................................................*/ +/********************************************************************* + <p> + This enumeration provides the constants that describe the type of + input (complex or real) of a Fourier transform. + </p> + @see #makeHermitian(double[],double[],double[],double[]) + @see #makeHermitian(float[],float[],float[],float[]) + ********************************************************************/ +public enum InputDataType { +/********************************************************************* + <p> + The input of the Fourier transform is complex, made of a real and an + imaginary part. The two parts must be of equal length; moreover, this + length must match the length inferred at creation time of this + object. + </p> + ********************************************************************/ + COMPLEXINPUT, +/********************************************************************* + <p> + The input of the Fourier transform is real, although the storage for + the imaginary part must still be provided to receive the output of + the Fourier transform. The two parts must be of equal length; + moreover, this length must match the length inferred at creation time + of this object. + </p> + ********************************************************************/ + REALINPUT +} + +/*.................................................................... + SlowFourierTransform protected variables +....................................................................*/ +protected double[] imBufferDouble; +protected double[] imDataDouble; +protected double[] reBufferDouble; +protected double[] reDataDouble; +protected float[] imBufferFloat; +protected float[] imDataFloat; +protected float[] reBufferFloat; +protected float[] reDataFloat; + +/*.................................................................... + SlowFourierTransform private variables +....................................................................*/ +private Integer depth; +private Integer height; +private Integer width; +private int dataLength; +private int dimensions; +private int firstDimension; +private int fourierOrigin1; +private int fourierOrigin2; +private int fourierOrigin3; + +/*.................................................................... + SlowFourierTransform private enum constants +....................................................................*/ +private enum Algorithm { + BRUTEFORCE, + COPRIMEFACTOR, + DUOREAL, + EVENREAL, + LENGTH1, + LENGTH2, + LENGTH3, + LENGTH4, + LENGTH5, + LENGTH6, + LENGTH8, + MIXEDRADIX, + PADDEDRADER, + RADER, + RADIX2, + SPLITRADIX +} + +private final boolean PARALLELPROCESSING = true; + +/*.................................................................... + SlowFourierTransform inner classes +....................................................................*/ +/*==================================================================== +| DFTDouble +\===================================================================*/ +static class DFTDouble + +{ /* begin class DFTDouble */ + +/*.................................................................... + DFTDouble variables +....................................................................*/ +protected double[] imData; +protected double[] reData; +protected int startIndex; +protected int stride; + +/*.................................................................... + DFTDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTDouble ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + this.reData = reData; + this.imData = imData; + this.startIndex = startIndex; + this.stride = stride; +} /* end DFTDouble */ + +} /* end class DFTDouble */ + +/*==================================================================== +| DFTFloat +\===================================================================*/ +static class DFTFloat + +{ /* begin class DFTFloat */ + +/*.................................................................... + DFTFloat variables +....................................................................*/ +protected float[] imData; +protected float[] reData; +protected int startIndex; +protected int stride; + +/*.................................................................... + DFTFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTFloat ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + this.reData = reData; + this.imData = imData; + this.startIndex = startIndex; + this.stride = stride; +} /* end DFTFloat */ + +} /* end class DFTFloat */ + +/*==================================================================== +| DFTBruteForce +\===================================================================*/ +static class DFTBruteForce + +{ /* begin class DFTBruteForce */ + +/*.................................................................... + DFTBruteForce static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (FFTSetup.taboos.contains(new Integer(transformLength))) { + return(-1L); + } + final long K = (long)transformLength; + return(FFTSetup.FLALLOC * 2L + + FFTSetup.FLOP * (K * 2L + (K - 1L) * (K - 1L) * 8L) + + FFTSetup.FLASSIGN * (2L + K * 2L + 2L + (K- 1L) * (2L + + (K - 1L) * 2L + 2L) + K * 2L) + + FFTSetup.INTALLOC * 9L + + FFTSetup.INTOP * (K * 3L + 1L + (K - 1L) * (3L + (K - 1L) * 7L + 1L) + + K * 3L) + + FFTSetup.INTASSIGN * (5L + K * 2L + 2L + (K - 1L) * (4L + + (K - 1L) * 4L + 1L) + 2L + K * 2L) + + FFTSetup.IDX * (K * 2L + 2L + (K - 1L) * (2L + (K - 1L) * 8L + 2L) + + K * 4L) + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTBruteForce */ + +/*==================================================================== +| DFTBruteForceDouble +\===================================================================*/ +static class DFTBruteForceDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTBruteForceDouble */ + +/*.................................................................... + DFTBruteForceDouble private variables +....................................................................*/ +private double[] imBuffer; +private double[] imUnitRoot; +private double[] reBuffer; +private double[] reUnitRoot; + +/*.................................................................... + DFTBruteForceDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTBruteForceDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reUnitRoot, + final double[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTBruteForceDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = reUnitRoot.length; +//;IJ.log("DFTBruteForceDouble " + transformLength); + final int d1 = stride; + int n0 = startIndex; + double re = 0.0; + double im = 0.0; + int k1 = startIndex; + for (int n = 0; (n < transformLength); n++) { + re += reData[k1]; + im += imData[k1]; + k1 += d1; + } + reBuffer[n0] = re; + imBuffer[n0] = im; + n0 += d1; + for (int m = 1; (m < transformLength); m++) { + re = reData[startIndex]; + im = imData[startIndex]; + int m1 = m; + k1 = startIndex + d1; + for (int n = 1; (n < transformLength); n++) { + re += reData[k1] * reUnitRoot[m1] - imData[k1] * imUnitRoot[m1]; + im += reData[k1] * imUnitRoot[m1] + imData[k1] * reUnitRoot[m1]; + m1 += m; + m1 -= transformLength * (m1 / transformLength); + k1 += d1; + } + reBuffer[n0] = re; + imBuffer[n0] = im; + n0 += d1; + } + n0 = startIndex; + for (int m = 0; (m < transformLength); m++) { + reData[n0] = reBuffer[n0]; + imData[n0] = imBuffer[n0]; + n0 += d1; + } +} /* end run */ + +/*.................................................................... + DFTBruteForceDouble static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static double[] getImUnitRoot ( + final int transformLength +) { + final double[] imUnitRoot = new double[transformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < transformLength); k++) { + imUnitRoot[k] = sin((double)k * angularStep); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static double[] getReUnitRoot ( + final int transformLength +) { + final double[] reUnitRoot = new double[transformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < transformLength); k++) { + reUnitRoot[k] = cos((double)k * angularStep); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTBruteForceDouble */ + +/*==================================================================== +| DFTBruteForceFloat +\===================================================================*/ +static class DFTBruteForceFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTBruteForceFloat */ + +/*.................................................................... + DFTBruteForceFloat private variables +....................................................................*/ +private float[] imBuffer; +private float[] imUnitRoot; +private float[] reBuffer; +private float[] reUnitRoot; + +/*.................................................................... + DFTBruteForceFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTBruteForceFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reUnitRoot, + final float[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTBruteForceFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = reUnitRoot.length; +//;IJ.log("DFTBruteForceFloat " + transformLength); + final int d1 = stride; + int n0 = startIndex; + float re = 0.0F; + float im = 0.0F; + int k1 = startIndex; + for (int n = 0; (n < transformLength); n++) { + re += reData[k1]; + im += imData[k1]; + k1 += d1; + } + reBuffer[n0] = re; + imBuffer[n0] = im; + n0 += d1; + for (int m = 1; (m < transformLength); m++) { + re = reData[startIndex]; + im = imData[startIndex]; + int m1 = m; + k1 = startIndex + d1; + for (int n = 1; (n < transformLength); n++) { + re += reData[k1] * reUnitRoot[m1] - imData[k1] * imUnitRoot[m1]; + im += reData[k1] * imUnitRoot[m1] + imData[k1] * reUnitRoot[m1]; + m1 += m; + m1 -= transformLength * (m1 / transformLength); + k1 += d1; + } + reBuffer[n0] = re; + imBuffer[n0] = im; + n0 += d1; + } + n0 = startIndex; + for (int m = 0; (m < transformLength); m++) { + reData[n0] = reBuffer[n0]; + imData[n0] = imBuffer[n0]; + n0 += d1; + } +} /* end run */ + +/*.................................................................... + DFTBruteForceFloat static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static float[] getImUnitRoot ( + final int transformLength +) { + final float[] imUnitRoot = new float[transformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < transformLength); k++) { + imUnitRoot[k] = (float)sin((double)((float)k * angularStep)); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static float[] getReUnitRoot ( + final int transformLength +) { + final float[] reUnitRoot = new float[transformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < transformLength); k++) { + reUnitRoot[k] = (float)cos((double)((float)k * angularStep)); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTBruteForceFloat */ + +/*==================================================================== +| DFTBruteForceReal +\===================================================================*/ +static class DFTBruteForceReal + +{ /* begin class DFTBruteForceReal */ + +/*.................................................................... + DFTBruteForceReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (FFTSetup.taboos.contains(new Integer(transformLength))) { + return(-1L); + } + final long K = (long)transformLength; + final long k = (long)(transformLength >> 1); + return(FFTSetup.FLALLOC * 2L + + FFTSetup.FLOP * (K * 1L + k * (K * 4L)) + + FFTSetup.FLASSIGN * (2L + K * 1L + 1L + k * (2L + K * 2L + 2L) + + k * 2L + 2L) + + FFTSetup.INTALLOC * 11L + + FFTSetup.INTOP * (4L + K * 3L + k * (2L + K * 7L + 1L) + 1L + k * 3L) + + FFTSetup.INTASSIGN * (6L + K * 2L + 1L + k * (4L + K * 4L + 1L) + 2L + + k * 2L) + + FFTSetup.IDX * (K * 1L + 1L + k * (K * 4L + 2L) + k * 4L + 3L) + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTBruteForceReal */ + +/*==================================================================== +| DFTBruteForceRealDouble +\===================================================================*/ +static class DFTBruteForceRealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTBruteForceRealDouble */ + +/*.................................................................... + DFTBruteForceRealDouble private variables +....................................................................*/ +private double[] imBuffer; +private double[] imUnitRoot; +private double[] reBuffer; +private double[] reUnitRoot; + +/*.................................................................... + DFTBruteForceRealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTBruteForceRealDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reUnitRoot, + final double[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTBruteForceRealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + double re = 0.0; + double im = 0.0; + final int transformLength = reUnitRoot.length; +//;IJ.log("DFTBruteForceRealDouble " + transformLength); + final int halfTransformLength = transformLength >> 1; + final int d1 = stride; + int k1 = startIndex; + int n0 = startIndex + d1; + if (0 == (transformLength & 1)) { + for (int n = 0; (n < halfTransformLength); n++) { + re += reData[k1]; + im += reData[k1]; + k1 += d1; + re += reData[k1]; + im -= reData[k1]; + k1 += d1; + } + reBuffer[startIndex] = re; + int n1 = startIndex + halfTransformLength * d1; + reBuffer[n1] = im; + for (int m = 1; (m < halfTransformLength); m++) { + re = 0.0; + im = 0.0; + int m1 = 0; + k1 = startIndex; + for (int n = 0; (n < transformLength); n++) { + re += reData[k1] * reUnitRoot[m1]; + im += reData[k1] * imUnitRoot[m1]; + m1 += m; + m1 -= transformLength * (m1 / transformLength); + k1 += d1; + } + reBuffer[n0] = re; + imBuffer[n0] = im; + n0 += d1; + } + reData[n0] = reBuffer[n0]; + imData[n0] = 0.0; + n0 -= d1; + for (int m = 1; (m < halfTransformLength); m++) { + reData[n0] = reBuffer[n0]; + imData[n0] = imBuffer[n0]; + n0 -= d1; + } + reData[n0] = reBuffer[n0]; + imData[n0] = 0.0; + } + else { + for (int n = 0; (n < transformLength); n++) { + re += reData[k1]; + k1 += d1; + } + reBuffer[startIndex] = re; + for (int m = 1; (m <= halfTransformLength); m++) { + re = 0.0; + im = 0.0; + int m1 = 0; + k1 = startIndex; + for (int n = 0; (n < transformLength); n++) { + re += reData[k1] * reUnitRoot[m1]; + im += reData[k1] * imUnitRoot[m1]; + m1 += m; + m1 -= transformLength * (m1 / transformLength); + k1 += d1; + } + reBuffer[n0] = re; + imBuffer[n0] = im; + n0 += d1; + } + int n1 = n0 - d1; + for (int m = 1; (m <= halfTransformLength); m++) { + reData[n1] = reBuffer[n1]; + imData[n1] = imBuffer[n1]; + n1 -= d1; + } + reData[n1] = reBuffer[n1]; + imData[n1] = 0.0; + } +} /* end run */ + +} /* end class DFTBruteForceRealDouble */ + +/*==================================================================== +| DFTBruteForceRealFloat +\===================================================================*/ +static class DFTBruteForceRealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTBruteForceRealFloat */ + +/*.................................................................... + DFTBruteForceRealFloat private variables +....................................................................*/ +private float[] imBuffer; +private float[] imUnitRoot; +private float[] reBuffer; +private float[] reUnitRoot; + +/*.................................................................... + DFTBruteForceRealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTBruteForceRealFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reUnitRoot, + final float[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTBruteForceRealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + float re = 0.0F; + float im = 0.0F; + final int transformLength = reUnitRoot.length; +//;IJ.log("DFTBruteForceRealFloat " + transformLength); + final int halfTransformLength = transformLength >> 1; + final int d1 = stride; + int k1 = startIndex; + int n0 = startIndex + d1; + if (0 == (transformLength & 1)) { + for (int n = 0; (n < halfTransformLength); n++) { + re += reData[k1]; + im += reData[k1]; + k1 += d1; + re += reData[k1]; + im -= reData[k1]; + k1 += d1; + } + reBuffer[startIndex] = re; + int n1 = startIndex + halfTransformLength * d1; + reBuffer[n1] = im; + for (int m = 1; (m < halfTransformLength); m++) { + re = 0.0F; + im = 0.0F; + int m1 = 0; + k1 = startIndex; + for (int n = 0; (n < transformLength); n++) { + re += reData[k1] * reUnitRoot[m1]; + im += reData[k1] * imUnitRoot[m1]; + m1 += m; + m1 -= transformLength * (m1 / transformLength); + k1 += d1; + } + reBuffer[n0] = re; + imBuffer[n0] = im; + n0 += d1; + } + reData[n0] = reBuffer[n0]; + imData[n0] = 0.0F; + n0 -= d1; + for (int m = 1; (m < halfTransformLength); m++) { + reData[n0] = reBuffer[n0]; + imData[n0] = imBuffer[n0]; + n0 -= d1; + } + reData[n0] = reBuffer[n0]; + imData[n0] = 0.0F; + } + else { + for (int n = 0; (n < transformLength); n++) { + re += reData[k1]; + k1 += d1; + } + reBuffer[startIndex] = re; + for (int m = 1; (m <= halfTransformLength); m++) { + re = 0.0F; + im = 0.0F; + int m1 = 0; + k1 = startIndex; + for (int n = 0; (n < transformLength); n++) { + re += reData[k1] * reUnitRoot[m1]; + im += reData[k1] * imUnitRoot[m1]; + m1 += m; + m1 -= transformLength * (m1 / transformLength); + k1 += d1; + } + reBuffer[n0] = re; + imBuffer[n0] = im; + n0 += d1; + } + int n1 = n0 - d1; + for (int m = 1; (m <= halfTransformLength); m++) { + reData[n1] = reBuffer[n1]; + imData[n1] = imBuffer[n1]; + n1 -= d1; + } + reData[n1] = reBuffer[n1]; + imData[n1] = 0.0F; + } +} /* end run */ + +} /* end class DFTBruteForceRealFloat */ + +/*==================================================================== +| DFTCoprimeFactor +\===================================================================*/ +static class DFTCoprimeFactor + +{ /* begin class DFTCoprimeFactor */ + +/*.................................................................... + DFTCoprimeFactor static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int K1, + final int K2 +) { + if (FFTSetup.taboos.contains(new Integer(K1)) + || FFTSetup.taboos.contains(new Integer(K2))) { + return(-1L); + } + final long K = (long)K1 * (long)K2; + return(FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * 0L + + FFTSetup.FLASSIGN * (K * 2L + K * 2L) + + FFTSetup.INTALLOC * 11L + + FFTSetup.INTOP * (1L + K * 5L + 2L + K2 * 3L + 1L + K1 * 3L + K * 5L) + + FFTSetup.INTASSIGN * (4L + K * 3L + 4L + K2 * 2L + 2L + K1 * 2L + 2L + + K * 3L) + + FFTSetup.IDX * (K * 5L + K * 5L) + + FFTSetup.NEWOBJ * (K2 * 1L + K1 * 1L) + + (long)K2 * FFTSetup.cost(K1) + (long)K1 * FFTSetup.cost(K2) + ); +} /* end cost */ + +/*------------------------------------------------------------------*/ +static int[] getChineseRemainderShuffling ( + final int K1, + final int K2 +) { + final int K1K2 = K1 * K2; + int[] chineseRemainderShuffling = new int[K1K2]; + final int p1 = modularMultiplicativeInverse(K1, K2); + final int p2 = modularMultiplicativeInverse(K2, K1); + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + int q = p * p1; + for (int k1 = 0; (k1 < K1); k1++) { + chineseRemainderShuffling[q - K1K2 * (q / K1K2)] = p++; + q += p2 * K2; + } + } + return(chineseRemainderShuffling); +} /* end getChineseRemainderShuffling */ + +/*------------------------------------------------------------------*/ +static int[] getRuritanianShuffling ( + final int K1, + final int K2 +) { + final int K1K2 = K1 * K2; + int[] ruritanianShuffling = new int[K1K2]; + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + int q = p; + for (int k1 = 0; (k1 < K1); k1++) { + ruritanianShuffling[p++] = q - K1K2 * (q / K1K2); + q += K2; + } + } + return(ruritanianShuffling); +} /* end getRuritanianShuffling */ + +/*.................................................................... + DFTCoprimeFactor private methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static private int[] extendedGreatestCommonDivisor ( + int m, + int n +) { + if ((m < 1) || (n < 1)) { + return(null); + } + int a = 1; + int b = 0; + int p = 0; + int q = 1; + while (0 != n) { + final int i = m; + final int j = a; + final int k = b; + m = n; + a = p; + b = q; + final int f = i / n; + n = i - f * n; + p = j - f * p; + q = k - f * q; + } + return(new int[] { // a * m + b * n = gcd(m, n) + m, // gcd + a, + b + }); +} /* end extendedGreatestCommonDivisor */ + +/*------------------------------------------------------------------*/ +static private int modularMultiplicativeInverse ( + int n, + final int modulo +) { + if ((n < 1) || (modulo < 1)) { + return(0); + } + n = extendedGreatestCommonDivisor(n, modulo)[1]; + return((n < 0) ? (n + modulo) : (n)); +} /* end modularMultiplicativeInverse */ + +} /* end class DFTCoprimeFactor */ + +/*==================================================================== +| DFTCoprimeFactorDouble +\===================================================================*/ +static class DFTCoprimeFactorDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTCoprimeFactorDouble */ + +/*.................................................................... + DFTCoprimeFactorDouble private variables +....................................................................*/ +private double[] imBuffer; +private double[] reBuffer; +private int[] ruritanian; +private int[] chinese; +private int K1; + +/*.................................................................... + DFTCoprimeFactorDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTCoprimeFactorDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final int[] ruritanian, + final int[] chinese, + final int K1 +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.ruritanian = ruritanian; + this.chinese = chinese; + this.K1 = K1; +} /* end DFTCoprimeFactorDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = ruritanian.length; +//;IJ.log("DFTCoprimeFactorDouble " + transformLength + " / " + K1); + final int K2 = transformLength / K1; + int p = startIndex; + for (int k = 0; (k < transformLength); k++) { + final int q = startIndex + ruritanian[k] * stride; + reBuffer[p] = reData[q]; + imBuffer[p] = imData[q]; + p += stride; + } + final int d1 = stride; + final int d2 = K1 * d1; + p = startIndex; + final FFTSetup fft1 = FFTSetup.transforms.get(new Integer(K1)); + switch (fft1.algorithm) { + case BRUTEFORCE: { + for (int n = 0; (n < K2); n++) { + new DFTBruteForceDouble(reBuffer, imBuffer, reData, imData, + p, d1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + p += d2; + } + break; + } + case COPRIMEFACTOR: { + for (int n = 0; (n < K2); n++) { + new DFTCoprimeFactorDouble(reBuffer, imBuffer, reData, imData, + p, d1, + fft1.ruritanian, fft1.chinese, fft1.K1).run(); + p += d2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int n = 0; (n < K2); n++) { + new DFTLength2Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH3: { + for (int n = 0; (n < K2); n++) { + new DFTLength3Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH4: { + for (int n = 0; (n < K2); n++) { + new DFTLength4Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH5: { + for (int n = 0; (n < K2); n++) { + new DFTLength5Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH6: { + for (int n = 0; (n < K2); n++) { + new DFTLength6Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH8: { + for (int n = 0; (n < K2); n++) { + new DFTLength8Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case MIXEDRADIX: { + for (int n = 0; (n < K2); n++) { + new DFTMixedRadixDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble, + fft1.K1).run(); + p += d2; + } + break; + } + case PADDEDRADER: { + for (int n = 0; (n < K2); n++) { + new DFTPaddedRaderDouble(reBuffer, imBuffer, + p, d1, fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADER: { + for (int n = 0; (n < K2); n++) { + new DFTRaderDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADIX2: { + for (int n = 0; (n < K2); n++) { + new DFTRadix2Double(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + p += d2; + } + break; + } + case SPLITRADIX: { + for (int n = 0; (n < K2); n++) { + new DFTSplitRadixDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + p += d2; + } + break; + } + } + p = startIndex; + final FFTSetup fft2 = FFTSetup.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int n = 0; (n < K1); n++) { + new DFTBruteForceDouble(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + p += d1; + } + break; + } + case COPRIMEFACTOR: { + for (int n = 0; (n < K1); n++) { + new DFTCoprimeFactorDouble(reBuffer, imBuffer, reData, imData, + p, d2, fft2.ruritanian, fft2.chinese, fft2.K1).run(); + p += d1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int n = 0; (n < K1); n++) { + new DFTLength2Double(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH3: { + for (int n = 0; (n < K1); n++) { + new DFTLength3Double(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH4: { + for (int n = 0; (n < K1); n++) { + new DFTLength4Double(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH5: { + for (int n = 0; (n < K1); n++) { + new DFTLength5Double(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH6: { + for (int n = 0; (n < K1); n++) { + new DFTLength6Double(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH8: { + for (int n = 0; (n < K1); n++) { + new DFTLength8Double(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case MIXEDRADIX: { + for (int n = 0; (n < K1); n++) { + new DFTMixedRadixDouble(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1).run(); + p += d1; + } + break; + } + case PADDEDRADER: { + for (int n = 0; (n < K1); n++) { + new DFTPaddedRaderDouble(reBuffer, imBuffer, + p, d2, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADER: { + for (int n = 0; (n < K1); n++) { + new DFTRaderDouble(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADIX2: { + for (int n = 0; (n < K1); n++) { + new DFTRadix2Double(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + p += d1; + } + break; + } + case SPLITRADIX: { + for (int n = 0; (n < K1); n++) { + new DFTSplitRadixDouble(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + p += d1; + } + break; + } + } + p = startIndex; + for (int k = 0; (k < transformLength); k++) { + final int q = startIndex + chinese[k] * stride; + reData[p] = reBuffer[q]; + imData[p] = imBuffer[q]; + p += stride; + } +} /* end run */ + +} /* end class DFTCoprimeFactorDouble */ + +/*==================================================================== +| DFTCoprimeFactorFloat +\===================================================================*/ +static class DFTCoprimeFactorFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTCoprimeFactorFloat */ + +/*.................................................................... + DFTCoprimeFactorFloat private variables +....................................................................*/ +private float[] imBuffer; +private float[] reBuffer; +private int[] ruritanian; +private int[] chinese; +private int K1; + +/*.................................................................... + DFTCoprimeFactorFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTCoprimeFactorFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final int[] ruritanian, + final int[] chinese, + final int K1 +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.ruritanian = ruritanian; + this.chinese = chinese; + this.K1 = K1; +} /* end DFTCoprimeFactorFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = ruritanian.length; +//;IJ.log("DFTCoprimeFactorFloat " + transformLength + " / " + K1); + final int K2 = transformLength / K1; + int p = startIndex; + for (int k = 0; (k < transformLength); k++) { + final int q = startIndex + ruritanian[k] * stride; + reBuffer[p] = reData[q]; + imBuffer[p] = imData[q]; + p += stride; + } + final int d1 = stride; + final int d2 = K1 * d1; + p = startIndex; + final FFTSetup fft1 = FFTSetup.transforms.get(new Integer(K1)); + switch (fft1.algorithm) { + case BRUTEFORCE: { + for (int n = 0; (n < K2); n++) { + new DFTBruteForceFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + p += d2; + } + break; + } + case COPRIMEFACTOR: { + for (int n = 0; (n < K2); n++) { + new DFTCoprimeFactorFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.ruritanian, fft1.chinese, fft1.K1).run(); + p += d2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int n = 0; (n < K2); n++) { + new DFTLength2Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH3: { + for (int n = 0; (n < K2); n++) { + new DFTLength3Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH4: { + for (int n = 0; (n < K2); n++) { + new DFTLength4Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH5: { + for (int n = 0; (n < K2); n++) { + new DFTLength5Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH6: { + for (int n = 0; (n < K2); n++) { + new DFTLength6Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH8: { + for (int n = 0; (n < K2); n++) { + new DFTLength8Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case MIXEDRADIX: { + for (int n = 0; (n < K2); n++) { + new DFTMixedRadixFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat, + fft1.K1).run(); + p += d2; + } + break; + } + case PADDEDRADER: { + for (int n = 0; (n < K2); n++) { + new DFTPaddedRaderFloat(reBuffer, imBuffer, + p, d1, fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADER: { + for (int n = 0; (n < K2); n++) { + new DFTRaderFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADIX2: { + for (int n = 0; (n < K2); n++) { + new DFTRadix2Float(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + p += d2; + } + break; + } + case SPLITRADIX: { + for (int n = 0; (n < K2); n++) { + new DFTSplitRadixFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + p += d2; + } + break; + } + } + p = startIndex; + final FFTSetup fft2 = FFTSetup.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int n = 0; (n < K1); n++) { + new DFTBruteForceFloat(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + p += d1; + } + break; + } + case COPRIMEFACTOR: { + for (int n = 0; (n < K1); n++) { + new DFTCoprimeFactorFloat(reBuffer, imBuffer, reData, imData, + p, d2, fft2.ruritanian, fft2.chinese, fft2.K1).run(); + p += d1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int n = 0; (n < K1); n++) { + new DFTLength2Float(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH3: { + for (int n = 0; (n < K1); n++) { + new DFTLength3Float(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH4: { + for (int n = 0; (n < K1); n++) { + new DFTLength4Float(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH5: { + for (int n = 0; (n < K1); n++) { + new DFTLength5Float(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH6: { + for (int n = 0; (n < K1); n++) { + new DFTLength6Float(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH8: { + for (int n = 0; (n < K1); n++) { + new DFTLength8Float(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case MIXEDRADIX: { + for (int n = 0; (n < K1); n++) { + new DFTMixedRadixFloat(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1).run(); + p += d1; + } + break; + } + case PADDEDRADER: { + for (int n = 0; (n < K1); n++) { + new DFTPaddedRaderFloat(reBuffer, imBuffer, + p, d2, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADER: { + for (int n = 0; (n < K1); n++) { + new DFTRaderFloat(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADIX2: { + for (int n = 0; (n < K1); n++) { + new DFTRadix2Float(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + p += d1; + } + break; + } + case SPLITRADIX: { + for (int n = 0; (n < K1); n++) { + new DFTSplitRadixFloat(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + p += d1; + } + break; + } + } + p = startIndex; + for (int k = 0; (k < transformLength); k++) { + final int q = startIndex + chinese[k] * stride; + reData[p] = reBuffer[q]; + imData[p] = imBuffer[q]; + p += stride; + } +} /* end run */ + +} /* end class DFTCoprimeFactorFloat */ + +/*==================================================================== +| DFTCoprimeFactorReal +\===================================================================*/ +static class DFTCoprimeFactorReal + +{ /* begin class DFTCoprimeFactorReal */ + +/*.................................................................... + DFTCoprimeFactorReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int K1, + final int K2 +) { + if (FFTSetup.taboos.contains(new Integer(K1)) + || FFTSetup.taboos.contains(new Integer(K2))) { + return(-1L); + } + final long K = (long)K1 * (long)K2; + final long k = K >> 1L; + final long k1 = (long)(K1 >> 1); + final long k2 = (long)(K2 >> 1); + return(FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * ((K >> 2L) * 1L) + + FFTSetup.FLASSIGN * (K * 2L + (k + 1L) * 2L) + + FFTSetup.INTALLOC * 12L + + FFTSetup.INTOP * (3L + K * 5L + 4L + (long)K1 * 3L + 1L + + (k2 + 1L) * 3L + 2L + (k + 1L) * 6L) + + FFTSetup.INTASSIGN * (5L + K * 3L + 4L + (long)K1 * 2L + 2L + + (k2 + 1L) * 2L + 3L + (k + 1L) * 4L) + + FFTSetup.IDX * (K * 5L + (k + 1L) * 5L) + + FFTSetup.NEWOBJ * ((long)K1 * 1L + (long)K2 * 1L) + + k1 * FFTSetupDuoReal.cost(K2) + (k2 + 1L) * FFTSetup.cost(K1) + ); +} /* end cost */ + +/*------------------------------------------------------------------*/ +static int[] getTruncatedChineseRemainderShuffling ( + final int K1, + final int K2 +) { + final int K1K2 = K1 * K2; + final int halfK1K2 = (K1K2 >> 1) + 1; + final int halfK2 = (K2 >> 1) + 1; + int[] chineseRemainderShuffling = new int[halfK1K2]; + final int p1 = DFTCoprimeFactor.modularMultiplicativeInverse(K1, K2); + final int p2 = DFTCoprimeFactor.modularMultiplicativeInverse(K2, K1); + int n = 0; + for (int k2 = 0; (k2 < K2); k2++) { + int q = n * p1; + for (int k1 = 0; (k1 < K1); k1++) { + final int p = q - K1K2 * (q / K1K2); + if (p < halfK1K2) { + final int i0 = n / K1; + final int j0 = n - K1 * i0; + chineseRemainderShuffling[p] = (i0 < halfK2) ? (n) + : ((0 == j0) ? (n - K1K2) : (n - K1K2 - K1)); + } + q += p2 * K2; + n++; + } + } + return(chineseRemainderShuffling); +} /* end getTruncatedChineseRemainderShuffling */ + +} /* end class DFTCoprimeFactorReal */ + +/*==================================================================== +| DFTCoprimeFactorRealDouble +\===================================================================*/ +static class DFTCoprimeFactorRealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTCoprimeFactorRealDouble */ + +/*.................................................................... + DFTCoprimeFactorRealDouble private variables +....................................................................*/ +private double[] imBuffer; +private double[] reBuffer; +private int[] ruritanian; +private int[] chinese; +private int K1; + +/*.................................................................... + DFTCoprimeFactorRealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTCoprimeFactorRealDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final int[] ruritanian, + final int[] chinese, + final int K1 +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.ruritanian = ruritanian; + this.chinese = chinese; + this.K1 = K1; +} /* end DFTCoprimeFactorRealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = ruritanian.length; +//;IJ.log("DFTCoprimeFactorRealDouble " + transformLength + " / " + K1); + final int K2 = transformLength / K1; + final int halfK2 = (K2 >> 1) + 1; + int p = startIndex; + for (int k = 0; (k < transformLength); k++) { + final int q = startIndex + ruritanian[k] * stride; + reBuffer[p] = reData[q]; + imBuffer[p] = imData[q]; + p += stride; + } + final int d1 = stride; + final int d2 = K1 * d1; + p = startIndex; + int k1 = 0; + if (1 == (K1 & 1)) { + final FFTSetupReal fft2 = FFTSetupReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2RealDouble(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reBuffer, imBuffer, p, d2).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reBuffer, imBuffer, + p, d2, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootEvenDouble, fft2.imUnitRootEvenDouble, + fft2.reUnitRootOddDouble, fft2.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + } + p += d1; + k1++; + } + final FFTSetupDuoReal fft2 = + FFTSetupDuoReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + while (k1++ < K1) { + new DFTBruteForceRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + p += d1; + } + break; + } + case COPRIMEFACTOR: { + while (k1++ < K1) { + new DFTCoprimeFactorRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + p += d1; + } + break; + } + case DUOREAL: { + while (k1++ < K1) { + new DFTDuoRealDouble(reBuffer, imBuffer, + reData, imData, p, p + d1, d2, K2).run(); + p += 2 * d1; + k1++; + } + break; + } + case EVENREAL: { + while (k1++ < K1) { + new DFTEvenRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + p += d1; + } + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + while (k1++ < K1) { + new DFTLength2RealDouble(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH3: { + while (k1++ < K1) { + new DFTLength3RealDouble(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH4: { + while (k1++ < K1) { + new DFTLength4RealDouble(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH5: { + while (k1++ < K1) { + new DFTLength5RealDouble(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH6: { + while (k1++ < K1) { + new DFTLength6RealDouble(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH8: { + while (k1++ < K1) { + new DFTLength8RealDouble(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case MIXEDRADIX: { + while (k1++ < K1) { + new DFTMixedRadixRealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1).run(); + p += d1; + } + break; + } + case PADDEDRADER: { + while (k1++ < K1) { + new DFTPaddedRaderRealDouble(reBuffer, imBuffer, + p, d2, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADER: { + while (k1++ < K1) { + new DFTRaderRealDouble(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADIX2: { + while (k1++ < K1) { + new DFTRadix2RealDouble(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootEvenDouble, fft2.imUnitRootEvenDouble, + fft2.reUnitRootOddDouble, fft2.imUnitRootOddDouble).run(); + p += d1; + } + break; + } + case SPLITRADIX: { + while (k1++ < K1) { + new DFTSplitRadixRealDouble(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + p += d1; + } + break; + } + } + p = startIndex; + final FFTSetup fft1 = FFTSetup.transforms.get(new Integer(K1)); + switch (fft1.algorithm) { + case BRUTEFORCE: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTBruteForceDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + p += d2; + } + break; + } + case COPRIMEFACTOR: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTCoprimeFactorDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.ruritanian, fft1.chinese, fft1.K1).run(); + p += d2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength2Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH3: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength3Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH4: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength4Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH5: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength5Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH6: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength6Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH8: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength8Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case MIXEDRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTMixedRadixDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble, + fft1.K1).run(); + p += d2; + } + break; + } + case PADDEDRADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTPaddedRaderDouble(reBuffer, imBuffer, + p, d1, fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTRaderDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADIX2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTRadix2Double(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + p += d2; + } + break; + } + case SPLITRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTSplitRadixDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + p += d2; + } + break; + } + } + p = startIndex; + for (int k = 0, K = (transformLength >> 1) + 1; (k < K); k++) { + int q = chinese[k]; + if (q < 0) { + q = startIndex - q * stride; + reData[p] = reBuffer[q]; + imData[p] = -imBuffer[q]; + } + else { + q = startIndex + q * stride; + reData[p] = reBuffer[q]; + imData[p] = imBuffer[q]; + } + p += stride; + } +} /* end run */ + +} /* end class DFTCoprimeFactorRealDouble */ + +/*==================================================================== +| DFTCoprimeFactorRealFloat +\===================================================================*/ +static class DFTCoprimeFactorRealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTCoprimeFactorRealFloat */ + +/*.................................................................... + DFTCoprimeFactorRealFloat private variables +....................................................................*/ +private float[] imBuffer; +private float[] reBuffer; +private int[] ruritanian; +private int[] chinese; +private int K1; + +/*.................................................................... + DFTCoprimeFactorRealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTCoprimeFactorRealFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final int[] ruritanian, + final int[] chinese, + final int K1 +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.ruritanian = ruritanian; + this.chinese = chinese; + this.K1 = K1; +} /* end DFTCoprimeFactorRealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = ruritanian.length; +//;IJ.log("DFTCoprimeFactorRealFloat " + transformLength + " / " + K1); + final int K2 = transformLength / K1; + final int halfK2 = (K2 >> 1) + 1; + int p = startIndex; + for (int k = 0; (k < transformLength); k++) { + final int q = startIndex + ruritanian[k] * stride; + reBuffer[p] = reData[q]; + imBuffer[p] = imData[q]; + p += stride; + } + final int d1 = stride; + final int d2 = K1 * d1; + p = startIndex; + int k1 = 0; + if (1 == (K1 & 1)) { + final FFTSetupReal fft2 = FFTSetupReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2RealFloat(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reBuffer, imBuffer, p, d2).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reBuffer, imBuffer, p, d2).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reBuffer, imBuffer, + p, d2, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootEvenFloat, fft2.imUnitRootEvenFloat, + fft2.reUnitRootOddFloat, fft2.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + } + p += d1; + k1++; + } + final FFTSetupDuoReal fft2 = + FFTSetupDuoReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + while (k1++ < K1) { + new DFTBruteForceRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + p += d1; + } + break; + } + case COPRIMEFACTOR: { + while (k1++ < K1) { + new DFTCoprimeFactorRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + p += d1; + } + break; + } + case DUOREAL: { + while (k1++ < K1) { + new DFTDuoRealFloat(reBuffer, imBuffer, + reData, imData, p, p + d1, d2, K2).run(); + p += 2 * d1; + k1++; + } + break; + } + case EVENREAL: { + while (k1++ < K1) { + new DFTEvenRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + p += d1; + } + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + while (k1++ < K1) { + new DFTLength2RealFloat(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH3: { + while (k1++ < K1) { + new DFTLength3RealFloat(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH4: { + while (k1++ < K1) { + new DFTLength4RealFloat(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH5: { + while (k1++ < K1) { + new DFTLength5RealFloat(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH6: { + while (k1++ < K1) { + new DFTLength6RealFloat(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case LENGTH8: { + while (k1++ < K1) { + new DFTLength8RealFloat(reBuffer, imBuffer, p, d2).run(); + p += d1; + } + break; + } + case MIXEDRADIX: { + while (k1++ < K1) { + new DFTMixedRadixRealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1).run(); + p += d1; + } + break; + } + case PADDEDRADER: { + while (k1++ < K1) { + new DFTPaddedRaderRealFloat(reBuffer, imBuffer, + p, d2, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADER: { + while (k1++ < K1) { + new DFTRaderRealFloat(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADIX2: { + while (k1++ < K1) { + new DFTRadix2RealFloat(reBuffer, imBuffer, + reData, imData, p, d2, + fft2.reUnitRootEvenFloat, fft2.imUnitRootEvenFloat, + fft2.reUnitRootOddFloat, fft2.imUnitRootOddFloat).run(); + p += d1; + } + break; + } + case SPLITRADIX: { + while (k1++ < K1) { + new DFTSplitRadixRealFloat(reBuffer, imBuffer, reData, imData, + p, d2, fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + p += d1; + } + break; + } + } + p = startIndex; + final FFTSetup fft1 = FFTSetup.transforms.get(new Integer(K1)); + switch (fft1.algorithm) { + case BRUTEFORCE: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTBruteForceFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + p += d2; + } + break; + } + case COPRIMEFACTOR: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTCoprimeFactorFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.ruritanian, fft1.chinese, fft1.K1).run(); + p += d2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength2Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH3: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength3Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH4: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength4Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH5: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength5Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH6: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength6Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH8: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength8Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case MIXEDRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTMixedRadixFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat, + fft1.K1).run(); + p += d2; + } + break; + } + case PADDEDRADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTPaddedRaderFloat(reBuffer, imBuffer, + p, d1, fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTRaderFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADIX2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTRadix2Float(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + p += d2; + } + break; + } + case SPLITRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTSplitRadixFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + p += d2; + } + break; + } + } + p = startIndex; + for (int k = 0, K = (transformLength >> 1) + 1; (k < K); k++) { + int q = chinese[k]; + if (q < 0) { + q = startIndex - q * stride; + reData[p] = reBuffer[q]; + imData[p] = -imBuffer[q]; + } + else { + q = startIndex + q * stride; + reData[p] = reBuffer[q]; + imData[p] = imBuffer[q]; + } + p += stride; + } +} /* end run */ + +} /* end class DFTCoprimeFactorRealFloat */ + +/*==================================================================== +| DFTDuoReal +\===================================================================*/ +static class DFTDuoReal + +{ /* begin class DFTDuoReal */ + +/*.................................................................... + DFTDuoReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (FFTSetup.taboos.contains(new Integer(transformLength / 2))) { + return(-1L); + } + final long K = (long)transformLength; + final long k = K >> 1L; + return(FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * (k * 8L) + + FFTSetup.FLASSIGN * (K * 2L + 4L + k * 4L) + + FFTSetup.INTALLOC * 6L + + FFTSetup.INTOP * (K * 4L + 9L + k * 5L) + + FFTSetup.INTASSIGN * (3L + K * 3L + 7L + k * 4L) + + FFTSetup.IDX * (K * 4L + 6L + k * 8L) + + FFTSetup.NEWOBJ * 1L + + FFTSetup.cost(transformLength) + ); +} /* end cost */ + +} /* end class DFTDuoReal */ + +/*==================================================================== +| DFTDuoRealDouble +\===================================================================*/ +static class DFTDuoRealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTDuoRealDouble */ + +/*.................................................................... + DFTDuoRealDouble static variables +....................................................................*/ +private double[] imBuffer; +private double[] reBuffer; +private int duoStartIndex; +private int transformLength; + +/*.................................................................... + DFTDuoRealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTDuoRealDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int duoStartIndex, + final int stride, + final int transformLength +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.duoStartIndex = duoStartIndex; + this.transformLength = transformLength; +} /* end DFTDuoRealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTDuoRealDouble " + transformLength); + int i0 = startIndex; + int i1 = duoStartIndex; + for (int m = 0; (m < transformLength); m++) { + reBuffer[i0] = reData[i0]; + imBuffer[i0] = reData[i1]; + i0 += stride; + i1 += stride; + } + final FFTSetup fft = FFTSetup.transforms.get(new Integer(transformLength)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH3: { + new DFTLength3Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH4: { + new DFTLength4Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH5: { + new DFTLength5Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH6: { + new DFTLength6Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootDouble, fft.imUnitRootDouble, + fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderDouble(reBuffer, imBuffer, + startIndex, stride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Double(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + i0 = startIndex; + i1 = duoStartIndex; + reData[i0] = reBuffer[i0]; + imData[i0] = 0.0; + reData[i1] = imBuffer[i0]; + imData[i1] = 0.0; + i0 += stride; + i1 += stride; + int j0 = startIndex + (transformLength - 1) * stride; + if (0 == (transformLength & 1)) { + for (int m = 1, M = transformLength >> 1; (m < M); m++) { + reData[i0] = 0.5 * (reBuffer[i0] + reBuffer[j0]); + imData[i0] = 0.5 * (imBuffer[i0] - imBuffer[j0]); + reData[i1] = 0.5 * (imBuffer[i0] + imBuffer[j0]); + imData[i1] = -0.5 * (reBuffer[i0] - reBuffer[j0]); + i0 += stride; + i1 += stride; + j0 -= stride; + } + reData[i0] = reBuffer[i0]; + imData[i0] = 0.0; + reData[i1] = imBuffer[i0]; + imData[i1] = 0.0; + } + else { + for (int m = 1, M = transformLength >> 1; (m <= M); m++) { + reData[i0] = 0.5 * (reBuffer[i0] + reBuffer[j0]); + imData[i0] = 0.5 * (imBuffer[i0] - imBuffer[j0]); + reData[i1] = 0.5 * (imBuffer[i0] + imBuffer[j0]); + imData[i1] = -0.5 * (reBuffer[i0] - reBuffer[j0]); + i0 += stride; + i1 += stride; + j0 -= stride; + } + } +} /* end run */ + +} /* end class DFTDuoRealDouble */ + +/*==================================================================== +| DFTDuoRealFloat +\===================================================================*/ +static class DFTDuoRealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTDuoRealFloat */ + +/*.................................................................... + DFTDuoRealFloat static variables +....................................................................*/ +private float[] imBuffer; +private float[] reBuffer; +private int duoStartIndex; +private int transformLength; + +/*.................................................................... + DFTDuoRealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTDuoRealFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int duoStartIndex, + final int stride, + final int transformLength +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.duoStartIndex = duoStartIndex; + this.transformLength = transformLength; +} /* end DFTDuoRealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTDuoRealFloat " + transformLength); + int i0 = startIndex; + int i1 = duoStartIndex; + for (int m = 0; (m < transformLength); m++) { + reBuffer[i0] = reData[i0]; + imBuffer[i0] = reData[i1]; + i0 += stride; + i1 += stride; + } + final FFTSetup fft = FFTSetup.transforms.get(new Integer(transformLength)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH3: { + new DFTLength3Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH4: { + new DFTLength4Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH5: { + new DFTLength5Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH6: { + new DFTLength6Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootFloat, fft.imUnitRootFloat, + fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderFloat(reBuffer, imBuffer, + startIndex, stride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Float(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + i0 = startIndex; + i1 = duoStartIndex; + reData[i0] = reBuffer[i0]; + imData[i0] = 0.0F; + reData[i1] = imBuffer[i0]; + imData[i1] = 0.0F; + i0 += stride; + i1 += stride; + int j0 = startIndex + (transformLength - 1) * stride; + if (0 == (transformLength & 1)) { + for (int m = 1, M = transformLength >> 1; (m < M); m++) { + reData[i0] = 0.5F * (reBuffer[i0] + reBuffer[j0]); + imData[i0] = 0.5F * (imBuffer[i0] - imBuffer[j0]); + reData[i1] = 0.5F * (imBuffer[i0] + imBuffer[j0]); + imData[i1] = -0.5F * (reBuffer[i0] - reBuffer[j0]); + i0 += stride; + i1 += stride; + j0 -= stride; + } + reData[i0] = reBuffer[i0]; + imData[i0] = 0.0F; + reData[i1] = imBuffer[i0]; + imData[i1] = 0.0F; + } + else { + for (int m = 1, M = transformLength >> 1; (m <= M); m++) { + reData[i0] = 0.5F * (reBuffer[i0] + reBuffer[j0]); + imData[i0] = 0.5F * (imBuffer[i0] - imBuffer[j0]); + reData[i1] = 0.5F * (imBuffer[i0] + imBuffer[j0]); + imData[i1] = -0.5F * (reBuffer[i0] - reBuffer[j0]); + i0 += stride; + i1 += stride; + j0 -= stride; + } + } +} /* end run */ + +} /* end class DFTDuoRealFloat */ + +/*==================================================================== +| DFTEvenReal +\===================================================================*/ +static class DFTEvenReal + +{ /* begin class DFTEvenReal */ + +/*.................................................................... + DFTEvenReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (FFTSetup.taboos.contains(new Integer(transformLength / 2))) { + return(-1L); + } + final long k = (long)(transformLength >> 1); + return(FFTSetup.FLALLOC * 4L + + FFTSetup.FLOP * (1L + (k - 1L) * 14L + 1L) + + FFTSetup.FLASSIGN * (k * 2L + 2L + (k - 1L) * 6L + 2L) + + FFTSetup.INTALLOC * 7L + + FFTSetup.INTOP * (1L + k * 5L + 5L + (k - 1L) * 4L) + + FFTSetup.INTASSIGN * (6L + k * 4L + 4L + (k - 1L) * 3L) + + FFTSetup.IDX * (k * 4L + 4L + (k - 1L) * 12L + 4L) + + FFTSetup.NEWOBJ * 1L + + FFTSetup.cost(transformLength >> 1) + ); +} /* end cost */ + +} /* end class DFTEvenReal */ + +/*==================================================================== +| DFTEvenRealDouble +\===================================================================*/ +static class DFTEvenRealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTEvenRealDouble */ + +/*.................................................................... + DFTEvenRealDouble static variables +....................................................................*/ +private double[] imBuffer; +private double[] imUnitRoot; +private double[] reBuffer; +private double[] reUnitRoot; + +/*.................................................................... + DFTEvenRealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTEvenRealDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reUnitRoot, + final double[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTEvenRealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int halfTransformLength = reUnitRoot.length; +//;IJ.log("DFTEvenRealDouble " + (2 * halfTransformLength)); + final int doubleStride = stride << 1; + int m0 = startIndex; + int i0 = startIndex; + int i1 = startIndex + stride; + for (int m = 0; (m < halfTransformLength); m++) { + reBuffer[m0] = reData[i0]; + imBuffer[m0] = reData[i1]; + m0 += stride; + i0 += doubleStride; + i1 += doubleStride; + } + final FFTSetup fft = + FFTSetup.transforms.get(new Integer(halfTransformLength)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH3: { + new DFTLength3Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH4: { + new DFTLength4Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH5: { + new DFTLength5Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH6: { + new DFTLength6Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Double(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootDouble, fft.imUnitRootDouble, + fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderDouble(reBuffer, imBuffer, + startIndex, stride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Double(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixDouble(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + i0 = startIndex; + reData[i0] = reBuffer[i0] + imBuffer[i0]; + imData[i0] = 0.0; + i0 += stride; + i1 = startIndex + (halfTransformLength - 1) * stride; + for (int m = 1; (m < halfTransformLength); m++) { + final double re = reBuffer[i0] - reBuffer[i1]; + final double im = imBuffer[i0] + imBuffer[i1]; + final double reRoot = reUnitRoot[m]; + final double imRoot = imUnitRoot[m]; + reData[i0] = 0.5 * (reBuffer[i0] + reBuffer[i1] + + re * imRoot + im * reRoot); + imData[i0] = 0.5 * (imBuffer[i0] - imBuffer[i1] + - re * reRoot + im * imRoot); + i0 += stride; + i1 -= stride; + } + reData[i0] = reBuffer[startIndex] - imBuffer[startIndex]; + imData[i0] = 0.0; +} /* end run */ + +/*.................................................................... + DFTEvenRealDouble static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static double[] getImUnitRoot ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final double[] imUnitRoot = new double[halfTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + imUnitRoot[k] = sin((double)k * angularStep); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static double[] getReUnitRoot ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final double[] reUnitRoot = new double[halfTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + reUnitRoot[k] = cos((double)k * angularStep); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTEvenRealDouble */ + +/*==================================================================== +| DFTEvenRealFloat +\===================================================================*/ +static class DFTEvenRealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTEvenRealFloat */ + +/*.................................................................... + DFTEvenRealFloat static variables +....................................................................*/ +private float[] imBuffer; +private float[] imUnitRoot; +private float[] reBuffer; +private float[] reUnitRoot; + +/*.................................................................... + DFTEvenRealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTEvenRealFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reUnitRoot, + final float[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTEvenRealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int halfTransformLength = reUnitRoot.length; +//;IJ.log("DFTEvenRealFloat " + (2 * halfTransformLength)); + final int doubleStride = stride << 1; + int m0 = startIndex; + int i0 = startIndex; + int i1 = startIndex + stride; + for (int m = 0; (m < halfTransformLength); m++) { + reBuffer[m0] = reData[i0]; + imBuffer[m0] = reData[i1]; + m0 += stride; + i0 += doubleStride; + i1 += doubleStride; + } + final FFTSetup fft = + FFTSetup.transforms.get(new Integer(halfTransformLength)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH3: { + new DFTLength3Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH4: { + new DFTLength4Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH5: { + new DFTLength5Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH6: { + new DFTLength6Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Float(reBuffer, imBuffer, + startIndex, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootFloat, fft.imUnitRootFloat, + fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderFloat(reBuffer, imBuffer, + startIndex, stride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Float(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixFloat(reBuffer, imBuffer, reData, imData, + startIndex, stride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + i0 = startIndex; + reData[i0] = reBuffer[i0] + imBuffer[i0]; + imData[i0] = 0.0F; + i0 += stride; + i1 = startIndex + (halfTransformLength - 1) * stride; + for (int m = 1; (m < halfTransformLength); m++) { + final float re = reBuffer[i0] - reBuffer[i1]; + final float im = imBuffer[i0] + imBuffer[i1]; + final float reRoot = reUnitRoot[m]; + final float imRoot = imUnitRoot[m]; + reData[i0] = 0.5F * (reBuffer[i0] + reBuffer[i1] + + re * imRoot + im * reRoot); + imData[i0] = 0.5F * (imBuffer[i0] - imBuffer[i1] + - re * reRoot + im * imRoot); + i0 += stride; + i1 -= stride; + } + reData[i0] = reBuffer[startIndex] - imBuffer[startIndex]; + imData[i0] = 0.0F; +} /* end run */ + +/*.................................................................... + DFTEvenRealFloat static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static float[] getImUnitRoot ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final float[] imUnitRoot = new float[halfTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + imUnitRoot[k] = (float)sin((double)((float)k * angularStep)); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static float[] getReUnitRoot ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final float[] reUnitRoot = new float[halfTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + reUnitRoot[k] = (float)cos((double)((float)k * angularStep)); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTEvenRealFloat */ + +/*==================================================================== +| DFTLength2 +\===================================================================*/ +static class DFTLength2 + +{ /* begin class DFTLength2 */ + +/*.................................................................... + DFTLength2 static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 3L + + FFTSetup.FLOP * 4L + + FFTSetup.FLASSIGN * 8L + + FFTSetup.INTALLOC * 1L + + FFTSetup.INTOP * 1L + + FFTSetup.INTASSIGN * 1L + + FFTSetup.IDX * 8L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength2 */ + +/*==================================================================== +| DFTLength2Double +\===================================================================*/ +static class DFTLength2Double + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength2Double */ + +/*.................................................................... + DFTLength2Double constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength2Double ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength2Double */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength2Double"); + final int i1 = startIndex + stride; + final double re1 = reData[i1]; + final double im1 = imData[i1]; + double butterfly = reData[startIndex] - re1; + reData[startIndex] += re1; + reData[i1] = butterfly; + butterfly = imData[startIndex] - im1; + imData[startIndex] += im1; + imData[i1] = butterfly; +} /* end run */ + +} /* end class DFTLength2Double */ + +/*==================================================================== +| DFTLength2Float +\===================================================================*/ +static class DFTLength2Float + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength2Float */ + +/*.................................................................... + DFTLength2Float constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength2Float ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength2Float */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength2Float"); + final int i1 = startIndex + stride; + final float re1 = reData[i1]; + final float im1 = imData[i1]; + float butterfly = reData[startIndex] - re1; + reData[startIndex] += re1; + reData[i1] = butterfly; + butterfly = imData[startIndex] - im1; + imData[startIndex] += im1; + imData[i1] = butterfly; +} /* end run */ + +} /* end class DFTLength2Float */ + +/*==================================================================== +| DFTLength2Real +\===================================================================*/ +static class DFTLength2Real + +{ /* begin class DFTLength2Real */ + +/*.................................................................... + DFTLength2Real static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 2L + + FFTSetup.FLOP * 2L + + FFTSetup.FLASSIGN * 6L + + FFTSetup.INTALLOC * 1L + + FFTSetup.INTOP * 1L + + FFTSetup.INTASSIGN * 1L + + FFTSetup.IDX * 6L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength2Real */ + +/*==================================================================== +| DFTLength2RealDouble +\===================================================================*/ +static class DFTLength2RealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength2RealDouble */ + +/*.................................................................... + DFTLength2RealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength2RealDouble ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength2RealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength2RealDouble"); + final int i1 = startIndex + stride; + final double re1 = reData[i1]; + double butterfly = reData[startIndex] - re1; + reData[startIndex] += re1; + reData[i1] = butterfly; + imData[startIndex] = 0.0; + imData[i1] = 0.0; +} /* end run */ + +} /* end class DFTLength2RealDouble */ + +/*==================================================================== +| DFTLength2RealFloat +\===================================================================*/ +static class DFTLength2RealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength2RealFloat */ + +/*.................................................................... + DFTLength2RealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength2RealFloat ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength2RealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength2RealFloat"); + final int i1 = startIndex + stride; + final float re1 = reData[i1]; + float butterfly = reData[startIndex] - re1; + reData[startIndex] += re1; + reData[i1] = butterfly; + imData[startIndex] = 0.0F; + imData[i1] = 0.0F; +} /* end run */ + +} /* end class DFTLength2RealFloat */ + +/*==================================================================== +| DFTLength3 +\===================================================================*/ +static class DFTLength3 + +{ /* begin class DFTLength3 */ + +/*.................................................................... + DFTLength3 static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 6L + + FFTSetup.FLOP * 20L + + FFTSetup.FLASSIGN * 16L + + FFTSetup.INTALLOC * 2L + + FFTSetup.INTOP * 2L + + FFTSetup.INTASSIGN * 2L + + FFTSetup.IDX * 12L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength3 */ + +/*==================================================================== +| DFTLength3Double +\===================================================================*/ +static class DFTLength3Double + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength3Double */ + +/*.................................................................... + DFTLength3Double static variables +....................................................................*/ +private static final double SQRT3 = sqrt(3.0); + +/*.................................................................... + DFTLength3Double constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength3Double ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength3Double */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength3Double"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + double reButterfly = reData[i1]; + final double imButterfly = imData[i1]; + double reDragonfly = reData[i2]; + final double imDragonfly = imData[i2]; + final double reLadybug = SQRT3 * (imDragonfly - imButterfly); + final double imLadybug = SQRT3 * (reButterfly - reDragonfly); + reButterfly += reDragonfly; + reDragonfly = reData[startIndex]; + reData[i1] = reDragonfly - 0.5 * (reLadybug + reButterfly); + reData[i2] = reDragonfly + 0.5 * (reLadybug - reButterfly); + reData[startIndex] += reButterfly; + reDragonfly = imData[startIndex]; + reButterfly = imButterfly + imDragonfly; + imData[i1] = reDragonfly - 0.5 * (imLadybug + reButterfly); + imData[i2] = reDragonfly + 0.5 * (imLadybug - reButterfly); + imData[startIndex] += reButterfly; +} /* end run */ + +} /* end class DFTLength3Double */ + +/*==================================================================== +| DFTLength3Float +\===================================================================*/ +static class DFTLength3Float + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength3Float */ + +/*.................................................................... + DFTLength3Float static variables +....................................................................*/ +private static final float SQRT3 = (float)sqrt(3.0); + +/*.................................................................... + DFTLength3Float constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength3Float ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength3Float */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength3Float"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + float reButterfly = reData[i1]; + final float imButterfly = imData[i1]; + float reDragonfly = reData[i2]; + final float imDragonfly = imData[i2]; + final float reLadybug = SQRT3 * (imDragonfly - imButterfly); + final float imLadybug = SQRT3 * (reButterfly - reDragonfly); + reButterfly += reDragonfly; + reDragonfly = reData[startIndex]; + reData[i1] = reDragonfly - 0.5F * (reLadybug + reButterfly); + reData[i2] = reDragonfly + 0.5F * (reLadybug - reButterfly); + reData[startIndex] += reButterfly; + reDragonfly = imData[startIndex]; + reButterfly = imButterfly + imDragonfly; + imData[i1] = reDragonfly - 0.5F * (imLadybug + reButterfly); + imData[i2] = reDragonfly + 0.5F * (imLadybug - reButterfly); + imData[startIndex] += reButterfly; +} /* end run */ + +} /* end class DFTLength3Float */ + +/*==================================================================== +| DFTLength3Real +\===================================================================*/ +static class DFTLength3Real + +{ /* begin class DFTLength3Real */ + +/*.................................................................... + DFTLength3Real static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 2L + + FFTSetup.FLOP * 6L + + FFTSetup.FLASSIGN * 6L + + FFTSetup.INTALLOC * 2L + + FFTSetup.INTOP * 2L + + FFTSetup.INTASSIGN * 2L + + FFTSetup.IDX * 9L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength3Real */ + +/*==================================================================== +| DFTLength3RealDouble +\===================================================================*/ +static class DFTLength3RealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength3RealDouble */ + +/*.................................................................... + DFTLength3RealDouble static variables +....................................................................*/ +private static final double HALFSQRT3 = 0.5 * sqrt(3.0); + +/*.................................................................... + DFTLength3RealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength3RealDouble ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength3RealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength3RealDouble"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final double reButterfly = reData[i2] + reData[i1]; + final double imButterfly = HALFSQRT3 * (reData[i2] - reData[i1]); + reData[i1] = reData[startIndex] - 0.5 * reButterfly; + reData[startIndex] += reButterfly; + imData[startIndex] = 0.0; + imData[i1] = imButterfly; +} /* end run */ + +} /* end class DFTLength3RealDouble */ + +/*==================================================================== +| DFTLength3RealFloat +\===================================================================*/ +static class DFTLength3RealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength3RealFloat */ + +/*.................................................................... + DFTLength3RealFloat static variables +....................................................................*/ +private static final float HALFSQRT3 = 0.5F * (float)sqrt(3.0); + +/*.................................................................... + DFTLength3RealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength3RealFloat ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength3RealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength3RealFloat"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final float reButterfly = reData[i2] + reData[i1]; + final float imButterfly = HALFSQRT3 * (reData[i2] - reData[i1]); + reData[i1] = reData[startIndex] - 0.5F * reButterfly; + reData[startIndex] += reButterfly; + imData[startIndex] = 0.0F; + imData[i1] = imButterfly; +} /* end run */ + +} /* end class DFTLength3RealFloat */ + +/*==================================================================== +| DFTLength4 +\===================================================================*/ +static class DFTLength4 + +{ /* begin class DFTLength4 */ + +/*.................................................................... + DFTLength4 static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 8L + + FFTSetup.FLOP * 16L + + FFTSetup.FLASSIGN * 24L + + FFTSetup.INTALLOC * 1L + + FFTSetup.INTOP * 11L + + FFTSetup.INTASSIGN * 10L + + FFTSetup.IDX * 16L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength4 */ + +/*==================================================================== +| DFTLength4Double +\===================================================================*/ +static class DFTLength4Double + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength4Double */ + +/*.................................................................... + DFTLength4Double constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength4Double ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength4Double */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength4Double"); + double data0 = reData[startIndex]; + int k = startIndex + stride; + double data1 = reData[k]; + k += stride; + double data2 = reData[k]; + k += stride; + double data3 = reData[k]; + double butterfly = data0 + data2; + double dragonfly = data1 + data3; + double ladybug = data0 - data2; + double moth = data1 - data3; + data3 = imData[k]; + k -= stride; + data2 = imData[k]; + k -= stride; + data1 = imData[k]; + k += stride; + data0 = imData[startIndex]; + reData[startIndex] = butterfly + dragonfly; + reData[k] = butterfly - dragonfly; + k -= stride; + butterfly = data0 - data2; + dragonfly = data1 - data3; + reData[k] = ladybug + dragonfly; + k += stride + stride; + reData[k] = ladybug - dragonfly; + dragonfly = data0 + data2; + ladybug = data1 + data3; + imData[k] = butterfly + moth; + k -= stride; + imData[k] = dragonfly - ladybug; + k -= stride; + imData[k] = butterfly - moth; + imData[startIndex] = dragonfly + ladybug; +} /* end run */ + +} /* end class DFTLength4Double */ + +/*==================================================================== +| DFTLength4Float +\===================================================================*/ +static class DFTLength4Float + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength4Float */ + +/*.................................................................... + DFTLength4Float constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength4Float ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength4Float */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength4Float"); + float data0 = reData[startIndex]; + int k = startIndex + stride; + float data1 = reData[k]; + k += stride; + float data2 = reData[k]; + k += stride; + float data3 = reData[k]; + float butterfly = data0 + data2; + float dragonfly = data1 + data3; + float ladybug = data0 - data2; + float moth = data1 - data3; + data3 = imData[k]; + k -= stride; + data2 = imData[k]; + k -= stride; + data1 = imData[k]; + k += stride; + data0 = imData[startIndex]; + reData[startIndex] = butterfly + dragonfly; + reData[k] = butterfly - dragonfly; + k -= stride; + butterfly = data0 - data2; + dragonfly = data1 - data3; + reData[k] = ladybug + dragonfly; + k += stride + stride; + reData[k] = ladybug - dragonfly; + dragonfly = data0 + data2; + ladybug = data1 + data3; + imData[k] = butterfly + moth; + k -= stride; + imData[k] = dragonfly - ladybug; + k -= stride; + imData[k] = butterfly - moth; + imData[startIndex] = dragonfly + ladybug; +} /* end run */ + +} /* end class DFTLength4Float */ + +/*==================================================================== +| DFTLength4Real +\===================================================================*/ +static class DFTLength4Real + +{ /* begin class DFTLength4Real */ + +/*.................................................................... + DFTLength4Real static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 2L + + FFTSetup.FLOP * 6L + + FFTSetup.FLASSIGN * 8L + + FFTSetup.INTALLOC * 3L + + FFTSetup.INTOP * 3L + + FFTSetup.INTASSIGN * 3L + + FFTSetup.IDX * 14L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength4Real */ + +/*==================================================================== +| DFTLength4RealDouble +\===================================================================*/ +static class DFTLength4RealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength4RealDouble */ + +/*.................................................................... + DFTLength4RealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength4RealDouble ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength4RealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength4RealDouble"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final int i3 = i2 + stride; + final double butterfly = reData[startIndex] + reData[i2]; + final double dragonfly = reData[i1] + reData[i3]; + imData[startIndex] = 0.0; + imData[i1] = reData[i3] - reData[i1]; + imData[i2] = 0.0; + reData[i1] = reData[startIndex] - reData[i2]; + reData[i2] = butterfly - dragonfly; + reData[startIndex] = butterfly + dragonfly; +} /* end run */ + +} /* end class DFTLength4RealDouble */ + +/*==================================================================== +| DFTLength4RealFloat +\===================================================================*/ +static class DFTLength4RealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength4RealFloat */ + +/*.................................................................... + DFTLength4RealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength4RealFloat ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength4RealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength4RealFloat"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final int i3 = i2 + stride; + final float butterfly = reData[startIndex] + reData[i2]; + final float dragonfly = reData[i1] + reData[i3]; + imData[startIndex] = 0.0F; + imData[i1] = reData[i3] - reData[i1]; + imData[i2] = 0.0F; + reData[i1] = reData[startIndex] - reData[i2]; + reData[i2] = butterfly - dragonfly; + reData[startIndex] = butterfly + dragonfly; +} /* end run */ + +} /* end class DFTLength4RealFloat */ + +/*==================================================================== +| DFTLength5 +\===================================================================*/ +static class DFTLength5 + +{ /* begin class DFTLength5 */ + +/*.................................................................... + DFTLength5 static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 18L + + FFTSetup.FLOP * 52L + + FFTSetup.FLASSIGN * 50L + + FFTSetup.INTALLOC * 1L + + FFTSetup.INTOP * 7L + + FFTSetup.INTASSIGN * 7L + + FFTSetup.IDX * 20L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength5 */ + +/*==================================================================== +| DFTLength5Double +\===================================================================*/ +static class DFTLength5Double + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength5Double */ + +/*.................................................................... + DFTLength5Double static variables +....................................................................*/ +private static final double IM5 = sqrt((5.0 - sqrt(5.0)) / 32.0); +private static final double RE5 = sqrt((5.0 + sqrt(5.0)) / 32.0); +private static final double S5 = sqrt(5.0 / 16.0); + +/*.................................................................... + DFTLength5Double constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength5Double ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength5Double */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength5Double"); + int k = startIndex + stride; + double re1 = reData[k]; + double im1 = imData[k]; + k += stride; + double re2 = reData[k]; + double im2 = imData[k]; + k += stride; + double re3 = reData[k]; + double im3 = imData[k]; + k += stride; + double re4 = reData[k]; + double im4 = imData[k]; + double reDragonfly = re1 + re4; + double imDragonfly = im1 + im4; + double reLadybug = re1 - re4; + double imLadybug = im1 - im4; + double reMoth = re2 + re3; + double imMoth = im2 + im3; + double reBeetle = re2 - re3; + double imBeetle = im2 - im3; + final double reButterfly = reDragonfly + reMoth; + final double imButterfly = imDragonfly + imMoth; + re1 = imLadybug + reBeetle; + im1 = reLadybug - imBeetle; + re2 = IM5 * im1 - RE5 * re1; + im2 = IM5 * re1 + RE5 * im1; + re1 = -0.25 * reButterfly; + im1 = -0.25 * imButterfly; + re3 = reBeetle - imLadybug; + im3 = imBeetle + reLadybug; + re4 = RE5 * re3 - IM5 * im3; + im4 = RE5 * im3 + IM5 * re3; + re3 = S5 * (reDragonfly - reMoth); + im3 = S5 * (imDragonfly - imMoth); + reDragonfly = reData[startIndex] + re1; + imDragonfly = imData[startIndex] + im1; + reLadybug = reDragonfly - re3; + imLadybug = imDragonfly - im3; + reDragonfly += re3; + imDragonfly += im3; + reMoth = re2 + re4; + imMoth = im2 + im4; + reBeetle = re2 - re4; + imBeetle = im2 - im4; + reData[k] = reDragonfly + reMoth; + imData[k] = imDragonfly + imMoth; + k -= stride; + reData[k] = reLadybug - imBeetle; + imData[k] = imLadybug + reBeetle; + k -= stride; + reData[k] = reLadybug + imBeetle; + imData[k] = imLadybug - reBeetle; + k -= stride; + reData[k] = reDragonfly - reMoth; + imData[k] = imDragonfly - imMoth; + reData[startIndex] += reButterfly; + imData[startIndex] += imButterfly; +} /* end run */ + +} /* end class DFTLength5Double */ + +/*==================================================================== +| DFTLength5Float +\===================================================================*/ +static class DFTLength5Float + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength5Float */ + +/*.................................................................... + DFTLength5Float static variables +....................................................................*/ +private static final float IM5 = (float)sqrt((5.0 - sqrt(5.0)) / 32.0); +private static final float RE5 = (float)sqrt((5.0 + sqrt(5.0)) / 32.0); +private static final float S5 = (float)sqrt(5.0 / 16.0); + +/*.................................................................... + DFTLength5Float constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength5Float ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength5Float */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength5Float"); + int k = startIndex + stride; + float re1 = reData[k]; + float im1 = imData[k]; + k += stride; + float re2 = reData[k]; + float im2 = imData[k]; + k += stride; + float re3 = reData[k]; + float im3 = imData[k]; + k += stride; + float re4 = reData[k]; + float im4 = imData[k]; + float reDragonfly = re1 + re4; + float imDragonfly = im1 + im4; + float reLadybug = re1 - re4; + float imLadybug = im1 - im4; + float reMoth = re2 + re3; + float imMoth = im2 + im3; + float reBeetle = re2 - re3; + float imBeetle = im2 - im3; + final float reButterfly = reDragonfly + reMoth; + final float imButterfly = imDragonfly + imMoth; + re1 = imLadybug + reBeetle; + im1 = reLadybug - imBeetle; + re2 = IM5 * im1 - RE5 * re1; + im2 = IM5 * re1 + RE5 * im1; + re1 = -0.25F * reButterfly; + im1 = -0.25F * imButterfly; + re3 = reBeetle - imLadybug; + im3 = imBeetle + reLadybug; + re4 = RE5 * re3 - IM5 * im3; + im4 = RE5 * im3 + IM5 * re3; + re3 = S5 * (reDragonfly - reMoth); + im3 = S5 * (imDragonfly - imMoth); + reDragonfly = reData[startIndex] + re1; + imDragonfly = imData[startIndex] + im1; + reLadybug = reDragonfly - re3; + imLadybug = imDragonfly - im3; + reDragonfly += re3; + imDragonfly += im3; + reMoth = re2 + re4; + imMoth = im2 + im4; + reBeetle = re2 - re4; + imBeetle = im2 - im4; + reData[k] = reDragonfly + reMoth; + imData[k] = imDragonfly + imMoth; + k -= stride; + reData[k] = reLadybug - imBeetle; + imData[k] = imLadybug + reBeetle; + k -= stride; + reData[k] = reLadybug + imBeetle; + imData[k] = imLadybug - reBeetle; + k -= stride; + reData[k] = reDragonfly - reMoth; + imData[k] = imDragonfly - imMoth; + reData[startIndex] += reButterfly; + imData[startIndex] += imButterfly; +} /* end run */ + +} /* end class DFTLength5Float */ + +/*==================================================================== +| DFTLength5Real +\===================================================================*/ +static class DFTLength5Real + +{ /* begin class DFTLength5Real */ + +/*.................................................................... + DFTLength5Real static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 4L + + FFTSetup.FLOP * 18L + + FFTSetup.FLASSIGN * 13L + + FFTSetup.INTALLOC * 4L + + FFTSetup.INTOP * 4L + + FFTSetup.INTASSIGN * 4L + + FFTSetup.IDX * 15L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength5Real */ + +/*==================================================================== +| DFTLength5RealDouble +\===================================================================*/ +static class DFTLength5RealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength5RealDouble */ + +/*.................................................................... + DFTLength5RealDouble static variables +....................................................................*/ +private static final double IM5 = -sqrt((5.0 - sqrt(5.0)) / 8.0); +private static final double RE5 = -sqrt((5.0 + sqrt(5.0)) / 8.0); +private static final double S5 = sqrt(5.0 / 16.0); + +/*.................................................................... + DFTLength5RealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength5RealDouble ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength5RealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength5RealDouble"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final int i3 = i2 + stride; + final int i4 = i3 + stride; + double butterfly = reData[i1] - reData[i4]; + double dragonfly = reData[i2] - reData[i3]; + imData[startIndex] = 0.0; + imData[i1] = RE5 * butterfly + IM5 * dragonfly; + imData[i2] = IM5 * butterfly - RE5 * dragonfly; + butterfly = reData[i1] + reData[i4]; + dragonfly = reData[i2] + reData[i3]; + final double ladybug = S5 * (butterfly - dragonfly); + final double moth = butterfly + dragonfly; + butterfly = reData[startIndex] - 0.25 * moth; + reData[startIndex] += moth; + reData[i1] = butterfly + ladybug; + reData[i2] = butterfly - ladybug; +} /* end run */ + +} /* end class DFTLength5RealDouble */ + +/*==================================================================== +| DFTLength5RealFloat +\===================================================================*/ +static class DFTLength5RealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength5RealFloat */ + +/*.................................................................... + DFTLength5RealFloat static variables +....................................................................*/ +private static final float IM5 = -(float)sqrt((5.0 - sqrt(5.0)) / 8.0); +private static final float RE5 = -(float)sqrt((5.0 + sqrt(5.0)) / 8.0); +private static final float S5 = (float)sqrt(5.0 / 16.0); + +/*.................................................................... + DFTLength5RealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength5RealFloat ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength5RealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength5RealFloat"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final int i3 = i2 + stride; + final int i4 = i3 + stride; + float butterfly = reData[i1] - reData[i4]; + float dragonfly = reData[i2] - reData[i3]; + imData[startIndex] = 0.0F; + imData[i1] = RE5 * butterfly + IM5 * dragonfly; + imData[i2] = IM5 * butterfly - RE5 * dragonfly; + butterfly = reData[i1] + reData[i4]; + dragonfly = reData[i2] + reData[i3]; + final float ladybug = S5 * (butterfly - dragonfly); + final float moth = butterfly + dragonfly; + butterfly = reData[startIndex] - 0.25F * moth; + reData[startIndex] += moth; + reData[i1] = butterfly + ladybug; + reData[i2] = butterfly - ladybug; +} /* end run */ + +} /* end class DFTLength5RealFloat */ + +/*==================================================================== +| DFTLength6 +\===================================================================*/ +static class DFTLength6 + +{ /* begin class DFTLength6 */ + +/*.................................................................... + DFTLength6 static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 24L + + FFTSetup.FLOP * 52L + + FFTSetup.FLASSIGN * 44L + + FFTSetup.INTALLOC * 1L + + FFTSetup.INTOP * 12L + + FFTSetup.INTASSIGN * 9L + + FFTSetup.IDX * 24L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength6 */ + +/*==================================================================== +| DFTLength6Double +\===================================================================*/ +static class DFTLength6Double + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength6Double */ + +/*.................................................................... + DFTLength6Double static variables +....................................................................*/ +private static final double SQRT3 = sqrt(3.0); + +/*.................................................................... + DFTLength6Double constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength6Double ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength6Double */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength6Double"); + double reLadybug = reData[startIndex]; + int k = startIndex + 3 * stride; + double reMoth = reData[k]; + final double reButterfly = reLadybug + reMoth; + final double reDragonfly = reLadybug - reMoth; + double imLadybug = imData[startIndex]; + double imMoth = imData[k]; + k -= stride << 1; + final double imButterfly = imLadybug + imMoth; + final double imDragonfly = imLadybug - imMoth; + double re1 = reData[k]; + double im1 = imData[k]; + k += stride; + double re2 = reData[k]; + double im2 = imData[k]; + k += stride << 1; + double re4 = reData[k]; + double im4 = imData[k]; + k += stride; + double re5 = reData[k]; + double im5 = imData[k]; + reLadybug = re1 + re2; + imLadybug = im1 + im2; + reMoth = re4 + re5; + imMoth = im4 + im5; + final double reAnt = reLadybug + reMoth; + final double imAnt = imLadybug + imMoth; + final double reBee = SQRT3 * (imMoth - imLadybug); + final double imBee = SQRT3 * (reLadybug - reMoth); + reLadybug = re1 - re2; + imLadybug = im1 - im2; + reMoth = re4 - re5; + imMoth = im4 - im5; + final double reGrasshopper = SQRT3 * (imMoth + imLadybug); + final double imGrasshopper = SQRT3 * (reMoth + reLadybug); + final double reBeetle = reMoth - reLadybug; + final double imBeetle = imMoth - imLadybug; + reData[k] = reDragonfly + 0.5 * (reBee - reBeetle); + imData[k] = imDragonfly + 0.5 * (imBee - imBeetle); + k -= stride; + reData[k] = reButterfly - 0.5 * (reAnt + reGrasshopper); + imData[k] = imButterfly - 0.5 * (imAnt - imGrasshopper); + k -= stride; + reData[k] = reDragonfly + reBeetle; + imData[k] = imDragonfly + imBeetle; + k -= stride; + reData[k] = reButterfly + 0.5 * (reGrasshopper - reAnt); + imData[k] = imButterfly - 0.5 * (imGrasshopper + imAnt); + k -= stride; + reData[k] = reDragonfly - 0.5 * (reBee + reBeetle); + imData[k] = imDragonfly - 0.5 * (imBee + imBeetle); + reData[startIndex] = reButterfly + reAnt; + imData[startIndex] = imButterfly + imAnt; +} /* end run */ + +} /* end class DFTLength6Double */ + +/*==================================================================== +| DFTLength6Float +\===================================================================*/ +static class DFTLength6Float + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength6Float */ + +/*.................................................................... + DFTLength6Float static variables +....................................................................*/ +private static final float SQRT3 = (float)sqrt(3.0); + +/*.................................................................... + DFTLength6Float constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength6Float ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength6Float */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength6Float"); + float reLadybug = reData[startIndex]; + int k = startIndex + 3 * stride; + float reMoth = reData[k]; + final float reButterfly = reLadybug + reMoth; + final float reDragonfly = reLadybug - reMoth; + float imLadybug = imData[startIndex]; + float imMoth = imData[k]; + k -= stride << 1; + final float imButterfly = imLadybug + imMoth; + final float imDragonfly = imLadybug - imMoth; + float re1 = reData[k]; + float im1 = imData[k]; + k += stride; + float re2 = reData[k]; + float im2 = imData[k]; + k += stride << 1; + float re4 = reData[k]; + float im4 = imData[k]; + k += stride; + float re5 = reData[k]; + float im5 = imData[k]; + reLadybug = re1 + re2; + imLadybug = im1 + im2; + reMoth = re4 + re5; + imMoth = im4 + im5; + final float reAnt = reLadybug + reMoth; + final float imAnt = imLadybug + imMoth; + final float reBee = SQRT3 * (imMoth - imLadybug); + final float imBee = SQRT3 * (reLadybug - reMoth); + reLadybug = re1 - re2; + imLadybug = im1 - im2; + reMoth = re4 - re5; + imMoth = im4 - im5; + final float reGrasshopper = SQRT3 * (imMoth + imLadybug); + final float imGrasshopper = SQRT3 * (reMoth + reLadybug); + final float reBeetle = reMoth - reLadybug; + final float imBeetle = imMoth - imLadybug; + reData[k] = reDragonfly + 0.5F * (reBee - reBeetle); + imData[k] = imDragonfly + 0.5F * (imBee - imBeetle); + k -= stride; + reData[k] = reButterfly - 0.5F * (reAnt + reGrasshopper); + imData[k] = imButterfly - 0.5F * (imAnt - imGrasshopper); + k -= stride; + reData[k] = reDragonfly + reBeetle; + imData[k] = imDragonfly + imBeetle; + k -= stride; + reData[k] = reButterfly + 0.5F * (reGrasshopper - reAnt); + imData[k] = imButterfly - 0.5F * (imGrasshopper + imAnt); + k -= stride; + reData[k] = reDragonfly - 0.5F * (reBee + reBeetle); + imData[k] = imDragonfly - 0.5F * (imBee + imBeetle); + reData[startIndex] = reButterfly + reAnt; + imData[startIndex] = imButterfly + imAnt; +} /* end run */ + +} /* end class DFTLength6Float */ + +/*==================================================================== +| DFTLength6Real +\===================================================================*/ +static class DFTLength6Real + +{ /* begin class DFTLength6Real */ + +/*.................................................................... + DFTLength6Real static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 6L + + FFTSetup.FLOP * 18L + + FFTSetup.FLASSIGN * 16L + + FFTSetup.INTALLOC * 5L + + FFTSetup.INTOP * 5L + + FFTSetup.INTASSIGN * 5L + + FFTSetup.IDX * 20L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength6Real */ + +/*==================================================================== +| DFTLength6RealDouble +\===================================================================*/ +static class DFTLength6RealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength6RealDouble */ + +/*.................................................................... + DFTLength6RealDouble static variables +....................................................................*/ +private static final double NEGHALFSQRT3 = -0.5 * sqrt(3.0); + +/*.................................................................... + DFTLength6RealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength6RealDouble ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength6RealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength6RealDouble"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final int i3 = i2 + stride; + final int i4 = i3 + stride; + final int i5 = i4 + stride; + double butterfly = reData[i1] + reData[i2]; + double dragonfly = reData[i1] - reData[i2]; + final double ladybug = reData[i4] + reData[i5]; + final double grasshopper = reData[i4] - reData[i5]; + imData[startIndex] = 0.0; + imData[i1] = NEGHALFSQRT3 * (butterfly - ladybug); + imData[i2] = NEGHALFSQRT3 * (dragonfly + grasshopper); + imData[i3] = 0.0; + final double beetle = butterfly + ladybug; + final double ant = dragonfly - grasshopper; + butterfly = reData[startIndex] + reData[i3]; + dragonfly = reData[startIndex] - reData[i3]; + reData[startIndex] = butterfly + beetle; + reData[i1] = dragonfly + 0.5 * ant; + reData[i2] = butterfly - 0.5 * beetle; + reData[i3] = dragonfly - ant; +} /* end run */ + +} /* end class DFTLength6RealDouble */ + +/*==================================================================== +| DFTLength6RealFloat +\===================================================================*/ +static class DFTLength6RealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength6RealFloat */ + +/*.................................................................... + DFTLength6RealFloat static variables +....................................................................*/ +private static final float NEGHALFSQRT3 = -0.5F * (float)sqrt(3.0); + +/*.................................................................... + DFTLength6RealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength6RealFloat ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength6RealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength6RealFloat"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final int i3 = i2 + stride; + final int i4 = i3 + stride; + final int i5 = i4 + stride; + float butterfly = reData[i1] + reData[i2]; + float dragonfly = reData[i1] - reData[i2]; + final float ladybug = reData[i4] + reData[i5]; + final float grasshopper = reData[i4] - reData[i5]; + imData[startIndex] = 0.0F; + imData[i1] = NEGHALFSQRT3 * (butterfly - ladybug); + imData[i2] = NEGHALFSQRT3 * (dragonfly + grasshopper); + imData[i3] = 0.0F; + final float beetle = butterfly + ladybug; + final float ant = dragonfly - grasshopper; + butterfly = reData[startIndex] + reData[i3]; + dragonfly = reData[startIndex] - reData[i3]; + reData[startIndex] = butterfly + beetle; + reData[i1] = dragonfly + 0.5F * ant; + reData[i2] = butterfly - 0.5F * beetle; + reData[i3] = dragonfly - ant; +} /* end run */ + +} /* end class DFTLength6RealFloat */ + +/*==================================================================== +| DFTLength8 +\===================================================================*/ +static class DFTLength8 + +{ /* begin class DFTLength8 */ + +/*.................................................................... + DFTLength8 static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 24L + + FFTSetup.FLOP * 56L + + FFTSetup.FLASSIGN * 68L + + FFTSetup.INTALLOC * 1L + + FFTSetup.INTOP * 15L + + FFTSetup.INTASSIGN * 14L + + FFTSetup.IDX * 32L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength8 */ + +/*==================================================================== +| DFTLength8Double +\===================================================================*/ +static class DFTLength8Double + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength8Double */ + +/*.................................................................... + DFTLength8Double static variables +....................................................................*/ +private static final double SQRTHALF = 1.0 / sqrt(2.0); + +/*.................................................................... + DFTLength8Double constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength8Double ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength8Double */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength8Double"); + int k = startIndex; + double reData0 = reData[k]; + double imData0 = imData[k]; + k += stride; + double reData1 = reData[k]; + double imData1 = imData[k]; + k += stride; + double reData2 = reData[k]; + double imData2 = imData[k]; + k += stride; + double reData3 = reData[k]; + double imData3 = imData[k]; + k += stride; + double reData4 = reData[k]; + double imData4 = imData[k]; + k += stride; + double reData5 = reData[k]; + double imData5 = imData[k]; + k += stride; + double reData6 = reData[k]; + double imData6 = imData[k]; + k += stride; + double reData7 = reData[k]; + double imData7 = imData[k]; + double reButterfly = reData0 + reData4; + double imButterfly = imData0 + imData4; + double reDragonfly = reData2 + reData6; + double imDragonfly = imData2 + imData6; + final double re0 = reButterfly + reDragonfly; + final double im0 = imButterfly + imDragonfly; + final double re1 = reButterfly - reDragonfly; + final double im1 = imButterfly - imDragonfly; + reButterfly = reData0 - reData4; + imButterfly = imData0 - imData4; + reDragonfly = imData6 - imData2; + imDragonfly = reData2 - reData6; + reData0 = reButterfly + reDragonfly; + imData0 = imButterfly + imDragonfly; + reData2 = reButterfly - reDragonfly; + imData2 = imButterfly - imDragonfly; + reButterfly = reData1 + reData5; + imButterfly = imData1 + imData5; + reDragonfly = reData3 + reData7; + imDragonfly = imData3 + imData7; + reData4 = reButterfly + reDragonfly; + imData4 = imButterfly + imDragonfly; + reData6 = imDragonfly - imButterfly; + imData6 = reButterfly - reDragonfly; + reData5 -= reData1; + imData5 -= imData1; + reButterfly = SQRTHALF * (reData5 + imData5); + imButterfly = SQRTHALF * (reData5 - imData5); + reData7 -= reData3; + imData7 -= imData3; + reDragonfly = SQRTHALF * (imData7 - reData7); + imDragonfly = SQRTHALF * (imData7 + reData7); + reData1 = imButterfly - imDragonfly; + imData1 = reDragonfly - reButterfly; + reData3 = reDragonfly + reButterfly; + imData3 = imButterfly + imDragonfly; + reData[k] = reData0 - reData1; + imData[k] = imData0 + imData1; + k -= stride; + reData[k] = re1 + reData6; + imData[k] = im1 + imData6; + k -= stride; + reData[k] = reData2 + reData3; + imData[k] = imData2 - imData3; + k -= stride; + reData[k] = re0 - reData4; + imData[k] = im0 - imData4; + k -= stride; + reData[k] = reData0 + reData1; + imData[k] = imData0 - imData1; + k -= stride; + reData[k] = re1 - reData6; + imData[k] = im1 - imData6; + k -= stride; + reData[k] = reData2 - reData3; + imData[k] = imData2 + imData3; + k -= stride; + reData[k] = re0 + reData4; + imData[k] = im0 + imData4; +} /* end run */ + +} /* end class DFTLength8Double */ + +/*==================================================================== +| DFTLength8Float +\===================================================================*/ +static class DFTLength8Float + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength8Float */ + +/*.................................................................... + DFTLength8Float static variables +....................................................................*/ +private static final float SQRTHALF = 1.0F / (float)sqrt(2.0); + +/*.................................................................... + DFTLength8Float constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength8Float ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength8Float */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength8Float"); + int k = startIndex; + float reData0 = reData[k]; + float imData0 = imData[k]; + k += stride; + float reData1 = reData[k]; + float imData1 = imData[k]; + k += stride; + float reData2 = reData[k]; + float imData2 = imData[k]; + k += stride; + float reData3 = reData[k]; + float imData3 = imData[k]; + k += stride; + float reData4 = reData[k]; + float imData4 = imData[k]; + k += stride; + float reData5 = reData[k]; + float imData5 = imData[k]; + k += stride; + float reData6 = reData[k]; + float imData6 = imData[k]; + k += stride; + float reData7 = reData[k]; + float imData7 = imData[k]; + float reButterfly = reData0 + reData4; + float imButterfly = imData0 + imData4; + float reDragonfly = reData2 + reData6; + float imDragonfly = imData2 + imData6; + final float re0 = reButterfly + reDragonfly; + final float im0 = imButterfly + imDragonfly; + final float re1 = reButterfly - reDragonfly; + final float im1 = imButterfly - imDragonfly; + reButterfly = reData0 - reData4; + imButterfly = imData0 - imData4; + reDragonfly = imData6 - imData2; + imDragonfly = reData2 - reData6; + reData0 = reButterfly + reDragonfly; + imData0 = imButterfly + imDragonfly; + reData2 = reButterfly - reDragonfly; + imData2 = imButterfly - imDragonfly; + reButterfly = reData1 + reData5; + imButterfly = imData1 + imData5; + reDragonfly = reData3 + reData7; + imDragonfly = imData3 + imData7; + reData4 = reButterfly + reDragonfly; + imData4 = imButterfly + imDragonfly; + reData6 = imDragonfly - imButterfly; + imData6 = reButterfly - reDragonfly; + reData5 -= reData1; + imData5 -= imData1; + reButterfly = SQRTHALF * (reData5 + imData5); + imButterfly = SQRTHALF * (reData5 - imData5); + reData7 -= reData3; + imData7 -= imData3; + reDragonfly = SQRTHALF * (imData7 - reData7); + imDragonfly = SQRTHALF * (imData7 + reData7); + reData1 = imButterfly - imDragonfly; + imData1 = reDragonfly - reButterfly; + reData3 = reDragonfly + reButterfly; + imData3 = imButterfly + imDragonfly; + reData[k] = reData0 - reData1; + imData[k] = imData0 + imData1; + k -= stride; + reData[k] = re1 + reData6; + imData[k] = im1 + imData6; + k -= stride; + reData[k] = reData2 + reData3; + imData[k] = imData2 - imData3; + k -= stride; + reData[k] = re0 - reData4; + imData[k] = im0 - imData4; + k -= stride; + reData[k] = reData0 + reData1; + imData[k] = imData0 - imData1; + k -= stride; + reData[k] = re1 - reData6; + imData[k] = im1 - imData6; + k -= stride; + reData[k] = reData2 - reData3; + imData[k] = imData2 + imData3; + k -= stride; + reData[k] = re0 + reData4; + imData[k] = im0 + imData4; +} /* end run */ + +} /* end class DFTLength8Float */ + +/*==================================================================== +| DFTLength8Real +\===================================================================*/ +static class DFTLength8Real + +{ /* begin class DFTLength8Real */ + +/*.................................................................... + DFTLength8Real static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( +) { + return(FFTSetup.FLALLOC * 8L + + FFTSetup.FLOP * 22L + + FFTSetup.FLASSIGN * 26L + + FFTSetup.INTALLOC * 7L + + FFTSetup.INTOP * 7L + + FFTSetup.INTASSIGN * 7L + + FFTSetup.IDX * 22L + + FFTSetup.NEWOBJ * 0L + ); +} /* end cost */ + +} /* end class DFTLength8Real */ + +/*==================================================================== +| DFTLength8RealDouble +\===================================================================*/ +static class DFTLength8RealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTLength8RealDouble */ + +/*.................................................................... + DFTLength8RealDouble static variables +....................................................................*/ +private static final double NEGSQRTHALF = -1.0 / sqrt(2.0); + +/*.................................................................... + DFTLength8RealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength8RealDouble ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength8RealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength8RealDouble"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final int i3 = i2 + stride; + final int i4 = i3 + stride; + final int i5 = i4 + stride; + final int i6 = i5 + stride; + final int i7 = i6 + stride; + double re0 = reData[startIndex]; + double re2 = reData[i2]; + final double re4 = reData[i4]; + final double re6 = reData[i6]; + double butterfly = re0 + re4; + double dragonfly = re2 + re6; + double ladybug = butterfly + dragonfly; + reData[i2] = butterfly - dragonfly; + butterfly = reData[i1] + reData[i5]; + dragonfly = reData[i3] + reData[i7]; + double moth = dragonfly + butterfly; + imData[i2] = dragonfly - butterfly; + reData[startIndex] = ladybug + moth; + imData[startIndex] = 0.0; + reData[i4] = ladybug - moth; + imData[i4] = 0.0; + butterfly = re0 - re4; + dragonfly = re2 - re6; + re0 = reData[i1] - reData[i5]; + re2 = reData[i3] - reData[i7]; + ladybug = NEGSQRTHALF * (re0 - re2); + moth = NEGSQRTHALF * (re0 + re2); + reData[i1] = butterfly - ladybug; + imData[i1] = moth - dragonfly; + reData[i3] = butterfly + ladybug; + imData[i3] = moth + dragonfly; +} /* end run */ + +} /* end class DFTLength8RealDouble */ + +/*==================================================================== +| DFTLength8RealFloat +\===================================================================*/ +static class DFTLength8RealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTLength8RealFloat */ + +/*.................................................................... + DFTLength8RealFloat static variables +....................................................................*/ +private static final float NEGSQRTHALF = -1.0F / (float)sqrt(2.0); + +/*.................................................................... + DFTLength8RealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTLength8RealFloat ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride +) { + super(reData, imData, startIndex, stride); +} /* end DFTLength8RealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { +//;IJ.log("DFTLength8RealFloat"); + final int i1 = startIndex + stride; + final int i2 = i1 + stride; + final int i3 = i2 + stride; + final int i4 = i3 + stride; + final int i5 = i4 + stride; + final int i6 = i5 + stride; + final int i7 = i6 + stride; + float re0 = reData[startIndex]; + float re2 = reData[i2]; + final float re4 = reData[i4]; + final float re6 = reData[i6]; + float butterfly = re0 + re4; + float dragonfly = re2 + re6; + float ladybug = butterfly + dragonfly; + reData[i2] = butterfly - dragonfly; + butterfly = reData[i1] + reData[i5]; + dragonfly = reData[i3] + reData[i7]; + float moth = dragonfly + butterfly; + imData[i2] = dragonfly - butterfly; + reData[startIndex] = ladybug + moth; + imData[startIndex] = 0.0F; + reData[i4] = ladybug - moth; + imData[i4] = 0.0F; + butterfly = re0 - re4; + dragonfly = re2 - re6; + re0 = reData[i1] - reData[i5]; + re2 = reData[i3] - reData[i7]; + ladybug = NEGSQRTHALF * (re0 - re2); + moth = NEGSQRTHALF * (re0 + re2); + reData[i1] = butterfly - ladybug; + imData[i1] = moth - dragonfly; + reData[i3] = butterfly + ladybug; + imData[i3] = moth + dragonfly; +} /* end run */ + +} /* end class DFTLength8RealFloat */ + +/*==================================================================== +| DFTMixedRadix +\===================================================================*/ +static class DFTMixedRadix + +{ /* begin class DFTMixedRadix */ + +/*.................................................................... + DFTMixedRadix static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int K1, + final int K2 +) { + if (FFTSetup.taboos.contains(new Integer(K1)) + || FFTSetup.taboos.contains(new Integer(K2))) { + return(-1L); + } + final long K = (long)K1 * (long)K2; + return(FFTSetup.FLALLOC * 4L + + FFTSetup.FLOP * ((long)K2 * ((long)K1 * 6L)) + + FFTSetup.FLASSIGN * ((long)K2 * ((long)K1 * 6L) + + (long)K2 * ((long)K1 * 2L) + K * 2L) + + FFTSetup.INTALLOC * 16L + + FFTSetup.INTOP * (3L + (long)K2 * 3L + (long)K2 * (3L + + (long)K1 * 7L) + 1L + (long)K1 * 3L + (long)K2 * (3L + + (long)K1 * 4L) + K * 3L) + + FFTSetup.INTASSIGN * (6L + (long)K2 * 2L + 2L + (long)K2 * (3L + + (long)K1 * 4L) + 2L + (long)K1 * 2L + 3L + (long)K2 * (4L + + (long)K1 * 3L) + 2L + K * 2L) + + FFTSetup.IDX * ((long)K2 * ((long)K1 * 6L) + + (long)K2 * ((long)K1 * 4L) + K * 4L) + + FFTSetup.NEWOBJ * ((long)K2 * 1L + (long)K1 * 1L) + + (long)K2 * FFTSetup.cost(K1) + (long)K1 * FFTSetup.cost(K2) + ); +} /* end cost */ + +} /* end class DFTMixedRadix */ + +/*==================================================================== +| DFTMixedRadixDouble +\===================================================================*/ +static class DFTMixedRadixDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTMixedRadixDouble */ + +/*.................................................................... + DFTMixedRadixDouble private variables +....................................................................*/ +private double[] imBuffer; +private double[] imUnitRoot; +private double[] reBuffer; +private double[] reUnitRoot; +private int K1; + +/*.................................................................... + DFTMixedRadixDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTMixedRadixDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reUnitRoot, + final double[] imUnitRoot, + final int K1 +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; + this.K1 = K1; +} /* end DFTMixedRadixDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = reUnitRoot.length; +//;IJ.log("DFTMixedRadixDouble " + transformLength + " / " + K1); + final int K2 = transformLength / K1; + final int d1 = stride; + final int d2 = K2 * d1; + int k2 = startIndex; + final FFTSetup fft1 = FFTSetup.transforms.get(new Integer(K1)); + switch (fft1.algorithm) { + case BRUTEFORCE: { + for (int n = 0; (n < K2); n++) { + new DFTBruteForceDouble(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + k2 += d1; + } + break; + } + case COPRIMEFACTOR: { + for (int n = 0; (n < K2); n++) { + new DFTCoprimeFactorDouble(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.ruritanian, fft1.chinese, fft1.K1).run(); + k2 += d1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int n = 0; (n < K2); n++) { + new DFTLength2Double(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH3: { + for (int n = 0; (n < K2); n++) { + new DFTLength3Double(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH4: { + for (int n = 0; (n < K2); n++) { + new DFTLength4Double(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH5: { + for (int n = 0; (n < K2); n++) { + new DFTLength5Double(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH6: { + for (int n = 0; (n < K2); n++) { + new DFTLength6Double(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH8: { + for (int n = 0; (n < K2); n++) { + new DFTLength8Double(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case MIXEDRADIX: { + for (int n = 0; (n < K2); n++) { + new DFTMixedRadixDouble(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reUnitRootDouble, fft1.imUnitRootDouble, + fft1.K1).run(); + k2 += d1; + } + break; + } + case PADDEDRADER: { + for (int n = 0; (n < K2); n++) { + new DFTPaddedRaderDouble(reData, imData, + k2, d2, fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular).run(); + k2 += d1; + } + break; + } + case RADER: { + for (int n = 0; (n < K2); n++) { + new DFTRaderDouble(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular).run(); + k2 += d1; + } + break; + } + case RADIX2: { + for (int n = 0; (n < K2); n++) { + new DFTRadix2Double(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + k2 += d1; + } + break; + } + case SPLITRADIX: { + for (int n = 0; (n < K2); n++) { + new DFTSplitRadixDouble(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + k2 += d1; + } + break; + } + } + k2 = startIndex; + for (int n = 0; (n < K2); n++) { + int m2 = 0; + int m1 = k2; + k2 += d1; + for (int m = 0; (m < K1); m++) { + final double re = reData[m1]; + final double im = imData[m1]; + final double reRoot = reUnitRoot[m2]; + final double imRoot = imUnitRoot[m2]; + reData[m1] = re * reRoot - im * imRoot; + imData[m1] = re * imRoot + im * reRoot; + m1 += d2; + m2 += n; + m2 -= transformLength * (m2 / transformLength); + } + } + int k1 = startIndex; + final FFTSetup fft2 = FFTSetup.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int n = 0; (n < K1); n++) { + new DFTBruteForceDouble(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + k1 += d2; + } + break; + } + case COPRIMEFACTOR: { + for (int n = 0; (n < K1); n++) { + new DFTCoprimeFactorDouble(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.ruritanian, fft2.chinese, fft2.K1).run(); + k1 += d2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int n = 0; (n < K1); n++) { + new DFTLength2Double(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH3: { + for (int n = 0; (n < K1); n++) { + new DFTLength3Double(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH4: { + for (int n = 0; (n < K1); n++) { + new DFTLength4Double(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH5: { + for (int n = 0; (n < K1); n++) { + new DFTLength5Double(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH6: { + for (int n = 0; (n < K1); n++) { + new DFTLength6Double(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH8: { + for (int n = 0; (n < K1); n++) { + new DFTLength8Double(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case MIXEDRADIX: { + for (int n = 0; (n < K1); n++) { + new DFTMixedRadixDouble(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1).run(); + k1 += d2; + } + break; + } + case PADDEDRADER: { + for (int n = 0; (n < K1); n++) { + new DFTPaddedRaderDouble(reData, imData, + k1, d1, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + k1 += d2; + } + break; + } + case RADER: { + for (int n = 0; (n < K1); n++) { + new DFTRaderDouble(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + k1 += d2; + } + break; + } + case RADIX2: { + for (int n = 0; (n < K1); n++) { + new DFTRadix2Double(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + k1 += d2; + } + break; + } + case SPLITRADIX: { + for (int n = 0; (n < K1); n++) { + new DFTSplitRadixDouble(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + k1 += d2; + } + break; + } + } + k1 = startIndex; + k2 = startIndex; + for (int m2 = 0; (m2 < K2); m2++) { + int n2 = k1; + for (int m1 = 0; (m1 < K1); m1++) { + reBuffer[k2] = reData[n2]; + imBuffer[k2] = imData[n2]; + k2 += d1; + n2 += d2; + } + k1 += d1; + } + k1 = startIndex; + for (int m = 0; (m < transformLength); m++) { + reData[k1] = reBuffer[k1]; + imData[k1] = imBuffer[k1]; + k1 += d1; + } +} /* end run */ + +/*.................................................................... + DFTMixedRadixDouble static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static double[] getImUnitRoot ( + final int transformLength +) { + final double[] imUnitRoot = new double[transformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < transformLength); k++) { + imUnitRoot[k] = sin((double)k * angularStep); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static double[] getReUnitRoot ( + final int transformLength +) { + final double[] reUnitRoot = new double[transformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < transformLength); k++) { + reUnitRoot[k] = cos((double)k * angularStep); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTMixedRadixDouble */ + +/*==================================================================== +| DFTMixedRadixFloat +\===================================================================*/ +static class DFTMixedRadixFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTMixedRadixFloat */ + +/*.................................................................... + DFTMixedRadixFloat private variables +....................................................................*/ +private float[] imBuffer; +private float[] imUnitRoot; +private float[] reBuffer; +private float[] reUnitRoot; +private int K1; + +/*.................................................................... + DFTMixedRadixFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTMixedRadixFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reUnitRoot, + final float[] imUnitRoot, + final int K1 +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; + this.K1 = K1; +} /* end DFTMixedRadixFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = reUnitRoot.length; +//;IJ.log("DFTMixedRadixFloat " + transformLength + " / " + K1); + final int K2 = transformLength / K1; + final int d1 = stride; + final int d2 = K2 * d1; + int k2 = startIndex; + final FFTSetup fft1 = FFTSetup.transforms.get(new Integer(K1)); + switch (fft1.algorithm) { + case BRUTEFORCE: { + for (int n = 0; (n < K2); n++) { + new DFTBruteForceFloat(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + k2 += d1; + } + break; + } + case COPRIMEFACTOR: { + for (int n = 0; (n < K2); n++) { + new DFTCoprimeFactorFloat(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.ruritanian, fft1.chinese, fft1.K1).run(); + k2 += d1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int n = 0; (n < K2); n++) { + new DFTLength2Float(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH3: { + for (int n = 0; (n < K2); n++) { + new DFTLength3Float(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH4: { + for (int n = 0; (n < K2); n++) { + new DFTLength4Float(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH5: { + for (int n = 0; (n < K2); n++) { + new DFTLength5Float(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH6: { + for (int n = 0; (n < K2); n++) { + new DFTLength6Float(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case LENGTH8: { + for (int n = 0; (n < K2); n++) { + new DFTLength8Float(reData, imData, k2, d2).run(); + k2 += d1; + } + break; + } + case MIXEDRADIX: { + for (int n = 0; (n < K2); n++) { + new DFTMixedRadixFloat(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reUnitRootFloat, fft1.imUnitRootFloat, + fft1.K1).run(); + k2 += d1; + } + break; + } + case PADDEDRADER: { + for (int n = 0; (n < K2); n++) { + new DFTPaddedRaderFloat(reData, imData, + k2, d2, fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular).run(); + k2 += d1; + } + break; + } + case RADER: { + for (int n = 0; (n < K2); n++) { + new DFTRaderFloat(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular).run(); + k2 += d1; + } + break; + } + case RADIX2: { + for (int n = 0; (n < K2); n++) { + new DFTRadix2Float(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + k2 += d1; + } + break; + } + case SPLITRADIX: { + for (int n = 0; (n < K2); n++) { + new DFTSplitRadixFloat(reData, imData, reBuffer, imBuffer, + k2, d2, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + k2 += d1; + } + break; + } + } + k2 = startIndex; + for (int n = 0; (n < K2); n++) { + int m2 = 0; + int m1 = k2; + k2 += d1; + for (int m = 0; (m < K1); m++) { + final float re = reData[m1]; + final float im = imData[m1]; + final float reRoot = reUnitRoot[m2]; + final float imRoot = imUnitRoot[m2]; + reData[m1] = re * reRoot - im * imRoot; + imData[m1] = re * imRoot + im * reRoot; + m1 += d2; + m2 += n; + m2 -= transformLength * (m2 / transformLength); + } + } + int k1 = startIndex; + final FFTSetup fft2 = FFTSetup.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int n = 0; (n < K1); n++) { + new DFTBruteForceFloat(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + k1 += d2; + } + break; + } + case COPRIMEFACTOR: { + for (int n = 0; (n < K1); n++) { + new DFTCoprimeFactorFloat(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.ruritanian, fft2.chinese, fft2.K1).run(); + k1 += d2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int n = 0; (n < K1); n++) { + new DFTLength2Float(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH3: { + for (int n = 0; (n < K1); n++) { + new DFTLength3Float(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH4: { + for (int n = 0; (n < K1); n++) { + new DFTLength4Float(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH5: { + for (int n = 0; (n < K1); n++) { + new DFTLength5Float(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH6: { + for (int n = 0; (n < K1); n++) { + new DFTLength6Float(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case LENGTH8: { + for (int n = 0; (n < K1); n++) { + new DFTLength8Float(reData, imData, k1, d1).run(); + k1 += d2; + } + break; + } + case MIXEDRADIX: { + for (int n = 0; (n < K1); n++) { + new DFTMixedRadixFloat(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1).run(); + k1 += d2; + } + break; + } + case PADDEDRADER: { + for (int n = 0; (n < K1); n++) { + new DFTPaddedRaderFloat(reData, imData, + k1, d1, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + k1 += d2; + } + break; + } + case RADER: { + for (int n = 0; (n < K1); n++) { + new DFTRaderFloat(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + k1 += d2; + } + break; + } + case RADIX2: { + for (int n = 0; (n < K1); n++) { + new DFTRadix2Float(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + k1 += d2; + } + break; + } + case SPLITRADIX: { + for (int n = 0; (n < K1); n++) { + new DFTSplitRadixFloat(reData, imData, reBuffer, imBuffer, + k1, d1, fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + k1 += d2; + } + break; + } + } + k1 = startIndex; + k2 = startIndex; + for (int m2 = 0; (m2 < K2); m2++) { + int n2 = k1; + for (int m1 = 0; (m1 < K1); m1++) { + reBuffer[k2] = reData[n2]; + imBuffer[k2] = imData[n2]; + k2 += d1; + n2 += d2; + } + k1 += d1; + } + k1 = startIndex; + for (int m = 0; (m < transformLength); m++) { + reData[k1] = reBuffer[k1]; + imData[k1] = imBuffer[k1]; + k1 += d1; + } +} /* end run */ + +/*.................................................................... + DFTMixedRadixFloat static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static float[] getImUnitRoot ( + final int transformLength +) { + final float[] imUnitRoot = new float[transformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < transformLength); k++) { + imUnitRoot[k] = (float)sin((double)((float)k * angularStep)); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static float[] getReUnitRoot ( + final int transformLength +) { + final float[] reUnitRoot = new float[transformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < transformLength); k++) { + reUnitRoot[k] = (float)cos((double)((float)k * angularStep)); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTMixedRadixFloat */ + +/*==================================================================== +| DFTMixedRadixReal +\===================================================================*/ +static class DFTMixedRadixReal + +{ /* begin class DFTMixedRadixReal */ + +/*.................................................................... + DFTMixedRadixReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int K1, + final int K2 +) { + if (FFTSetup.taboos.contains(new Integer(K1)) + || FFTSetup.taboos.contains(new Integer(K2))) { + return(-1L); + } + final long K = (long)K1 * (long)K2; + final long k = K >> 1L; + final long k1 = (long)(K1 >> 1); + final long k2 = (long)(K2 >> 1); + return(FFTSetup.FLALLOC * 4L + + FFTSetup.FLOP * ((k2 + 1L) * ((long)K1 * 6L) + k1 * k2 * 1L) + + FFTSetup.FLASSIGN * ((k2 + 1L) * ((long)K1 * 6L) + 2L + K * 1L) + + FFTSetup.INTALLOC * 14L + + FFTSetup.INTOP * (7L + (long)K1 * 3L + (k2 + 1L) * (2L + + (long)K1 * 4L) + 1L + (k2 + 1L) * 3L + 4L + (K * 2L + K1 * 5L) + + 2L) + + FFTSetup.INTASSIGN * (7L + (long)K1 * 2L + 1L + (k2 + 1L) * (3L + + (long)K1 * 3L) + 2L + (k2 + 1L) * 2L + 5L + (k * 3L + K1 * 3L)) + + FFTSetup.IDX * ((k2 + 1L) * ((long)K1 * 6L) + 3L + (K * 2L)) + + FFTSetup.NEWOBJ * ((long)K1 * 1L + (k2 + 1L) * 1L) + + k1 * FFTSetupDuoReal.cost(K2) + (k2 + 1L) * FFTSetup.cost(K1) + ); +} /* end cost */ + +} /* end class DFTMixedRadixReal */ + +/*==================================================================== +| DFTMixedRadixRealDouble +\===================================================================*/ +static class DFTMixedRadixRealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTMixedRadixRealDouble */ + +/*.................................................................... + DFTMixedRadixRealDouble private variables +....................................................................*/ +private double[] imBuffer; +private double[] imUnitRoot; +private double[] reBuffer; +private double[] reUnitRoot; +private int K1; + +/*.................................................................... + DFTMixedRadixRealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTMixedRadixRealDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reUnitRoot, + final double[] imUnitRoot, + final int K1 +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; + this.K1 = K1; +} /* end DFTMixedRadixDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = reUnitRoot.length; +//;IJ.log("DFTMixedRadixRealDouble " + transformLength + " / " + K1); + final int K2 = transformLength / K1; + final int halfK2 = (K2 >> 1) + 1; + final int d1 = stride; + final int d2 = K1 * d1; + int p = startIndex; + int k1 = 0; + if (1 == (K1 & 1)) { + final FFTSetupReal fft2 = FFTSetupReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2RealDouble(reData, imData, p, d2).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble(reData, imData, p, d2).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble(reData, imData, p, d2).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble(reData, imData, p, d2).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble(reData, imData, p, d2).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reData, imData, p, d2).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reData, imData, + p, d2, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootEvenDouble, fft2.imUnitRootEvenDouble, + fft2.reUnitRootOddDouble, fft2.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + } + p += d1; + k1++; + } + final FFTSetupDuoReal fft2 = + FFTSetupDuoReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + while (k1++ < K1) { + new DFTBruteForceRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + p += d1; + } + break; + } + case COPRIMEFACTOR: { + while (k1++ < K1) { + new DFTCoprimeFactorRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + p += d1; + } + break; + } + case DUOREAL: { + while (k1++ < K1) { + new DFTDuoRealDouble(reData, imData, + reBuffer, imBuffer, p, p + d1, d2, K2).run(); + p += 2 * d1; + k1++; + } + break; + } + case EVENREAL: { + while (k1++ < K1) { + new DFTEvenRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + p += d1; + } + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + while (k1++ < K1) { + new DFTLength2RealDouble(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH3: { + while (k1++ < K1) { + new DFTLength3RealDouble(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH4: { + while (k1++ < K1) { + new DFTLength4RealDouble(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH5: { + while (k1++ < K1) { + new DFTLength5RealDouble(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH6: { + while (k1++ < K1) { + new DFTLength6RealDouble(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH8: { + while (k1++ < K1) { + new DFTLength8RealDouble(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case MIXEDRADIX: { + while (k1++ < K1) { + new DFTMixedRadixRealDouble(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1).run(); + p += d1; + } + break; + } + case PADDEDRADER: { + while (k1++ < K1) { + new DFTPaddedRaderRealDouble(reData, imData, + p, d2, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADER: { + while (k1++ < K1) { + new DFTRaderRealDouble(reData, imData, reBuffer, imBuffer, + p, d2, fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADIX2: { + while (k1++ < K1) { + new DFTRadix2RealDouble(reData, imData, reBuffer, imBuffer, + p, d2, fft2.reUnitRootEvenDouble, fft2.imUnitRootEvenDouble, + fft2.reUnitRootOddDouble, fft2.imUnitRootOddDouble).run(); + p += d1; + } + break; + } + case SPLITRADIX: { + while (k1++ < K1) { + new DFTSplitRadixRealDouble(reData, imData, reBuffer, imBuffer, + p, d2, fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + p += d1; + } + break; + } + } + p = startIndex; + for (int n2 = 0; (n2 < halfK2); n2++) { + int n = 0; + for (k1 = 0; (k1 < K1); k1++) { + final double re = reData[p]; + final double im = imData[p]; + final double reRoot = reUnitRoot[n]; + final double imRoot = imUnitRoot[n]; + reBuffer[p] = re * reRoot - im * imRoot; + imBuffer[p] = re * imRoot + im * reRoot; + p += d1; + n += n2; + } + } + p = startIndex; + final FFTSetup fft1 = FFTSetup.transforms.get(new Integer(K1)); + switch (fft1.algorithm) { + case BRUTEFORCE: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTBruteForceDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + p += d2; + } + break; + } + case COPRIMEFACTOR: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTCoprimeFactorDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.ruritanian, fft1.chinese, fft1.K1).run(); + p += d2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength2Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH3: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength3Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH4: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength4Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH5: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength5Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH6: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength6Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH8: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength8Double(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case MIXEDRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTMixedRadixDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble, + fft1.K1).run(); + p += d2; + } + break; + } + case PADDEDRADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTPaddedRaderDouble(reBuffer, imBuffer, + p, d1, fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTRaderDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADIX2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTRadix2Double(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + p += d2; + } + break; + } + case SPLITRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTSplitRadixDouble(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootDouble, fft1.imUnitRootDouble).run(); + p += d2; + } + break; + } + } + p = startIndex; + reData[p] = reBuffer[p]; + imData[p] = 0.0; + p += d1; + int progressive = startIndex; + int regressive = startIndex + (K1 - 1) * d1; + int k2 = 1; + while (progressive < regressive) { + int q = progressive + d2; + while (k2 < halfK2) { + reData[p] = reBuffer[q]; + imData[p] = imBuffer[q]; + k2++; + p += d1; + q += d2; + } + k2 -= 2 - (K2 & 1); + progressive += d1; + q = regressive + k2 * d2; + while (0 <= k2) { + reData[p] = reBuffer[q]; + imData[p] = -imBuffer[q]; + k2--; + p += d1; + q -= d2; + } + k2 += 2; + regressive -= d1; + } + if (1 == (K1 & 1)) { + int q = progressive + k2 * d2; + while (k2 < halfK2) { + reData[p] = reBuffer[q]; + imData[p] = imBuffer[q]; + k2++; + p += d1; + q += d2; + } + } +} /* end run */ + +} /* end class DFTMixedRadixRealDouble */ + +/*==================================================================== +| DFTMixedRadixRealFloat +\===================================================================*/ +static class DFTMixedRadixRealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTMixedRadixRealFloat */ + +/*.................................................................... + DFTMixedRadixRealFloat private variables +....................................................................*/ +private float[] imBuffer; +private float[] imUnitRoot; +private float[] reBuffer; +private float[] reUnitRoot; +private int K1; + +/*.................................................................... + DFTMixedRadixRealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTMixedRadixRealFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reUnitRoot, + final float[] imUnitRoot, + final int K1 +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; + this.K1 = K1; +} /* end DFTMixedRadixRealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int transformLength = reUnitRoot.length; +//;IJ.log("DFTMixedRadixRealFloat " + transformLength + " / " + K1); + final int K2 = transformLength / K1; + final int halfK2 = (K2 >> 1) + 1; + final int d1 = stride; + final int d2 = K1 * d1; + int p = startIndex; + int k1 = 0; + if (1 == (K1 & 1)) { + final FFTSetupReal fft2 = FFTSetupReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2RealFloat(reData, imData, p, d2).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reData, imData, p, d2).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reData, imData, p, d2).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reData, imData, p, d2).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reData, imData, p, d2).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reData, imData, p, d2).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reData, imData, + p, d2, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootEvenFloat, fft2.imUnitRootEvenFloat, + fft2.reUnitRootOddFloat, fft2.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + } + p += d1; + k1++; + } + final FFTSetupDuoReal fft2 = + FFTSetupDuoReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + while (k1++ < K1) { + new DFTBruteForceRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + p += d1; + } + break; + } + case COPRIMEFACTOR: { + while (k1++ < K1) { + new DFTCoprimeFactorRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + p += d1; + } + break; + } + case DUOREAL: { + while (k1++ < K1) { + new DFTDuoRealFloat(reData, imData, + reBuffer, imBuffer, p, p + d1, d2, K2).run(); + p += 2 * d1; + k1++; + } + break; + } + case EVENREAL: { + while (k1++ < K1) { + new DFTEvenRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + p += d1; + } + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + while (k1++ < K1) { + new DFTLength2RealFloat(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH3: { + while (k1++ < K1) { + new DFTLength3RealFloat(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH4: { + while (k1++ < K1) { + new DFTLength4RealFloat(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH5: { + while (k1++ < K1) { + new DFTLength5RealFloat(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH6: { + while (k1++ < K1) { + new DFTLength6RealFloat(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case LENGTH8: { + while (k1++ < K1) { + new DFTLength8RealFloat(reData, imData, p, d2).run(); + p += d1; + } + break; + } + case MIXEDRADIX: { + while (k1++ < K1) { + new DFTMixedRadixRealFloat(reData, imData, + reBuffer, imBuffer, p, d2, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1).run(); + p += d1; + } + break; + } + case PADDEDRADER: { + while (k1++ < K1) { + new DFTPaddedRaderRealFloat(reData, imData, + p, d2, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADER: { + while (k1++ < K1) { + new DFTRaderRealFloat(reData, imData, reBuffer, imBuffer, + p, d2, fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + p += d1; + } + break; + } + case RADIX2: { + while (k1++ < K1) { + new DFTRadix2RealFloat(reData, imData, reBuffer, imBuffer, + p, d2, fft2.reUnitRootEvenFloat, fft2.imUnitRootEvenFloat, + fft2.reUnitRootOddFloat, fft2.imUnitRootOddFloat).run(); + p += d1; + } + break; + } + case SPLITRADIX: { + while (k1++ < K1) { + new DFTSplitRadixRealFloat(reData, imData, reBuffer, imBuffer, + p, d2, fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + p += d1; + } + break; + } + } + p = startIndex; + for (int n2 = 0; (n2 < halfK2); n2++) { + int n = 0; + for (k1 = 0; (k1 < K1); k1++) { + final float re = reData[p]; + final float im = imData[p]; + final float reRoot = reUnitRoot[n]; + final float imRoot = imUnitRoot[n]; + reBuffer[p] = re * reRoot - im * imRoot; + imBuffer[p] = re * imRoot + im * reRoot; + p += d1; + n += n2; + } + } + p = startIndex; + final FFTSetup fft1 = FFTSetup.transforms.get(new Integer(K1)); + switch (fft1.algorithm) { + case BRUTEFORCE: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTBruteForceFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + p += d2; + } + break; + } + case COPRIMEFACTOR: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTCoprimeFactorFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.ruritanian, fft1.chinese, fft1.K1).run(); + p += d2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength2Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH3: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength3Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH4: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength4Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH5: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength5Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH6: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength6Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case LENGTH8: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTLength8Float(reBuffer, imBuffer, p, d1).run(); + p += d2; + } + break; + } + case MIXEDRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTMixedRadixFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat, + fft1.K1).run(); + p += d2; + } + break; + } + case PADDEDRADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTPaddedRaderFloat(reBuffer, imBuffer, + p, d1, fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTRaderFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular).run(); + p += d2; + } + break; + } + case RADIX2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTRadix2Float(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + p += d2; + } + break; + } + case SPLITRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + new DFTSplitRadixFloat(reBuffer, imBuffer, reData, imData, + p, d1, fft1.reUnitRootFloat, fft1.imUnitRootFloat).run(); + p += d2; + } + break; + } + } + p = startIndex; + reData[p] = reBuffer[p]; + imData[p] = 0.0F; + p += d1; + int progressive = startIndex; + int regressive = startIndex + (K1 - 1) * d1; + int k2 = 1; + while (progressive < regressive) { + int q = progressive + d2; + while (k2 < halfK2) { + reData[p] = reBuffer[q]; + imData[p] = imBuffer[q]; + k2++; + p += d1; + q += d2; + } + k2 -= 2 - (K2 & 1); + progressive += d1; + q = regressive + k2 * d2; + while (0 <= k2) { + reData[p] = reBuffer[q]; + imData[p] = -imBuffer[q]; + k2--; + p += d1; + q -= d2; + } + k2 += 2; + regressive -= d1; + } + if (1 == (K1 & 1)) { + int q = progressive + k2 * d2; + while (k2 < halfK2) { + reData[p] = reBuffer[q]; + imData[p] = imBuffer[q]; + k2++; + p += d1; + q += d2; + } + } +} /* end run */ + +} /* end class DFTMixedRadixRealFloat */ + +/*==================================================================== +| DFTPaddedRader +\===================================================================*/ +static class DFTPaddedRader + +{ /* begin class DFTPaddedRader */ + +/*.................................................................... + DFTPaddedRader static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int prime, + final int paddedLength +) { + if (FFTSetup.taboos.contains(new Integer(paddedLength))) { + return(-1L); + } + final long K = (long)prime; + final long P = (long)paddedLength; + return(FFTSetup.FLALLOC * (P * 4L + 8L) + + FFTSetup.FLOP * (P * 6L + (K - 1L) * 2L + 2L) + + FFTSetup.FLASSIGN * (P * 4L + 2L + (K - 1L) * 2L + 2L + P * 6L + + (K - 1L) * 2L + 2L) + + FFTSetup.INTALLOC * 9L + + FFTSetup.INTOP * (2L + (K - 1L) * 5L + P * 2L + 1L + (K - 1L) * 3L) + + FFTSetup.INTASSIGN * (4L + (K - 1L) * 3L + 1L + P * 1L + 2L + + (K - 1L) * 3L) + + FFTSetup.IDX * (2L + (K - 1L) * 5L + 2L + P * 6L + (K - 1L) * 5L + 2L) + + 1L * (FFTSetup.NEWOBJ + + FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * 0L + + FFTSetup.FLASSIGN * 0L + + FFTSetup.INTALLOC * 0L + + FFTSetup.INTOP * 1L + + FFTSetup.INTASSIGN * 6L + + FFTSetup.IDX * 0L + + FFTSetup.NEWOBJ * 6L) + + 2L * (FFTSetup.cost(paddedLength) + + FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * 0L + + FFTSetup.FLASSIGN * 0L + + FFTSetup.INTALLOC * 0L + + FFTSetup.INTOP * (10L + 2L) + + FFTSetup.INTASSIGN * 0L + + FFTSetup.IDX * 0L + + FFTSetup.NEWOBJ * 1L) + ); +} /* end cost */ + +/*------------------------------------------------------------------*/ +static int[] getInverseModularPowerShuffling ( + final int[] modularShuffling, + final int paddedLength +) { + final int prime = modularShuffling.length; + int[] inverseShuffling = new int[prime]; + inverseShuffling[modularShuffling[prime - 3]] = 0; + inverseShuffling[modularShuffling[prime - 2]] = 1; + inverseShuffling[modularShuffling[prime - 1]] = paddedLength - prime + 3; + for (int k = 4; (k < prime); k++) { + inverseShuffling[modularShuffling[k - 3]] = paddedLength - prime + k; + } + return(inverseShuffling); +} /* end getInverseModularPowerShuffling */ + +} /* end class DFTPaddedRader */ + +/*==================================================================== +| DFTPaddedRaderDouble +\===================================================================*/ +static class DFTPaddedRaderDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTPaddedRaderDouble */ + +/*.................................................................... + DFTPaddedRaderDouble private variables +....................................................................*/ +private double[] imConvolver; +private double[] reConvolver; +private int[] inverseModular; +private int[] modular; + +/*.................................................................... + DFTPaddedRaderDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTPaddedRaderDouble ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride, + final double[] reConvolver, + final double[] imConvolver, + final int[] modular, + final int[] inverseModular +) { + super(reData, imData, startIndex, stride); + this.reConvolver = reConvolver; + this.imConvolver = imConvolver; + this.modular = modular; + this.inverseModular = inverseModular; +} /* end DFTPaddedRaderDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int prime = modular.length; + final int paddedLength = reConvolver.length; +//;IJ.log("DFTPaddedRaderDouble " + prime + " (" + paddedLength +")"); + final double[] rePadded = new double[paddedLength]; + final double[] imPadded = new double[paddedLength]; + final double[] reBuffer = new double[paddedLength]; + final double[] imBuffer = new double[paddedLength]; + final double reBaseline = reData[startIndex]; + final double imBaseline = imData[startIndex]; + for (int k = paddedLength - prime + 1, m = 1; (k < paddedLength); k++) { + final int q = startIndex + modular[m++] * stride; + rePadded[k] = reData[q]; + imPadded[k] = imData[q]; + } + final AcademicFourierTransform fft = new AcademicFourierTransform(paddedLength, 0); + fft.directTransform(rePadded, imPadded, reBuffer, imBuffer, + InputDataType.COMPLEXINPUT); + final double reSum = rePadded[0]; + final double imSum = imPadded[0]; + for (int k = 0; (k < paddedLength); k++) { + final double re = rePadded[k]; + final double im = imPadded[k]; + final double reWeight = reConvolver[k]; + final double imWeight = imConvolver[k]; + rePadded[k] = re * reWeight - im * imWeight; + imPadded[k] = re * imWeight + im * reWeight; + } + fft.directTransform(rePadded, imPadded, reBuffer, imBuffer, + InputDataType.COMPLEXINPUT); + int p = startIndex + stride; + for (int k = 1; (k < prime); k++) { + final int q = inverseModular[k]; + reData[p] = rePadded[q] + reBaseline; + imData[p] = imPadded[q] + imBaseline; + p += stride; + } + reData[startIndex] += reSum; + imData[startIndex] += imSum; +} /* end run */ + +/*.................................................................... + DFTPaddedRaderDouble static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static double[][] getConvolverReAndIm ( + final int[] modular, + final int paddedLength +) { + final int prime = modular.length; + final double[] reConvolver = new double[paddedLength]; + final double[] imConvolver = new double[paddedLength]; + final double angularStep = -2.0 * PI / (double)prime; + final double norm = 1.0 / (double)paddedLength; + int n = 0; + for (int k = prime - 2; (1 <= k); k--) { + final double shuffled = (double)modular[k]; + reConvolver[n] = norm * cos(shuffled * angularStep); + imConvolver[n] = norm * sin(shuffled * angularStep); + n++; + } + reConvolver[n] = norm * cos(angularStep); + imConvolver[n] = norm * sin(angularStep); + while (++n < paddedLength) { + reConvolver[n] = reConvolver[n - prime + 1]; + imConvolver[n] = imConvolver[n - prime + 1]; + } + final AcademicFourierTransform fft = new AcademicFourierTransform(paddedLength, 0); + fft.directTransform(reConvolver, imConvolver, null, null, + InputDataType.COMPLEXINPUT); + return(new double[][] { + reConvolver, + imConvolver + }); +} /* end getConvolverReAndIm */ + +} /* end class DFTPaddedRaderDouble */ + +/*==================================================================== +| DFTPaddedRaderFloat +\===================================================================*/ +static class DFTPaddedRaderFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTPaddedRaderFloat */ + +/*.................................................................... + DFTPaddedRaderFloat private variables +....................................................................*/ +private float[] imConvolver; +private float[] reConvolver; +private int[] inverseModular; +private int[] modular; + +/*.................................................................... + DFTPaddedRaderFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTPaddedRaderFloat ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride, + final float[] reConvolver, + final float[] imConvolver, + final int[] modular, + final int[] inverseModular +) { + super(reData, imData, startIndex, stride); + this.reConvolver = reConvolver; + this.imConvolver = imConvolver; + this.modular = modular; + this.inverseModular = inverseModular; +} /* end DFTPaddedRaderFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int prime = modular.length; + final int paddedLength = reConvolver.length; +//;IJ.log("DFTPaddedRaderFloat " + prime + " (" + paddedLength +")"); + final float[] rePadded = new float[paddedLength]; + final float[] imPadded = new float[paddedLength]; + final float[] reBuffer = new float[paddedLength]; + final float[] imBuffer = new float[paddedLength]; + final float reBaseline = reData[startIndex]; + final float imBaseline = imData[startIndex]; + for (int k = paddedLength - prime + 1, m = 1; (k < paddedLength); k++) { + final int q = startIndex + modular[m++] * stride; + rePadded[k] = reData[q]; + imPadded[k] = imData[q]; + } + final AcademicFourierTransform fft = new AcademicFourierTransform(paddedLength, 0); + fft.directTransform(rePadded, imPadded, reBuffer, imBuffer, + InputDataType.COMPLEXINPUT); + final float reSum = rePadded[0]; + final float imSum = imPadded[0]; + for (int k = 0; (k < paddedLength); k++) { + final float re = rePadded[k]; + final float im = imPadded[k]; + final float reWeight = reConvolver[k]; + final float imWeight = imConvolver[k]; + rePadded[k] = re * reWeight - im * imWeight; + imPadded[k] = re * imWeight + im * reWeight; + } + fft.directTransform(rePadded, imPadded, reBuffer, imBuffer, + InputDataType.COMPLEXINPUT); + int p = startIndex + stride; + for (int k = 1; (k < prime); k++) { + final int q = inverseModular[k]; + reData[p] = rePadded[q] + reBaseline; + imData[p] = imPadded[q] + imBaseline; + p += stride; + } + reData[startIndex] += reSum; + imData[startIndex] += imSum; +} /* end run */ + +/*.................................................................... + DFTPaddedRaderFloat static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static float[][] getConvolverReAndIm ( + final int[] modular, + final int paddedLength +) { + final int prime = modular.length; + final float[] reConvolver = new float[paddedLength]; + final float[] imConvolver = new float[paddedLength]; + final float angularStep = -2.0F * (float)PI / (float)prime; + final float norm = 1.0F / (float)paddedLength; + int n = 0; + for (int k = prime - 2; (1 <= k); k--) { + final float shuffled = (float)modular[k]; + reConvolver[n] = norm * (float)cos((double)(shuffled * angularStep)); + imConvolver[n] = norm * (float)sin((double)(shuffled * angularStep)); + n++; + } + reConvolver[n] = norm * (float)cos((double)angularStep); + imConvolver[n] = norm * (float)sin((double)angularStep); + while (++n < paddedLength) { + reConvolver[n] = reConvolver[n - prime + 1]; + imConvolver[n] = imConvolver[n - prime + 1]; + } + final AcademicFourierTransform fft = new AcademicFourierTransform(paddedLength, 0); + fft.directTransform(reConvolver, imConvolver, null, null, + InputDataType.COMPLEXINPUT); + return(new float[][] { + reConvolver, + imConvolver + }); +} /* end getConvolverReAndIm */ + +} /* end class DFTPaddedRaderFloat */ + +/*==================================================================== +| DFTPaddedRaderReal +\===================================================================*/ +static class DFTPaddedRaderReal + +{ /* begin class DFTPaddedRaderReal */ + +/*.................................................................... + DFTPaddedRaderReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int prime, + final int paddedLength +) { + if (FFTSetup.taboos.contains(new Integer(paddedLength))) { + return(-1L); + } + final long K = (long)prime; + final long k = K >> 1L; + final long P = (long)paddedLength; + return(FFTSetup.FLALLOC * (P * 4L + 6L) + + FFTSetup.FLOP * (P * 6L + k * 1L + 1L) + + FFTSetup.FLASSIGN * (P * 4L + 1L + (K - 1L) * 1L + 1L + P * 6L + + k * 2L + 2L) + + FFTSetup.INTALLOC * 8L + + FFTSetup.INTOP * (4L + (K - 1L) * 5L + P * 2L + 1L + k * 3L) + + FFTSetup.INTASSIGN * (5L + (K - 1L) * 2L + 1L + P * 1L + 1L + + k * 3L) + + FFTSetup.IDX * (1L + (K - 1L) * 3L + 1L + P * 6L + k * 5L + 2L) + + 1L * (FFTSetup.NEWOBJ + + FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * 0L + + FFTSetup.FLASSIGN * 0L + + FFTSetup.INTALLOC * 0L + + FFTSetup.INTOP * 1L + + FFTSetup.INTASSIGN * 6L + + FFTSetup.IDX * 0L + + FFTSetup.NEWOBJ * 6L) + + 1L * (FFTSetupReal.cost(paddedLength) + + FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * (k * 1L) + + FFTSetup.FLASSIGN * (k * 2L) + + FFTSetup.INTALLOC * 2L + + FFTSetup.INTOP * (10L + 2L + 1L + k * 3L) + + FFTSetup.INTASSIGN * (2L + k * 2L) + + FFTSetup.IDX * (k * 4L) + + FFTSetup.NEWOBJ * 1L) + + 1L * (FFTSetup.cost(paddedLength) + + FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * 0L + + FFTSetup.FLASSIGN * 0L + + FFTSetup.INTALLOC * 0L + + FFTSetup.INTOP * (10L + 2L) + + FFTSetup.INTASSIGN * 0L + + FFTSetup.IDX * 0L + + FFTSetup.NEWOBJ * 1L) + ); +} /* end cost */ + +} /* end class DFTPaddedRaderReal */ + +/*==================================================================== +| DFTPaddedRaderRealDouble +\===================================================================*/ +static class DFTPaddedRaderRealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTPaddedRaderRealDouble */ + +/*.................................................................... + DFTPaddedRaderRealDouble private variables +....................................................................*/ +private double[] imConvolver; +private double[] reConvolver; +private int[] inverseModular; +private int[] modular; + +/*.................................................................... + DFTPaddedRaderRealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTPaddedRaderRealDouble ( + final double[] reData, + final double[] imData, + final int startIndex, + final int stride, + final double[] reConvolver, + final double[] imConvolver, + final int[] modular, + final int[] inverseModular +) { + super(reData, imData, startIndex, stride); + this.reConvolver = reConvolver; + this.imConvolver = imConvolver; + this.modular = modular; + this.inverseModular = inverseModular; +} /* end DFTPaddedRaderRealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int prime = modular.length; + final int halfPrime = (prime >> 1) + 1; + final int paddedLength = reConvolver.length; +//;IJ.log("DFTPaddedRaderRealDouble " + prime + " (" + paddedLength +")"); + final double[] rePadded = new double[paddedLength]; + final double[] imPadded = new double[paddedLength]; + final double[] reBuffer = new double[paddedLength]; + final double[] imBuffer = new double[paddedLength]; + final double reBaseline = reData[startIndex]; + for (int k = paddedLength - prime + 1, m = 1; (k < paddedLength); k++) { + rePadded[k] = reData[startIndex + modular[m++] * stride]; + } + final AcademicFourierTransform fft = new AcademicFourierTransform(paddedLength, 0); + fft.directTransform(rePadded, imPadded, reBuffer, imBuffer, + InputDataType.REALINPUT); + final double reSum = rePadded[0]; + for (int k = 0; (k < paddedLength); k++) { + final double re = rePadded[k]; + final double im = imPadded[k]; + final double reWeight = reConvolver[k]; + final double imWeight = imConvolver[k]; + rePadded[k] = re * reWeight - im * imWeight; + imPadded[k] = re * imWeight + im * reWeight; + } + fft.directTransform(rePadded, imPadded, reBuffer, imBuffer, + InputDataType.COMPLEXINPUT); + int p = startIndex + stride; + for (int k = 1; (k < halfPrime); k++) { + final int q = inverseModular[k]; + reData[p] = rePadded[q] + reBaseline; + imData[p] = imPadded[q]; + p += stride; + } + reData[startIndex] += reSum; + imData[startIndex] = 0.0; +} /* end run */ + +} /* end class DFTPaddedRaderRealDouble */ + +/*==================================================================== +| DFTPaddedRaderRealFloat +\===================================================================*/ +static class DFTPaddedRaderRealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTPaddedRaderRealFloat */ + +/*.................................................................... + DFTPaddedRaderRealFloat private variables +....................................................................*/ +private float[] imConvolver; +private float[] reConvolver; +private int[] inverseModular; +private int[] modular; + +/*.................................................................... + DFTPaddedRaderRealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTPaddedRaderRealFloat ( + final float[] reData, + final float[] imData, + final int startIndex, + final int stride, + final float[] reConvolver, + final float[] imConvolver, + final int[] modular, + final int[] inverseModular +) { + super(reData, imData, startIndex, stride); + this.reConvolver = reConvolver; + this.imConvolver = imConvolver; + this.modular = modular; + this.inverseModular = inverseModular; +} /* end DFTPaddedRaderRealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int prime = modular.length; + final int halfPrime = (prime >> 1) + 1; + final int paddedLength = reConvolver.length; +//;IJ.log("DFTPaddedRaderRealFloat " + prime + " (" + paddedLength +")"); + final float[] rePadded = new float[paddedLength]; + final float[] imPadded = new float[paddedLength]; + final float[] reBuffer = new float[paddedLength]; + final float[] imBuffer = new float[paddedLength]; + final float reBaseline = reData[startIndex]; + for (int k = paddedLength - prime + 1, m = 1; (k < paddedLength); k++) { + rePadded[k] = reData[startIndex + modular[m++] * stride]; + } + final AcademicFourierTransform fft = new AcademicFourierTransform(paddedLength, 0); + fft.directTransform(rePadded, imPadded, reBuffer, imBuffer, + InputDataType.REALINPUT); + final float reSum = rePadded[0]; + for (int k = 0; (k < paddedLength); k++) { + final float re = rePadded[k]; + final float im = imPadded[k]; + final float reWeight = reConvolver[k]; + final float imWeight = imConvolver[k]; + rePadded[k] = re * reWeight - im * imWeight; + imPadded[k] = re * imWeight + im * reWeight; + } + fft.directTransform(rePadded, imPadded, reBuffer, imBuffer, + InputDataType.COMPLEXINPUT); + int p = startIndex + stride; + for (int k = 1; (k < halfPrime); k++) { + final int q = inverseModular[k]; + reData[p] = rePadded[q] + reBaseline; + imData[p] = imPadded[q]; + p += stride; + } + reData[startIndex] += reSum; + imData[startIndex] = 0.0F; +} /* end run */ + +} /* end class DFTPaddedRaderRealFloat */ + +/*==================================================================== +| DFTRader +\===================================================================*/ +static class DFTRader + +{ /* begin class DFTRader */ + +/*.................................................................... + DFTRader static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int prime +) { + if (FFTSetup.taboos.contains(new Integer(prime)) + || FFTSetup.taboos.contains(new Integer(prime - 1))) { + return(-1L); + } + final long K = (long)prime; + return(FFTSetup.FLALLOC * 6L + + FFTSetup.FLOP * ((K - 1L) * 6L + (K - 1L) * 2L + 2L) + + FFTSetup.FLASSIGN * (2L + (K - 1L) * 2L + 2L + (K - 1L) * 6L + + (K - 1L) * 2L + 2L) + + FFTSetup.INTALLOC * 8L + + FFTSetup.INTOP * (1L + (K - 1L) * 5L + 4L + (K- 1L) * 3L + 2L + + (K - 1L) * 5L) + + FFTSetup.INTASSIGN * (3L + (K - 1L) * 3L + 3L + (K - 1L) * 2L + 2L + + (K - 1L) * 3L) + + FFTSetup.IDX * (2L + (K - 1L) * 5L + 4L + (K - 1L) * 6L + + (K - 1L) * 5L + 4L) + + FFTSetup.NEWOBJ * 2L + + 2L * FFTSetup.cost(prime - 1) + ); +} /* end cost */ + +/*------------------------------------------------------------------*/ +static int[] getInverseModularPowerShuffling ( + final int[] modularShuffling +) { + final int prime = modularShuffling.length; + int[] inverseShuffling = new int[prime]; + inverseShuffling[0] = 0; + inverseShuffling[modularShuffling[prime - 3]] = 1; + inverseShuffling[modularShuffling[prime - 2]] = 2; + inverseShuffling[modularShuffling[prime - 1]] = 3; + for (int k = 4; (k < prime); k++) { + inverseShuffling[modularShuffling[k - 3]] = k; + } + return(inverseShuffling); +} /* end getInverseModularPowerShuffling */ + +/*------------------------------------------------------------------*/ +static int[] getModularPowerShuffling ( + final int prime +) { + final int g = smallestPrimitiveRootOfPrime(prime); + int[] modularShuffling = new int[prime]; + modularShuffling[0] = 0; + for (int k = 1; (k < prime); k++) { + modularShuffling[k] = modularPositivePower(g, k, prime); + } + return(modularShuffling); +} /* end getModularPowerShuffling */ + +/*.................................................................... + DFTRader private methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static private TreeMap<Integer, Integer> factorize ( + int number +) { + final TreeMap<Integer, Integer> factors = + new TreeMap<Integer, Integer>(); + for (int divisor = 2; (divisor <= number); divisor++) { + if ((divisor * (number / divisor)) == number) { + number /= divisor; + int multiplicity = 1; + while ((divisor * (number / divisor)) == number) { + number /= divisor; + multiplicity++; + } + factors.put(new Integer(divisor), new Integer(multiplicity)); + } + } + return(factors); +} /* end factorize */ + +/*------------------------------------------------------------------*/ +static private int modularPositivePower ( + int number, + int exponent, + final int modulo +) { + int result = 1; + number -= modulo * (number / modulo); + while (0 < exponent) { + if (1 == (exponent & 1)) { + result *= number; + result -= modulo * (result / modulo); + } + exponent >>= 1; + number *= number; + number -= modulo * (number / modulo); + } + return(result); +} /* end modularPositivePower */ + +/*------------------------------------------------------------------*/ +static private int smallestPrimitiveRootOfPrime ( + final int prime +) { + if (2 == prime) { + return(1); + } + final TreeMap<Integer, Integer> factors = factorize(prime - 1); + int result = -1; + for (int candidate = 1; (candidate < prime); candidate++) { + result = candidate; + for (Integer primeDivisor: factors.navigableKeySet()) { + if (1 == modularPositivePower(candidate, (prime - 1) + / primeDivisor.intValue(), prime)) { + result = -1; + break; + } + } + if (0 < result) { + break; + } + } + return(result); +} /* end smallestPrimitiveRootOfPrime */ + +} /* end class DFTRader */ + +/*==================================================================== +| DFTRaderDouble +\===================================================================*/ +static class DFTRaderDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTRaderDouble */ + +/*.................................................................... + DFTRaderDouble private variables +....................................................................*/ +private double[] imBuffer; +private double[] imConvolver; +private double[] reBuffer; +private double[] reConvolver; +private int[] inverseModular; +private int[] modular; + +/*.................................................................... + DFTRaderDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTRaderDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reConvolver, + final double[] imConvolver, + final int[] modular, + final int[] inverseModular +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reConvolver = reConvolver; + this.imConvolver = imConvolver; + this.modular = modular; + this.inverseModular = inverseModular; +} /* end DFTRaderDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int prime = modular.length; +//;IJ.log("DFTRaderDouble " + prime); + final double reBaseline = reData[startIndex]; + final double imBaseline = imData[startIndex]; + int p = startIndex + stride; + for (int k = 1; (k < prime); k++) { + final int q = startIndex + modular[k] * stride; + reBuffer[p] = reData[q]; + imBuffer[p] = imData[q]; + p += stride; + } + final FFTSetup fft = FFTSetup.transforms.get(new Integer(prime - 1)); + p = startIndex + stride; + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble, + fft.K1).run(); + break; + } + case PADDEDRADER: { + throw(new IllegalStateException()); + } + case RADER: { + throw(new IllegalStateException()); + } + case RADIX2: { + new DFTRadix2Double(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + reBuffer[startIndex] = reBuffer[p]; + imBuffer[startIndex] = imBuffer[p]; + for (int k = 0, K = prime - 1; (k < K); k++) { + final double re = reBuffer[p]; + final double im = imBuffer[p]; + final double reWeight = reConvolver[k]; + final double imWeight = imConvolver[k]; + reBuffer[p] = re * reWeight - im * imWeight; + imBuffer[p] = re * imWeight + im * reWeight; + p += stride; + } + p = startIndex + stride; + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble, + fft.K1).run(); + break; + } + case PADDEDRADER: { + throw(new IllegalStateException()); + } + case RADER: { + throw(new IllegalStateException()); + } + case RADIX2: { + new DFTRadix2Double(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + for (int k = 1; (k < prime); k++) { + final int q = startIndex + inverseModular[k] * stride; + reData[p] = reBuffer[q] + reBaseline; + imData[p] = imBuffer[q] + imBaseline; + p += stride; + } + reData[startIndex] += reBuffer[startIndex]; + imData[startIndex] += imBuffer[startIndex]; +} /* end run */ + +/*.................................................................... + DFTRaderDouble static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static double[][] getConvolverReAndIm ( + final int[] modular +) { + final int prime = modular.length; + final double[] reConvolver = new double[prime - 1]; + final double[] imConvolver = new double[prime - 1]; + final double angularStep = -2.0 * PI / (double)prime; + final double norm = 1.0 / (double)(prime - 1); + int n = 0; + for (int k = prime - 2; (1 <= k); k--) { + final double shuffled = (double)modular[k]; + reConvolver[n] = norm * cos(shuffled * angularStep); + imConvolver[n] = norm * sin(shuffled * angularStep); + n++; + } + reConvolver[n] = norm * cos(angularStep); + imConvolver[n] = norm * sin(angularStep); + final AcademicFourierTransform fft = new AcademicFourierTransform(prime - 1, 0); + fft.directTransform(reConvolver, imConvolver, null, null, + InputDataType.COMPLEXINPUT); + return(new double[][] { + reConvolver, + imConvolver + }); +} /* end getConvolverReAndIm */ + +} /* end class DFTRaderDouble */ + +/*==================================================================== +| DFTRaderFloat +\===================================================================*/ +static class DFTRaderFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTRaderFloat */ + +/*.................................................................... + DFTRaderFloat private variables +....................................................................*/ +private float[] imBuffer; +private float[] imConvolver; +private float[] reBuffer; +private float[] reConvolver; +private int[] inverseModular; +private int[] modular; + +/*.................................................................... + DFTRaderFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTRaderFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reConvolver, + final float[] imConvolver, + final int[] modular, + final int[] inverseModular +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reConvolver = reConvolver; + this.imConvolver = imConvolver; + this.modular = modular; + this.inverseModular = inverseModular; +} /* end DFTRaderFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int prime = modular.length; +//;IJ.log("DFTRaderFloat " + prime); + final float reBaseline = reData[startIndex]; + final float imBaseline = imData[startIndex]; + int p = startIndex + stride; + for (int k = 1; (k < prime); k++) { + final int q = startIndex + modular[k] * stride; + reBuffer[p] = reData[q]; + imBuffer[p] = imData[q]; + p += stride; + } + final FFTSetup fft = FFTSetup.transforms.get(new Integer(prime - 1)); + p = startIndex + stride; + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat, + fft.K1).run(); + break; + } + case PADDEDRADER: { + throw(new IllegalStateException()); + } + case RADER: { + throw(new IllegalStateException()); + } + case RADIX2: { + new DFTRadix2Float(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + reBuffer[startIndex] = reBuffer[p]; + imBuffer[startIndex] = imBuffer[p]; + for (int k = 0, K = prime - 1; (k < K); k++) { + final float re = reBuffer[p]; + final float im = imBuffer[p]; + final float reWeight = reConvolver[k]; + final float imWeight = imConvolver[k]; + reBuffer[p] = re * reWeight - im * imWeight; + imBuffer[p] = re * imWeight + im * reWeight; + p += stride; + } + p = startIndex + stride; + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat, + fft.K1).run(); + break; + } + case PADDEDRADER: { + throw(new IllegalStateException()); + } + case RADER: { + throw(new IllegalStateException()); + } + case RADIX2: { + new DFTRadix2Float(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + for (int k = 1; (k < prime); k++) { + final int q = startIndex + inverseModular[k] * stride; + reData[p] = reBuffer[q] + reBaseline; + imData[p] = imBuffer[q] + imBaseline; + p += stride; + } + reData[startIndex] += reBuffer[startIndex]; + imData[startIndex] += imBuffer[startIndex]; +} /* end run */ + +/*.................................................................... + DFTRaderFloat static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static float[][] getConvolverReAndIm ( + final int[] modular +) { + final int prime = modular.length; + final float[] reConvolver = new float[prime - 1]; + final float[] imConvolver = new float[prime - 1]; + final float angularStep = -2.0F * (float)PI / (float)prime; + final float norm = 1.0F / (float)(prime - 1); + int n = 0; + for (int k = prime - 2; (1 <= k); k--) { + final float shuffled = (float)modular[k]; + reConvolver[n] = norm * (float)cos((double)(shuffled * angularStep)); + imConvolver[n] = norm * (float)sin((double)(shuffled * angularStep)); + n++; + } + reConvolver[n] = norm * (float)cos((double)angularStep); + imConvolver[n] = norm * (float)sin((double)angularStep); + final AcademicFourierTransform fft = new AcademicFourierTransform(prime - 1, 0); + fft.directTransform(reConvolver, imConvolver, null, null, + InputDataType.COMPLEXINPUT); + return(new float[][] { + reConvolver, + imConvolver + }); +} /* end getConvolverReAndIm */ + +} /* end class DFTRaderFloat */ + +/*==================================================================== +| DFTRaderReal +\===================================================================*/ +static class DFTRaderReal + +{ /* begin class DFTRaderReal */ + +/*.................................................................... + DFTRaderReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int prime +) { + if (FFTSetup.taboos.contains(new Integer(prime)) + || FFTSetup.taboos.contains(new Integer(prime - 1))) { + return(-1L); + } + final long K = (long)prime; + final long k = K >> 1L; + return(FFTSetup.FLALLOC * 5L + + FFTSetup.FLOP * (k * 1L + (K - 1L) * 6L + k * 1L + 1L) + + FFTSetup.FLASSIGN * (1L + (K - 1L) * 1L + k * 2L + 1L + (K - 1L) * 6L + + k * 2L + 2L) + + FFTSetup.INTALLOC * 11L + + FFTSetup.INTOP * (3L + (K - 1L) * 5L + 7L + k * 3L + 1L + + (K- 1L) * 3L + 3L + k * 5L) + + FFTSetup.INTASSIGN * (4L + (K - 1L) * 3L + 3L + k * 2L + 2L + + (K - 1L) * 2L + 2L + k * 3L) + + FFTSetup.IDX * (1L + (K - 1L) * 3L + k * 4L + 2L + (K - 1L) * 6L + + k * 5L + 3L) + + FFTSetup.NEWOBJ * 2L + + FFTSetupReal.cost(prime - 1) + FFTSetup.cost(prime - 1) + ); +} /* end cost */ + +} /* end class DFTRaderReal */ + +/*==================================================================== +| DFTRaderRealDouble +\===================================================================*/ +static class DFTRaderRealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTRaderRealDouble */ + +/*.................................................................... + DFTRaderRealDouble private variables +....................................................................*/ +private double[] imBuffer; +private double[] imConvolver; +private double[] reBuffer; +private double[] reConvolver; +private int[] inverseModular; +private int[] modular; + +/*.................................................................... + DFTRaderRealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTRaderRealDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reConvolver, + final double[] imConvolver, + final int[] modular, + final int[] inverseModular +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reConvolver = reConvolver; + this.imConvolver = imConvolver; + this.modular = modular; + this.inverseModular = inverseModular; +} /* end DFTRaderRealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int prime = modular.length; + final int halfPrime = (prime >> 1) + 1; +//;IJ.log("DFTRaderRealDouble " + prime); + final double reBaseline = reData[startIndex]; + int p = startIndex + stride; + for (int k = 1; (k < prime); k++) { + final int q = startIndex + modular[k] * stride; + reBuffer[p] = reData[q]; + p += stride; + } + final FFTSetupReal fftReal = + FFTSetupReal.transforms.get(new Integer(prime - 1)); + p = startIndex + stride; + switch (fftReal.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootDouble, fftReal.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.ruritanian, fftReal.chinese, fftReal.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootDouble, fftReal.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2RealDouble(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4RealDouble(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6RealDouble(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reBuffer, imBuffer, p, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootDouble, fftReal.imUnitRootDouble, + fftReal.K1).run(); + break; + } + case PADDEDRADER: { + throw(new IllegalStateException()); + } + case RADER: { + throw(new IllegalStateException()); + } + case RADIX2: { + new DFTRadix2RealDouble(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootEvenDouble, fftReal.imUnitRootEvenDouble, + fftReal.reUnitRootOddDouble, fftReal.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootDouble, fftReal.imUnitRootDouble).run(); + break; + } + } + int progressive = p + stride; + int regressive = p + (prime - 2) * stride; + while (progressive < regressive) { + reBuffer[regressive] = reBuffer[progressive]; + imBuffer[regressive] = -imBuffer[progressive]; + progressive += stride; + regressive -= stride; + } + reBuffer[startIndex] = reBuffer[p]; + for (int k = 0, K = prime - 1; (k < K); k++) { + final double re = reBuffer[p]; + final double im = imBuffer[p]; + final double reWeight = reConvolver[k]; + final double imWeight = imConvolver[k]; + reBuffer[p] = re * reWeight - im * imWeight; + imBuffer[p] = re * imWeight + im * reWeight; + p += stride; + } + p = startIndex + stride; + final FFTSetup fft = FFTSetup.transforms.get(new Integer(prime - 1)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Double(reBuffer, imBuffer, p, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble, + fft.K1).run(); + break; + } + case PADDEDRADER: { + throw(new IllegalStateException()); + } + case RADER: { + throw(new IllegalStateException()); + } + case RADIX2: { + new DFTRadix2Double(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixDouble(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + for (int k = 1; (k < halfPrime); k++) { + final int q = startIndex + inverseModular[k] * stride; + reData[p] = reBuffer[q] + reBaseline; + imData[p] = imBuffer[q]; + p += stride; + } + reData[startIndex] += reBuffer[startIndex]; + imData[startIndex] = 0.0; +} /* end run */ + +} /* end class DFTRaderRealDouble */ + +/*==================================================================== +| DFTRaderRealFloat +\===================================================================*/ +static class DFTRaderRealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTRaderRealFloat */ + +/*.................................................................... + DFTRaderRealFloat private variables +....................................................................*/ +private float[] imBuffer; +private float[] imConvolver; +private float[] reBuffer; +private float[] reConvolver; +private int[] inverseModular; +private int[] modular; + +/*.................................................................... + DFTRaderRealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTRaderRealFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reConvolver, + final float[] imConvolver, + final int[] modular, + final int[] inverseModular +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reConvolver = reConvolver; + this.imConvolver = imConvolver; + this.modular = modular; + this.inverseModular = inverseModular; +} /* end DFTRaderRealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int prime = modular.length; + final int halfPrime = (prime >> 1) + 1; +//;IJ.log("DFTRaderRealFloat " + prime); + final float reBaseline = reData[startIndex]; + int p = startIndex + stride; + for (int k = 1; (k < prime); k++) { + final int q = startIndex + modular[k] * stride; + reBuffer[p] = reData[q]; + p += stride; + } + final FFTSetupReal fftReal = + FFTSetupReal.transforms.get(new Integer(prime - 1)); + p = startIndex + stride; + switch (fftReal.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootFloat, fftReal.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.ruritanian, fftReal.chinese, fftReal.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootFloat, fftReal.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2RealFloat(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4RealFloat(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6RealFloat(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reBuffer, imBuffer, p, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootFloat, fftReal.imUnitRootFloat, + fftReal.K1).run(); + break; + } + case PADDEDRADER: { + throw(new IllegalStateException()); + } + case RADER: { + throw(new IllegalStateException()); + } + case RADIX2: { + new DFTRadix2RealFloat(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootEvenFloat, fftReal.imUnitRootEvenFloat, + fftReal.reUnitRootOddFloat, fftReal.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reBuffer, imBuffer, reData, imData, + p, stride, + fftReal.reUnitRootFloat, fftReal.imUnitRootFloat).run(); + break; + } + } + int progressive = p + stride; + int regressive = p + (prime - 2) * stride; + while (progressive < regressive) { + reBuffer[regressive] = reBuffer[progressive]; + imBuffer[regressive] = -imBuffer[progressive]; + progressive += stride; + regressive -= stride; + } + reBuffer[startIndex] = reBuffer[p]; + for (int k = 0, K = prime - 1; (k < K); k++) { + final float re = reBuffer[p]; + final float im = imBuffer[p]; + final float reWeight = reConvolver[k]; + final float imWeight = imConvolver[k]; + reBuffer[p] = re * reWeight - im * imWeight; + imBuffer[p] = re * imWeight + im * reWeight; + p += stride; + } + p = startIndex + stride; + final FFTSetup fft = FFTSetup.transforms.get(new Integer(prime - 1)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case LENGTH8: { + new DFTLength8Float(reBuffer, imBuffer, p, stride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat, + fft.K1).run(); + break; + } + case PADDEDRADER: { + throw(new IllegalStateException()); + } + case RADER: { + throw(new IllegalStateException()); + } + case RADIX2: { + new DFTRadix2Float(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixFloat(reBuffer, imBuffer, reData, imData, + p, stride, fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + for (int k = 1; (k < halfPrime); k++) { + final int q = startIndex + inverseModular[k] * stride; + reData[p] = reBuffer[q] + reBaseline; + imData[p] = imBuffer[q]; + p += stride; + } + reData[startIndex] += reBuffer[startIndex]; + imData[startIndex] = 0.0F; +} /* end run */ + +} /* end class DFTRaderRealFloat */ + +/*==================================================================== +| DFTRadix2 +\===================================================================*/ +static class DFTRadix2 + +{ /* begin class DFTRadix2 */ + +/*.................................................................... + DFTRadix2 static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (FFTSetup.taboos.contains(new Integer(transformLength / 2))) { + return(-1L); + } + final long k = (long)(transformLength >> 1); + return(FFTSetup.FLALLOC * 4L + + FFTSetup.FLOP * (k * 6L + k * 4L) + + FFTSetup.FLASSIGN * (k * 4L + k * 8L + k * 4L) + + FFTSetup.INTALLOC * 8L + + FFTSetup.INTOP * (5L + k * 6L + k * 5L + k * 4L) + + FFTSetup.INTASSIGN * (6L + k * 5L + 2L + k * 4L + 1L + k * 3L) + + FFTSetup.IDX * (k * 8L + k * 10L + k * 4L) + + FFTSetup.NEWOBJ * 2L + + 2L * FFTSetup.cost(transformLength / 2) + ); +} /* end cost */ + +} /* end class DFTRadix2 */ + +/*==================================================================== +| DFTRadix2Double +\===================================================================*/ +static class DFTRadix2Double + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTRadix2Double */ + +/*.................................................................... + DFTRadix2Double static variables +....................................................................*/ +private double[] imBuffer; +private double[] imUnitRoot; +private double[] reBuffer; +private double[] reUnitRoot; + +/*.................................................................... + DFTRadix2Double constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTRadix2Double ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reUnitRoot, + final double[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTRadix2Double */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int K2 = reUnitRoot.length; +//;IJ.log("DFTRadix2Double " + (2 * K2)); + final int doubleStride = stride << 1; + final FFTSetup fft = FFTSetup.transforms.get(new Integer(K2)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + new DFTBruteForceDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.ruritanian, fft.chinese, fft.K1).run(); + new DFTCoprimeFactorDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Double(reData, imData, + startIndex, doubleStride).run(); + new DFTLength2Double(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH3: { + new DFTLength3Double(reData, imData, + startIndex, doubleStride).run(); + new DFTLength3Double(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH4: { + new DFTLength4Double(reData, imData, + startIndex, doubleStride).run(); + new DFTLength4Double(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH5: { + new DFTLength5Double(reData, imData, + startIndex, doubleStride).run(); + new DFTLength5Double(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH6: { + new DFTLength6Double(reData, imData, + startIndex, doubleStride).run(); + new DFTLength6Double(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8Double(reData, imData, + startIndex, doubleStride).run(); + new DFTLength8Double(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble, + fft.K1).run(); + new DFTMixedRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble, + fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderDouble(reData, imData, + startIndex, doubleStride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + new DFTPaddedRaderDouble(reData, imData, + startIndex + stride, doubleStride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + new DFTRaderDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Double(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + new DFTRadix2Double(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + new DFTSplitRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + int m0 = startIndex; + int i0 = startIndex; + int i1 = startIndex + K2 * stride; + for (int m = 0; (m < K2); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += stride; + reBuffer[i1] = reData[m0]; + imBuffer[i1] = imData[m0]; + m0 += stride; + i0 += stride; + i1 += stride; + } + m0 = K2; + for (int m = 0; (m < K2); m++) { + m0--; + i1 -= stride; + i0 -= stride; + reData[i0] = reBuffer[i0]; + imData[i0] = imBuffer[i0]; + final double re = reBuffer[i1]; + final double im = imBuffer[i1]; + final double reRoot = reUnitRoot[m0]; + final double imRoot = imUnitRoot[m0]; + reData[i1] = re * reRoot - im * imRoot; + imData[i1] = re * imRoot + im * reRoot; + } + for (int m = 0; (m < K2); m++) { + reData[i0] -= reData[i1]; + imData[i0] -= imData[i1]; + reData[i1] += reBuffer[i0]; + imData[i1] += imBuffer[i0]; + i0 += stride; + i1 += stride; + } +} /* end run */ + +/*.................................................................... + DFTRadix2Double static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static double[] getImUnitRoot ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final double[] imUnitRoot = new double[halfTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + imUnitRoot[k] = sin((double)(halfTransformLength + k) * angularStep); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static double[] getReUnitRoot ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final double[] reUnitRoot = new double[halfTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + reUnitRoot[k] = cos((double)(halfTransformLength + k) * angularStep); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTRadix2Double */ + +/*==================================================================== +| DFTRadix2Float +\===================================================================*/ +static class DFTRadix2Float + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTRadix2Float */ + +/*.................................................................... + DFTRadix2Float static variables +....................................................................*/ +private float[] imBuffer; +private float[] imUnitRoot; +private float[] reBuffer; +private float[] reUnitRoot; + +/*.................................................................... + DFTRadix2Float constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTRadix2Float ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reUnitRoot, + final float[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTRadix2Float */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int K2 = reUnitRoot.length; +//;IJ.log("DFTRadix2Float " + (2 * K2)); + final int doubleStride = stride << 1; + final FFTSetup fft = FFTSetup.transforms.get(new Integer(K2)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + new DFTBruteForceFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.ruritanian, fft.chinese, + fft.K1).run(); + new DFTCoprimeFactorFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.ruritanian, fft.chinese, + fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Float(reData, imData, + startIndex, doubleStride).run(); + new DFTLength2Float(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH3: { + new DFTLength3Float(reData, imData, + startIndex, doubleStride).run(); + new DFTLength3Float(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH4: { + new DFTLength4Float(reData, imData, + startIndex, doubleStride).run(); + new DFTLength4Float(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH5: { + new DFTLength5Float(reData, imData, + startIndex, doubleStride).run(); + new DFTLength5Float(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH6: { + new DFTLength6Float(reData, imData, + startIndex, doubleStride).run(); + new DFTLength6Float(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8Float(reData, imData, + startIndex, doubleStride).run(); + new DFTLength8Float(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat, + fft.K1).run(); + new DFTMixedRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat, + fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderFloat(reData, imData, + startIndex, doubleStride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + new DFTPaddedRaderFloat(reData, imData, + startIndex + stride, doubleStride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + new DFTRaderFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Float(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + new DFTRadix2Float(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + new DFTSplitRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + int m0 = startIndex; + int i0 = startIndex; + int i1 = startIndex + K2 * stride; + for (int m = 0; (m < K2); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += stride; + reBuffer[i1] = reData[m0]; + imBuffer[i1] = imData[m0]; + m0 += stride; + i0 += stride; + i1 += stride; + } + m0 = K2; + for (int m = 0; (m < K2); m++) { + m0--; + i1 -= stride; + i0 -= stride; + reData[i0] = reBuffer[i0]; + imData[i0] = imBuffer[i0]; + final float re = reBuffer[i1]; + final float im = imBuffer[i1]; + final float reRoot = reUnitRoot[m0]; + final float imRoot = imUnitRoot[m0]; + reData[i1] = re * reRoot - im * imRoot; + imData[i1] = re * imRoot + im * reRoot; + } + for (int m = 0; (m < K2); m++) { + reData[i0] -= reData[i1]; + imData[i0] -= imData[i1]; + reData[i1] += reBuffer[i0]; + imData[i1] += imBuffer[i0]; + i0 += stride; + i1 += stride; + } +} /* end run */ + +/*.................................................................... + DFTRadix2Float static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static float[] getImUnitRoot ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final float[] imUnitRoot = new float[halfTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + imUnitRoot[k] = (float)sin((double)((float)(halfTransformLength + k) + * angularStep)); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static float[] getReUnitRoot ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final float[] reUnitRoot = new float[halfTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + reUnitRoot[k] = (float)cos((double)((float)(halfTransformLength + k) + * angularStep)); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTRadix2Float */ + +/*==================================================================== +| DFTRadix2Real +\===================================================================*/ +static class DFTRadix2Real + +{ /* begin class DFTRadix2Real */ + +/*.................................................................... + DFTRadix2Real static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (FFTSetup.taboos.contains(new Integer(transformLength / 2))) { + return(-1L); + } + final long k2 = (long)(transformLength >> 2); + return(FFTSetup.FLALLOC * 8L + + FFTSetup.FLOP * (1L + k2 * 8L + k2 * 9L + 1L) + + FFTSetup.FLASSIGN * ((k2 + 1L) * 4L + 2L + k2 * 6L + k2 * 6L + 2L) + + FFTSetup.INTALLOC * 9L + + FFTSetup.INTOP * (6L + (k2 + 1L) * 6L + 6L + k2 * 4L + 2L + k2 * 5L) + + FFTSetup.INTASSIGN * (7L + (k2 + 1L) * 5L + 4L + k2 * 3L + 4L + + k2 * 4L) + + FFTSetup.IDX * ((k2 + 1L) * 8L + 4L + k2 * 8L + k2 * 8L + 4L) + + FFTSetup.NEWOBJ * 2L + + FFTSetupDuoReal.cost(transformLength / 2) + ); +} /* end cost */ + +} /* end class DFTRadix2Real */ + +/*==================================================================== +| DFTRadix2RealDouble +\===================================================================*/ +static class DFTRadix2RealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTRadix2RealDouble */ + +/*.................................................................... + DFTRadix2RealDouble static variables +....................................................................*/ +private double[] imBuffer; +private double[] imUnitRootEven; +private double[] imUnitRootOdd; +private double[] reBuffer; +private double[] reUnitRootEven; +private double[] reUnitRootOdd; + +/*.................................................................... + DFTRadix2RealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTRadix2RealDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reUnitRootEven, + final double[] imUnitRootEven, + final double[] reUnitRootOdd, + final double[] imUnitRootOdd +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRootEven = reUnitRootEven; + this.imUnitRootEven = imUnitRootEven; + this.reUnitRootOdd = reUnitRootOdd; + this.imUnitRootOdd = imUnitRootOdd; +} /* end DFTRadix2RealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int K2 = reUnitRootEven.length; +//;IJ.log("DFTRadix2RealDouble " + (2 * K2)); + final int K4 = K2 >> 1; + final int doubleStride = stride << 1; + final FFTSetupDuoReal fft = + FFTSetupDuoReal.transforms.get(new Integer(K2)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + new DFTBruteForceRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.ruritanian, fft.chinese, fft.K1).run(); + new DFTCoprimeFactorRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + new DFTDuoRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, startIndex + stride, doubleStride, K2).run(); + break; + } + case EVENREAL: { + new DFTEvenRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + new DFTEvenRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + imData[startIndex] = 0.0; + imData[startIndex + stride] = 0.0; + break; + } + case LENGTH2: { + new DFTLength2RealDouble(reData, imData, + startIndex, doubleStride).run(); + new DFTLength2RealDouble(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble(reData, imData, + startIndex, doubleStride).run(); + new DFTLength3RealDouble(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble(reData, imData, + startIndex, doubleStride).run(); + new DFTLength4RealDouble(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble(reData, imData, + startIndex, doubleStride).run(); + new DFTLength5RealDouble(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble(reData, imData, + startIndex, doubleStride).run(); + new DFTLength6RealDouble(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reData, imData, + startIndex, doubleStride).run(); + new DFTLength8RealDouble(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble, + fft.K1).run(); + new DFTMixedRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble, + fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reData, imData, + startIndex, doubleStride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + new DFTPaddedRaderRealDouble(reData, imData, + startIndex + stride, doubleStride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + new DFTRaderRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootEvenDouble, fft.imUnitRootEvenDouble, + fft.reUnitRootOddDouble, fft.imUnitRootOddDouble).run(); + new DFTRadix2RealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootEvenDouble, fft.imUnitRootEvenDouble, + fft.reUnitRootOddDouble, fft.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + new DFTSplitRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + int m0 = startIndex; + int i0 = startIndex; + int i1 = startIndex + K2 * stride; + for (int m = 0; (m <= K4); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += stride; + reBuffer[i1] = reData[m0]; + imBuffer[i1] = imData[m0]; + m0 += stride; + i0 += stride; + i1 += stride; + } + i1 = startIndex + K2 * stride; + reData[startIndex] = reBuffer[startIndex] + reBuffer[i1]; + imData[startIndex] = 0.0; + i0 = startIndex + stride; + i1 += stride; + if (0 == (K2 & 1)) { + for (int m = 1; (m < K4); m++) { + final double re = reBuffer[i1]; + final double im = imBuffer[i1]; + final double reRoot = reUnitRootEven[m]; + final double imRoot = imUnitRootEven[m]; + reData[i0] = reBuffer[i0] + re * reRoot - im * imRoot; + imData[i0] = imBuffer[i0] + re * imRoot + im * reRoot; + i0 += stride; + i1 += stride; + } + reData[i0] = reBuffer[i0]; + imData[i0] = -reBuffer[i1]; + m0 = i0 + stride; + i0 -= stride; + i1 -= stride; + for (int m = 1; (m < K4); m++) { + final double re = imBuffer[i1]; + final double im = reBuffer[i1]; + final double reRoot = reUnitRootEven[m]; + final double imRoot = imUnitRootEven[m]; + reData[m0] = reBuffer[i0] - re * reRoot + im * imRoot; + imData[m0] = -imBuffer[i0] - re * imRoot - im * reRoot; + m0 += stride; + i0 -= stride; + i1 -= stride; + } + } + else { + for (int m = 1; (m <= K4); m++) { + final double re = reBuffer[i1]; + final double im = imBuffer[i1]; + final double reRoot = reUnitRootEven[m]; + final double imRoot = imUnitRootEven[m]; + reData[i0] = reBuffer[i0] + re * reRoot - im * imRoot; + imData[i0] = imBuffer[i0] + re * imRoot + im * reRoot; + i0 += stride; + i1 += stride; + } + m0 = i0; + i0 -= stride; + i1 -= stride; + for (int m = 0; (m < K4); m++) { + final double re = imBuffer[i1]; + final double im = reBuffer[i1]; + final double reRoot = reUnitRootOdd[m]; + final double imRoot = imUnitRootOdd[m]; + reData[m0] = reBuffer[i0] - re * reRoot + im * imRoot; + imData[m0] = -imBuffer[i0] - re * imRoot - im * reRoot; + i0 -= stride; + i1 -= stride; + m0 += stride; + } + } + reData[m0] = reBuffer[i0] - reBuffer[i1]; + imData[m0] = 0.0; +} /* end run */ + +/*.................................................................... + DFTRadix2RealDouble static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static double[] getImUnitRootEven ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final double[] imUnitRoot = new double[halfTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + imUnitRoot[k] = sin((double)k * angularStep); + } + return(imUnitRoot); +} /* end getImUnitRootEven */ + +/*------------------------------------------------------------------*/ +static double[] getReUnitRootEven ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final double[] reUnitRoot = new double[halfTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + reUnitRoot[k] = cos((double)k * angularStep); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +/*------------------------------------------------------------------*/ +static double[] getImUnitRootOdd ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final double[] imUnitRoot = new double[halfTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + imUnitRoot[k] = sin(((double)k + 0.5) * angularStep); + } + return(imUnitRoot); +} /* end getImUnitRootOdd */ + +/*------------------------------------------------------------------*/ +static double[] getReUnitRootOdd ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final double[] reUnitRoot = new double[halfTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + reUnitRoot[k] = cos(((double)k + 0.5) * angularStep); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class getReUnitRootOdd */ + +/*==================================================================== +| DFTRadix2RealFloat +\===================================================================*/ +static class DFTRadix2RealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTRadix2RealFloat */ + +/*.................................................................... + DFTRadix2RealFloat static variables +....................................................................*/ +private float[] imBuffer; +private float[] imUnitRootEven; +private float[] imUnitRootOdd; +private float[] reBuffer; +private float[] reUnitRootEven; +private float[] reUnitRootOdd; + +/*.................................................................... + DFTRadix2RealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTRadix2RealFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reUnitRootEven, + final float[] imUnitRootEven, + final float[] reUnitRootOdd, + final float[] imUnitRootOdd +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRootEven = reUnitRootEven; + this.imUnitRootEven = imUnitRootEven; + this.reUnitRootOdd = reUnitRootOdd; + this.imUnitRootOdd = imUnitRootOdd; +} /* end DFTRadix2RealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int K2 = reUnitRootEven.length; +//;IJ.log("DFTRadix2RealFloat " + (2 * K2)); + final int K4 = K2 >> 1; + final int doubleStride = stride << 1; + final FFTSetupDuoReal fft = + FFTSetupDuoReal.transforms.get(new Integer(K2)); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + new DFTBruteForceRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.ruritanian, fft.chinese, fft.K1).run(); + new DFTCoprimeFactorRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + new DFTDuoRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, startIndex + stride, doubleStride, K2).run(); + break; + } + case EVENREAL: { + new DFTEvenRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + new DFTEvenRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + imData[startIndex] = 0.0F; + imData[startIndex + stride] = 0.0F; + break; + } + case LENGTH2: { + new DFTLength2RealFloat(reData, imData, + startIndex, doubleStride).run(); + new DFTLength2RealFloat(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reData, imData, + startIndex, doubleStride).run(); + new DFTLength3RealFloat(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reData, imData, + startIndex, doubleStride).run(); + new DFTLength4RealFloat(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reData, imData, + startIndex, doubleStride).run(); + new DFTLength5RealFloat(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reData, imData, + startIndex, doubleStride).run(); + new DFTLength6RealFloat(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reData, imData, + startIndex, doubleStride).run(); + new DFTLength8RealFloat(reData, imData, + startIndex + stride, doubleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat, + fft.K1).run(); + new DFTMixedRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat, + fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reData, imData, + startIndex, doubleStride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + new DFTPaddedRaderRealFloat(reData, imData, + startIndex + stride, doubleStride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + new DFTRaderRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootEvenFloat, fft.imUnitRootEvenFloat, + fft.reUnitRootOddFloat, fft.imUnitRootOddFloat).run(); + new DFTRadix2RealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootEvenFloat, fft.imUnitRootEvenFloat, + fft.reUnitRootOddFloat, fft.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + new DFTSplitRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, doubleStride, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + int m0 = startIndex; + int i0 = startIndex; + int i1 = startIndex + K2 * stride; + for (int m = 0; (m <= K4); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += stride; + reBuffer[i1] = reData[m0]; + imBuffer[i1] = imData[m0]; + m0 += stride; + i0 += stride; + i1 += stride; + } + i1 = startIndex + K2 * stride; + reData[startIndex] = reBuffer[startIndex] + reBuffer[i1]; + imData[startIndex] = 0.0F; + i0 = startIndex + stride; + i1 += stride; + if (0 == (K2 & 1)) { + for (int m = 1; (m < K4); m++) { + final float re = reBuffer[i1]; + final float im = imBuffer[i1]; + final float reRoot = reUnitRootEven[m]; + final float imRoot = imUnitRootEven[m]; + reData[i0] = reBuffer[i0] + re * reRoot - im * imRoot; + imData[i0] = imBuffer[i0] + re * imRoot + im * reRoot; + i0 += stride; + i1 += stride; + } + reData[i0] = reBuffer[i0]; + imData[i0] = -reBuffer[i1]; + m0 = i0 + stride; + i0 -= stride; + i1 -= stride; + for (int m = 1; (m < K4); m++) { + final float re = imBuffer[i1]; + final float im = reBuffer[i1]; + final float reRoot = reUnitRootEven[m]; + final float imRoot = imUnitRootEven[m]; + reData[m0] = reBuffer[i0] - re * reRoot + im * imRoot; + imData[m0] = -imBuffer[i0] - re * imRoot - im * reRoot; + m0 += stride; + i0 -= stride; + i1 -= stride; + } + } + else { + for (int m = 1; (m <= K4); m++) { + final float re = reBuffer[i1]; + final float im = imBuffer[i1]; + final float reRoot = reUnitRootEven[m]; + final float imRoot = imUnitRootEven[m]; + reData[i0] = reBuffer[i0] + re * reRoot - im * imRoot; + imData[i0] = imBuffer[i0] + re * imRoot + im * reRoot; + i0 += stride; + i1 += stride; + } + m0 = i0; + i0 -= stride; + i1 -= stride; + for (int m = 0; (m < K4); m++) { + final float re = imBuffer[i1]; + final float im = reBuffer[i1]; + final float reRoot = reUnitRootOdd[m]; + final float imRoot = imUnitRootOdd[m]; + reData[m0] = reBuffer[i0] - re * reRoot + im * imRoot; + imData[m0] = -imBuffer[i0] - re * imRoot - im * reRoot; + i0 -= stride; + i1 -= stride; + m0 += stride; + } + } + reData[m0] = reBuffer[i0] - reBuffer[i1]; + imData[m0] = 0.0F; +} /* end run */ + +/*.................................................................... + DFTRadix2RealFloat static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static float[] getImUnitRootEven ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final float[] imUnitRoot = new float[halfTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + imUnitRoot[k] = (float)sin((double)((float)k * angularStep)); + } + return(imUnitRoot); +} /* end getImUnitRootEven */ + +/*------------------------------------------------------------------*/ +static float[] getReUnitRootEven ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final float[] reUnitRoot = new float[halfTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + reUnitRoot[k] = (float)cos((double)((float)k * angularStep)); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +/*------------------------------------------------------------------*/ +static float[] getImUnitRootOdd ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final float[] imUnitRoot = new float[halfTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + imUnitRoot[k] = (float)sin((double)(((float)k + 0.5F) + * angularStep)); + } + return(imUnitRoot); +} /* end getImUnitRootOdd */ + +/*------------------------------------------------------------------*/ +static float[] getReUnitRootOdd ( + final int transformLength +) { + final int halfTransformLength = transformLength >> 1; + final float[] reUnitRoot = new float[halfTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < halfTransformLength); k++) { + reUnitRoot[k] = (float)cos((double)(((float)k + 0.5F) + * angularStep)); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class getReUnitRootOdd */ + +/*==================================================================== +| DFTSplitRadix +\===================================================================*/ +static class DFTSplitRadix + +{ /* begin class DFTSplitRadix */ + +/*.................................................................... + DFTSplitRadix static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (FFTSetup.taboos.contains(new Integer(transformLength / 2)) + || FFTSetup.taboos.contains(new Integer(transformLength / 4))) { + return(-1L); + } + final long k = (long)(transformLength >> 1); + final long k2 = k >> 1L; + return(FFTSetup.FLALLOC * 12L + + FFTSetup.FLOP * (k2 * 24L) + + FFTSetup.FLASSIGN * (k * 2L + k2 * 2L + k2 * 2L + k2 * 28L) + + FFTSetup.INTALLOC * 15L + + FFTSetup.INTOP * (9L + k * 4L + 1L + k2 * 4L + 1L + k2 * 4L + 6L + + k2 * 7L) + + FFTSetup.INTASSIGN * (8L + k * 3L + 2L + k2 * 3L + 2L + k2 * 3L + 6L + + k2 * 6L) + + FFTSetup.IDX * (k * 4L + k2 * 4L + k2 * 4L + k2 * 20L) + + FFTSetup.NEWOBJ * 3L + + FFTSetup.cost(transformLength >> 1) + + 2L * FFTSetup.cost(transformLength >> 2) + ); +} /* end cost */ + +} /* end class DFTSplitRadix */ + +/*==================================================================== +| DFTSplitRadixDouble +\===================================================================*/ +static class DFTSplitRadixDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTSplitRadixDouble */ + +/*.................................................................... + DFTSplitRadixDouble static variables +....................................................................*/ +private double[] imBuffer; +private double[] imUnitRoot; +private double[] reBuffer; +private double[] reUnitRoot; + +/*.................................................................... + DFTSplitRadixDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTSplitRadixDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reUnitRoot, + final double[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTSplitRadixDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int K4 = reUnitRoot.length / 3; +//;IJ.log("DFTSplitRadixDouble " + (4 * K4)); + final int K2 = K4 << 1; + final int doubleStride = stride << 1; + final int tripleStride = doubleStride + stride; + final int quadrupleStride = tripleStride + stride; + final FFTSetup fft2 = FFTSetup.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2Double(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4Double(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6Double(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8Double(reData, imData, + startIndex, doubleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderDouble(reData, imData, + startIndex, doubleStride, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Double(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + } + final FFTSetup fft4 = FFTSetup.transforms.get(new Integer(K4)); + switch (fft4.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + new DFTBruteForceDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.ruritanian, fft4.chinese, + fft4.K1).run(); + new DFTCoprimeFactorDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.ruritanian, fft4.chinese, + fft4.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Double(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength2Double(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH3: { + new DFTLength3Double(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength3Double(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH4: { + new DFTLength4Double(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength4Double(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH5: { + new DFTLength5Double(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength5Double(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH6: { + new DFTLength6Double(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength6Double(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8Double(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength8Double(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble, + fft4.K1).run(); + new DFTMixedRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble, + fft4.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderDouble(reData, imData, + startIndex + stride, quadrupleStride, + fft4.reConvolverDouble, fft4.imConvolverDouble, + fft4.modular, fft4.inverseModular).run(); + new DFTPaddedRaderDouble(reData, imData, + startIndex + tripleStride, quadrupleStride, + fft4.reConvolverDouble, fft4.imConvolverDouble, + fft4.modular, fft4.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reConvolverDouble, fft4.imConvolverDouble, + fft4.modular, fft4.inverseModular).run(); + new DFTRaderDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reConvolverDouble, fft4.imConvolverDouble, + fft4.modular, fft4.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Double(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + new DFTRadix2Double(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + new DFTSplitRadixDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + break; + } + } + int m0 = startIndex; + int i0 = startIndex; + for (int m = 0; (m < K2); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += doubleStride; + i0 += stride; + } + m0 = startIndex + stride; + for (int m = 0; (m < K4); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += quadrupleStride; + i0 += stride; + } + m0 = startIndex + tripleStride; + for (int m = 0; (m < K4); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += quadrupleStride; + i0 += stride; + } + i0 = startIndex; + int i1 = i0 + K4 * stride; + int i2 = i1 + K4 * stride; + int i3 = i2 + K4 * stride; + for (int m1 = 0, m3 = 0; (m1 < K4); m1++, m3 += 3) { + double re = reBuffer[i2]; + double im = imBuffer[i2]; + double reRoot = reUnitRoot[m1]; + double imRoot = imUnitRoot[m1]; + double reButterfly = re * reRoot - im * imRoot; + double imButterfly = re * imRoot + im * reRoot; + re = reBuffer[i3]; + im = imBuffer[i3]; + reRoot = reUnitRoot[m3]; + imRoot = imUnitRoot[m3]; + double reDragonfly = re * reRoot - im * imRoot; + double imDragonfly = re * imRoot + im * reRoot; + final double reLadybug = reButterfly + reDragonfly; + final double imLadybug = imButterfly + imDragonfly; + final double reMoth = reButterfly - reDragonfly; + final double imMoth = imButterfly - imDragonfly; + reButterfly = reBuffer[i0]; + imButterfly = imBuffer[i0]; + reDragonfly = reBuffer[i1]; + imDragonfly = imBuffer[i1]; + reData[i0] = reButterfly + reLadybug; + imData[i0] = imButterfly + imLadybug; + reData[i1] = reDragonfly + imMoth; + imData[i1] = imDragonfly - reMoth; + reData[i2] = reButterfly - reLadybug; + imData[i2] = imButterfly - imLadybug; + reData[i3] = reDragonfly - imMoth; + imData[i3] = imDragonfly + reMoth; + i0 += stride; + i1 += stride; + i2 += stride; + i3 += stride; + } +} /* end run */ + +/*.................................................................... + DFTSplitRadixDouble static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static double[] getImUnitRoot ( + final int transformLength +) { + final int fourthTransformLength = transformLength >> 2; + final int threeFourthTransformLength = 3 * fourthTransformLength; + final double[] imUnitRoot = new double[threeFourthTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < threeFourthTransformLength); k++) { + imUnitRoot[k] = sin((double)k * angularStep); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static double[] getReUnitRoot ( + final int transformLength +) { + final int fourthTransformLength = transformLength >> 2; + final int threeFourthTransformLength = 3 * fourthTransformLength; + final double[] reUnitRoot = new double[threeFourthTransformLength]; + final double angularStep = -2.0 * PI / (double)transformLength; + for (int k = 0; (k < threeFourthTransformLength); k++) { + reUnitRoot[k] = cos((double)k * angularStep); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTSplitRadixDouble */ + +/*==================================================================== +| DFTSplitRadixFloat +\===================================================================*/ +static class DFTSplitRadixFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTSplitRadixFloat */ + +/*.................................................................... + DFTSplitRadixFloat static variables +....................................................................*/ +private float[] imBuffer; +private float[] imUnitRoot; +private float[] reBuffer; +private float[] reUnitRoot; + +/*.................................................................... + DFTSplitRadixFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTSplitRadixFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reUnitRoot, + final float[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTSplitRadixFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int K4 = reUnitRoot.length / 3; +//;IJ.log("DFTSplitRadixFloat " + (4 * K4)); + final int K2 = K4 << 1; + final int doubleStride = stride << 1; + final int tripleStride = doubleStride + stride; + final int quadrupleStride = tripleStride + stride; + final FFTSetup fft2 = FFTSetup.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.ruritanian, fft2.chinese, + fft2.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2Float(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4Float(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6Float(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8Float(reData, imData, + startIndex, doubleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderFloat(reData, imData, + startIndex, doubleStride, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Float(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + } + final FFTSetup fft4 = FFTSetup.transforms.get(new Integer(K4)); + switch (fft4.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + new DFTBruteForceFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.ruritanian, fft4.chinese, + fft4.K1).run(); + new DFTCoprimeFactorFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.ruritanian, fft4.chinese, + fft4.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Float(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength2Float(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH3: { + new DFTLength3Float(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength3Float(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH4: { + new DFTLength4Float(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength4Float(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH5: { + new DFTLength5Float(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength5Float(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH6: { + new DFTLength6Float(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength6Float(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8Float(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength8Float(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat, + fft4.K1).run(); + new DFTMixedRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat, + fft4.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderFloat(reData, imData, + startIndex + stride, quadrupleStride, + fft4.reConvolverFloat, fft4.imConvolverFloat, + fft4.modular, fft4.inverseModular).run(); + new DFTPaddedRaderFloat(reData, imData, + startIndex + tripleStride, quadrupleStride, + fft4.reConvolverFloat, fft4.imConvolverFloat, + fft4.modular, fft4.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reConvolverFloat, fft4.imConvolverFloat, + fft4.modular, fft4.inverseModular).run(); + new DFTRaderFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reConvolverFloat, fft4.imConvolverFloat, + fft4.modular, fft4.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Float(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + new DFTRadix2Float(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + new DFTSplitRadixFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + break; + } + } + int m0 = startIndex; + int i0 = startIndex; + for (int m = 0; (m < K2); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += doubleStride; + i0 += stride; + } + m0 = startIndex + stride; + for (int m = 0; (m < K4); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += quadrupleStride; + i0 += stride; + } + m0 = startIndex + tripleStride; + for (int m = 0; (m < K4); m++) { + reBuffer[i0] = reData[m0]; + imBuffer[i0] = imData[m0]; + m0 += quadrupleStride; + i0 += stride; + } + i0 = startIndex; + int i1 = i0 + K4 * stride; + int i2 = i1 + K4 * stride; + int i3 = i2 + K4 * stride; + for (int m1 = 0, m3 = 0; (m1 < K4); m1++, m3 += 3) { + float re = reBuffer[i2]; + float im = imBuffer[i2]; + float reRoot = reUnitRoot[m1]; + float imRoot = imUnitRoot[m1]; + float reButterfly = re * reRoot - im * imRoot; + float imButterfly = re * imRoot + im * reRoot; + re = reBuffer[i3]; + im = imBuffer[i3]; + reRoot = reUnitRoot[m3]; + imRoot = imUnitRoot[m3]; + float reDragonfly = re * reRoot - im * imRoot; + float imDragonfly = re * imRoot + im * reRoot; + final float reLadybug = reButterfly + reDragonfly; + final float imLadybug = imButterfly + imDragonfly; + final float reMoth = reButterfly - reDragonfly; + final float imMoth = imButterfly - imDragonfly; + reButterfly = reBuffer[i0]; + imButterfly = imBuffer[i0]; + reDragonfly = reBuffer[i1]; + imDragonfly = imBuffer[i1]; + reData[i0] = reButterfly + reLadybug; + imData[i0] = imButterfly + imLadybug; + reData[i1] = reDragonfly + imMoth; + imData[i1] = imDragonfly - reMoth; + reData[i2] = reButterfly - reLadybug; + imData[i2] = imButterfly - imLadybug; + reData[i3] = reDragonfly - imMoth; + imData[i3] = imDragonfly + reMoth; + i0 += stride; + i1 += stride; + i2 += stride; + i3 += stride; + } +} /* end run */ + +/*.................................................................... + DFTSplitRadixFloat static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static float[] getImUnitRoot ( + final int transformLength +) { + final int fourthTransformLength = transformLength >> 2; + final int threeFourthTransformLength = 3 * fourthTransformLength; + final float[] imUnitRoot = new float[threeFourthTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < threeFourthTransformLength); k++) { + imUnitRoot[k] = (float)sin((double)((float)k * angularStep)); + } + return(imUnitRoot); +} /* end getImUnitRoot */ + +/*------------------------------------------------------------------*/ +static float[] getReUnitRoot ( + final int transformLength +) { + final int fourthTransformLength = transformLength >> 2; + final int threeFourthTransformLength = 3 * fourthTransformLength; + final float[] reUnitRoot = new float[threeFourthTransformLength]; + final float angularStep = -2.0F * (float)PI / (float)transformLength; + for (int k = 0; (k < threeFourthTransformLength); k++) { + reUnitRoot[k] = (float)cos((double)((float)k * angularStep)); + } + return(reUnitRoot); +} /* end getReUnitRoot */ + +} /* end class DFTSplitRadixFloat */ + +/*==================================================================== +| DFTSplitRadixReal +\===================================================================*/ +static class DFTSplitRadixReal + +{ /* begin class DFTSplitRadixReal */ + +/*.................................................................... + DFTSplitRadixReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (FFTSetup.taboos.contains(new Integer(transformLength / 2)) + || FFTSetup.taboos.contains(new Integer(transformLength / 4))) { + return(-1L); + } + final long k = (long)(transformLength >> 1); + final long k2 = k >> 1L; + final long k4 = k2 >> 1L; + return(FFTSetup.FLALLOC * 8L + + FFTSetup.FLOP * ((k4 + 1L) * 16L + 1L + k4 * 2L + (k2 - k4) * 2L + 1L + + k4 * 3L + (k2 - k4) * 2L + 1L) + + FFTSetup.FLASSIGN * ((k2 + 1L) * 2L + (k4 + 1L) * 16L + 2L + k4 * 2L + + (k2 - k4) * 2L + 2L + k4 * 2L + (k2 - k4) * 2L + 2L) + + FFTSetup.INTALLOC * 18L + + FFTSetup.INTOP * (12L + (k2 + 1L) * 4L + 6L + (k4 + 1L) * 7L + 4L + + k4 * 4L + 4L + (k2 - k4) * 4L + 5L + k4 * 5L + 4L + + (k2 - k4) * 5L) + + FFTSetup.INTASSIGN * (10L + (k2 + 1L) * 3L + 6L + (k4 + 1L) * 6L + 5L + + k4 * 3L + 2L + (k2 - k4) * 3L + 4L + k4 * 4L + 2L + + (k2 - k4) * 4L) + + FFTSetup.IDX * ((k2 + 1L) * 4L + (k4 + 1L) * 12L + 4L + k4 * 6L + + (k2 - k4) * 6L + 4L + k4 * 6L + (k2 - k4) * 6L + 4L) + + FFTSetup.NEWOBJ * 3L + + FFTSetupReal.cost(transformLength >> 1) + + FFTSetupDuoReal.cost(transformLength >> 2) + ); +} /* end cost */ + +} /* end class DFTSplitRadixReal */ + +/*==================================================================== +| DFTSplitRadixRealDouble +\===================================================================*/ +static class DFTSplitRadixRealDouble + extends + DFTDouble + implements + Runnable + +{ /* begin class DFTSplitRadixRealDouble */ + +/*.................................................................... + DFTSplitRadixRealDouble static variables +....................................................................*/ +private double[] imBuffer; +private double[] imUnitRoot; +private double[] reBuffer; +private double[] reUnitRoot; + +/*.................................................................... + DFTSplitRadixRealDouble constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTSplitRadixRealDouble ( + final double[] reData, + final double[] imData, + final double[] reBuffer, + final double[] imBuffer, + final int startIndex, + final int stride, + final double[] reUnitRoot, + final double[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTSplitRadixRealDouble */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int K4 = reUnitRoot.length / 3; +//;IJ.log("DFTSplitRadixRealDouble " + (4 * K4)); + final int halfK4 = (K4 >> 1) + 1; + final int K2 = K4 << 1; + final int halfK2 = K4 + 1; + final int doubleStride = stride << 1; + final int tripleStride = doubleStride + stride; + final int quadrupleStride = tripleStride + stride; + final FFTSetupReal fft2 = FFTSetupReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2RealDouble(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4RealDouble(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6RealDouble(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reData, imData, + startIndex, doubleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reData, imData, + startIndex, doubleStride, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootEvenDouble, fft2.imUnitRootEvenDouble, + fft2.reUnitRootOddDouble, fft2.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootDouble, fft2.imUnitRootDouble).run(); + break; + } + } + final FFTSetupDuoReal fft4 = + FFTSetupDuoReal.transforms.get(new Integer(K4)); + switch (fft4.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + new DFTBruteForceRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.ruritanian, fft4.chinese, + fft4.K1).run(); + new DFTCoprimeFactorRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.ruritanian, fft4.chinese, + fft4.K1).run(); + break; + } + case DUOREAL: { + new DFTDuoRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, startIndex + tripleStride, + quadrupleStride, K4).run(); + break; + } + case EVENREAL: { + new DFTEvenRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + new DFTEvenRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + imData[startIndex + stride] = 0.0; + imData[startIndex + tripleStride] = 0.0; + break; + } + case LENGTH2: { + new DFTLength2RealDouble(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength2RealDouble(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength3RealDouble(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength4RealDouble(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength5RealDouble(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength6RealDouble(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength8RealDouble(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble, + fft4.K1).run(); + new DFTMixedRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble, + fft4.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reData, imData, + startIndex + stride, quadrupleStride, + fft4.reConvolverDouble, fft4.imConvolverDouble, + fft4.modular, fft4.inverseModular).run(); + new DFTPaddedRaderRealDouble(reData, imData, + startIndex + tripleStride, quadrupleStride, + fft4.reConvolverDouble, fft4.imConvolverDouble, + fft4.modular, fft4.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reConvolverDouble, fft4.imConvolverDouble, + fft4.modular, fft4.inverseModular).run(); + new DFTRaderRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reConvolverDouble, fft4.imConvolverDouble, + fft4.modular, fft4.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootEvenDouble, fft4.imUnitRootEvenDouble, + fft4.reUnitRootOddDouble, fft4.imUnitRootOddDouble).run(); + new DFTRadix2RealDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootEvenDouble, fft4.imUnitRootEvenDouble, + fft4.reUnitRootOddDouble, fft4.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + new DFTSplitRadixRealDouble(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootDouble, fft4.imUnitRootDouble).run(); + break; + } + } + int p = startIndex; + int q = startIndex; + for (int m = 0; (m < halfK2); m++) { + reBuffer[p] = reData[q]; + imBuffer[p] = imData[q]; + q += doubleStride; + p += stride; + } + p = startIndex + K2 * stride; + q = p + K4 * stride; + int r = startIndex + stride; + int s = r + doubleStride; + for (int m = 0, n = 0; (m < halfK4); m++, n += 3) { + double re = reData[r]; + double im = imData[r]; + double reRoot = reUnitRoot[m]; + double imRoot = imUnitRoot[m]; + double reButterfly = re * reRoot - im * imRoot; + double imButterfly = re * imRoot + im * reRoot; + re = reData[s]; + im = imData[s]; + reRoot = reUnitRoot[n]; + imRoot = imUnitRoot[n]; + final double reDragonfly = re * reRoot - im * imRoot; + final double imDragonfly = re * imRoot + im * reRoot; + reBuffer[p] = reButterfly + reDragonfly; + imBuffer[p] = imButterfly + imDragonfly; + reBuffer[q] = reButterfly - reDragonfly; + imBuffer[q] = imButterfly - imDragonfly; + r += quadrupleStride; + s += quadrupleStride; + p += stride; + q += stride; + }; + p = startIndex; + q = startIndex + K2 * stride; + reData[p] = reBuffer[p] + reBuffer[q]; + imData[p] = 0.0; + p += stride; + q += stride; + for (int n = 1; (n < halfK4); n++) { + reData[p] = reBuffer[p] + reBuffer[q]; + imData[p] = imBuffer[p] + imBuffer[q]; + p += stride; + q += stride; + } + q = startIndex + (2 * K2 - halfK4) * stride; + for (int n = halfK4; (n < K4); n++) { + reData[p] = reBuffer[p] - imBuffer[q]; + imData[p] = imBuffer[p] - reBuffer[q]; + p += stride; + q -= stride; + } + reData[p] = reBuffer[p]; + imData[p] = -reBuffer[q]; + p += stride; + q += stride; + r = startIndex + (K4 - 1) * stride; + for (int n = 1; (n < halfK4); n++) { + reData[p] = reBuffer[r] + imBuffer[q]; + imData[p] = -imBuffer[r] - reBuffer[q]; + p += stride; + q += stride; + r -= stride; + } + q = startIndex + (K2 + K4 - halfK4) * stride; + for (int n = halfK4; (n < K4); n++) { + reData[p] = reBuffer[r] - reBuffer[q]; + imData[p] = imBuffer[q] - imBuffer[r]; + p += stride; + q -= stride; + r -= stride; + } + reData[p] = reBuffer[startIndex] - reBuffer[q]; + imData[p] = 0.0; +} /* end run */ + +} /* end class DFTSplitRadixRealDouble */ + +/*==================================================================== +| DFTSplitRadixRealFloat +\===================================================================*/ +static class DFTSplitRadixRealFloat + extends + DFTFloat + implements + Runnable + +{ /* begin class DFTSplitRadixRealFloat */ + +/*.................................................................... + DFTSplitRadixRealFloat static variables +....................................................................*/ +private float[] imBuffer; +private float[] imUnitRoot; +private float[] reBuffer; +private float[] reUnitRoot; + +/*.................................................................... + DFTSplitRadixRealFloat constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +DFTSplitRadixRealFloat ( + final float[] reData, + final float[] imData, + final float[] reBuffer, + final float[] imBuffer, + final int startIndex, + final int stride, + final float[] reUnitRoot, + final float[] imUnitRoot +) { + super(reData, imData, startIndex, stride); + this.reBuffer = reBuffer; + this.imBuffer = imBuffer; + this.reUnitRoot = reUnitRoot; + this.imUnitRoot = imUnitRoot; +} /* end DFTSplitRadixRealFloat */ + +/*.................................................................... + Runnable methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public void run ( +) { + final int K4 = reUnitRoot.length / 3; +//;IJ.log("DFTSplitRadixRealFloat " + (4 * K4)); + final int halfK4 = (K4 >> 1) + 1; + final int K2 = K4 << 1; + final int halfK2 = K4 + 1; + final int doubleStride = stride << 1; + final int tripleStride = doubleStride + stride; + final int quadrupleStride = tripleStride + stride; + final FFTSetupReal fft2 = FFTSetupReal.transforms.get(new Integer(K2)); + switch (fft2.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.ruritanian, fft2.chinese, fft2.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + throw(new IllegalStateException()); + } + case LENGTH2: { + new DFTLength2RealFloat(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH3: { + throw(new IllegalStateException()); + } + case LENGTH4: { + new DFTLength4RealFloat(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH5: { + throw(new IllegalStateException()); + } + case LENGTH6: { + new DFTLength6RealFloat(reData, imData, + startIndex, doubleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reData, imData, + startIndex, doubleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reData, imData, + startIndex, doubleStride, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootEvenFloat, fft2.imUnitRootEvenFloat, + fft2.reUnitRootOddFloat, fft2.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex, doubleStride, + fft2.reUnitRootFloat, fft2.imUnitRootFloat).run(); + break; + } + } + final FFTSetupDuoReal fft4 = + FFTSetupDuoReal.transforms.get(new Integer(K4)); + switch (fft4.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + new DFTBruteForceRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.ruritanian, fft4.chinese, + fft4.K1).run(); + new DFTCoprimeFactorRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.ruritanian, fft4.chinese, + fft4.K1).run(); + break; + } + case DUOREAL: { + new DFTDuoRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, startIndex + tripleStride, + quadrupleStride, K4).run(); + break; + } + case EVENREAL: { + new DFTEvenRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + new DFTEvenRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + imData[startIndex + stride] = 0.0F; + imData[startIndex + tripleStride] = 0.0F; + break; + } + case LENGTH2: { + new DFTLength2RealFloat(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength2RealFloat(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength3RealFloat(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength4RealFloat(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength5RealFloat(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength6RealFloat(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reData, imData, + startIndex + stride, quadrupleStride).run(); + new DFTLength8RealFloat(reData, imData, + startIndex + tripleStride, quadrupleStride).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat, + fft4.K1).run(); + new DFTMixedRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat, + fft4.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reData, imData, + startIndex + stride, quadrupleStride, + fft4.reConvolverFloat, fft4.imConvolverFloat, + fft4.modular, fft4.inverseModular).run(); + new DFTPaddedRaderRealFloat(reData, imData, + startIndex + tripleStride, quadrupleStride, + fft4.reConvolverFloat, fft4.imConvolverFloat, + fft4.modular, fft4.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reConvolverFloat, fft4.imConvolverFloat, + fft4.modular, fft4.inverseModular).run(); + new DFTRaderRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reConvolverFloat, fft4.imConvolverFloat, + fft4.modular, fft4.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootEvenFloat, fft4.imUnitRootEvenFloat, + fft4.reUnitRootOddFloat, fft4.imUnitRootOddFloat).run(); + new DFTRadix2RealFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootEvenFloat, fft4.imUnitRootEvenFloat, + fft4.reUnitRootOddFloat, fft4.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + stride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + new DFTSplitRadixRealFloat(reData, imData, reBuffer, imBuffer, + startIndex + tripleStride, quadrupleStride, + fft4.reUnitRootFloat, fft4.imUnitRootFloat).run(); + break; + } + } + int p = startIndex; + int q = startIndex; + for (int m = 0; (m < halfK2); m++) { + reBuffer[p] = reData[q]; + imBuffer[p] = imData[q]; + q += doubleStride; + p += stride; + } + p = startIndex + K2 * stride; + q = p + K4 * stride; + int r = startIndex + stride; + int s = r + doubleStride; + for (int m = 0, n = 0; (m < halfK4); m++, n += 3) { + float re = reData[r]; + float im = imData[r]; + float reRoot = reUnitRoot[m]; + float imRoot = imUnitRoot[m]; + float reButterfly = re * reRoot - im * imRoot; + float imButterfly = re * imRoot + im * reRoot; + re = reData[s]; + im = imData[s]; + reRoot = reUnitRoot[n]; + imRoot = imUnitRoot[n]; + final float reDragonfly = re * reRoot - im * imRoot; + final float imDragonfly = re * imRoot + im * reRoot; + reBuffer[p] = reButterfly + reDragonfly; + imBuffer[p] = imButterfly + imDragonfly; + reBuffer[q] = reButterfly - reDragonfly; + imBuffer[q] = imButterfly - imDragonfly; + r += quadrupleStride; + s += quadrupleStride; + p += stride; + q += stride; + }; + p = startIndex; + q = startIndex + K2 * stride; + reData[p] = reBuffer[p] + reBuffer[q]; + imData[p] = 0.0F; + p += stride; + q += stride; + for (int n = 1; (n < halfK4); n++) { + reData[p] = reBuffer[p] + reBuffer[q]; + imData[p] = imBuffer[p] + imBuffer[q]; + p += stride; + q += stride; + } + q = startIndex + (2 * K2 - halfK4) * stride; + for (int n = halfK4; (n < K4); n++) { + reData[p] = reBuffer[p] - imBuffer[q]; + imData[p] = imBuffer[p] - reBuffer[q]; + p += stride; + q -= stride; + } + reData[p] = reBuffer[p]; + imData[p] = -reBuffer[q]; + p += stride; + q += stride; + r = startIndex + (K4 - 1) * stride; + for (int n = 1; (n < halfK4); n++) { + reData[p] = reBuffer[r] + imBuffer[q]; + imData[p] = -imBuffer[r] - reBuffer[q]; + p += stride; + q += stride; + r -= stride; + } + q = startIndex + (K2 + K4 - halfK4) * stride; + for (int n = halfK4; (n < K4); n++) { + reData[p] = reBuffer[r] - reBuffer[q]; + imData[p] = imBuffer[q] - imBuffer[r]; + p += stride; + q -= stride; + r -= stride; + } + reData[p] = reBuffer[startIndex] - reBuffer[q]; + imData[p] = 0.0F; +} /* end run */ + +} /* end class DFTSplitRadixRealFloat */ + +/*==================================================================== +| FFTSetup +\===================================================================*/ +static class FFTSetup + +{ /* begin class FFTSetup */ + +/*.................................................................... + FFTSetup static private variables +....................................................................*/ +private static final HashSet<Integer> composites = new HashSet<Integer>(); +private static final HashSet<Integer> primes = new HashSet<Integer>(); + +/*.................................................................... + FFTSetup static protected variables +....................................................................*/ +protected static final HashMap<Integer, Algorithm> algorithms = + new HashMap<Integer, Algorithm>(); +protected static final HashMap<Integer, Integer> lengths = + new HashMap<Integer, Integer>(); +protected static final HashMap<Integer, FFTSetup> transforms = + new HashMap<Integer, FFTSetup>(); +protected static final HashMap<Integer, Long> costs = + new HashMap<Integer, Long>(); +protected static final HashSet<Integer> taboos = + new HashSet<Integer>(); +protected static final long FLASSIGN = 2L; +protected static final long FLOP = 4L; +protected static final long IDX = 1L; +protected static final long INTASSIGN = 1L; +protected static final long INTOP = 2L; +protected static final long NEWOBJ = 50L; + +protected static final long FLALLOC = FLOP + FLASSIGN; +protected static final long INTALLOC = INTOP + INTASSIGN; + +/*.................................................................... + FFTSetup static private variables +....................................................................*/ +private static int futurePrime = 7; + +/*.................................................................... + FFTSetup protected variables +....................................................................*/ +protected Algorithm algorithm; +protected double[] imConvolverDouble; +protected double[] imUnitRootDouble; +protected double[] reConvolverDouble; +protected double[] reUnitRootDouble; +protected float[] imConvolverFloat; +protected float[] imUnitRootFloat; +protected float[] reConvolverFloat; +protected float[] reUnitRootFloat; +protected int[] chinese; +protected int[] inverseModular; +protected int[] modular; +protected int[] ruritanian; +protected int K1; + +/*.................................................................... + FFTSetup inner classes +....................................................................*/ +/*==================================================================== +| FFTCostPrediction +\===================================================================*/ +static class FFTCostPrediction + +{ /* begin class FFTCostPrediction */ + +/*.................................................................... + FFTCostPrediction variables +....................................................................*/ +protected Algorithm algorithm; +protected int length; +protected long cost; + +/*.................................................................... + FFTCostPrediction constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +FFTCostPrediction ( + final Algorithm algorithm, + final int length, + final long cost +) { + this.algorithm = algorithm; + this.length = length; + this.cost = cost; +} /* end FFTCostPrediction */ + +/*.................................................................... + Object methods +....................................................................*/ +/*------------------------------------------------------------------*/ +@Override +public boolean equals ( + final Object o +) { + return((((FFTCostPrediction)o).algorithm == algorithm) + && (((FFTCostPrediction)o).length == length)); +} /* end equals */ + +} /* end class FFTCostPrediction */ + +/*.................................................................... + FFTSetup static initialization block +....................................................................*/ +static { + initialize(); +} + +/*.................................................................... + FFTSetup constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +FFTSetup ( + final int transformLength +) { + if (transforms.containsKey(new Integer(transformLength))) { + return; + } + transforms.put(new Integer(transformLength), this); + cost(transformLength); + algorithm = algorithms.get(new Integer(transformLength)); + switch (algorithm) { + case BRUTEFORCE: { + reUnitRootDouble = + DFTBruteForceDouble.getReUnitRoot(transformLength); + imUnitRootDouble = + DFTBruteForceDouble.getImUnitRoot(transformLength); + reUnitRootFloat = + DFTBruteForceFloat.getReUnitRoot(transformLength); + imUnitRootFloat = + DFTBruteForceFloat.getImUnitRoot(transformLength); + break; + } + case COPRIMEFACTOR: { + K1 = lengths.get(new Integer(transformLength)).intValue(); + final int K2 = transformLength / K1; + ruritanian = DFTCoprimeFactor.getRuritanianShuffling(K1, K2); + chinese = DFTCoprimeFactor.getChineseRemainderShuffling(K1, K2); + new FFTSetup(K1); + new FFTSetup(K2); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + break; + } + case LENGTH3: { + break; + } + case LENGTH4: { + break; + } + case LENGTH5: { + break; + } + case LENGTH6: { + break; + } + case LENGTH8: { + break; + } + case MIXEDRADIX: { + K1 = lengths.get(new Integer(transformLength)).intValue(); + final int K2 = transformLength / K1; + reUnitRootDouble = + DFTMixedRadixDouble.getReUnitRoot(transformLength); + imUnitRootDouble = + DFTMixedRadixDouble.getImUnitRoot(transformLength); + reUnitRootFloat = + DFTMixedRadixFloat.getReUnitRoot(transformLength); + imUnitRootFloat = + DFTMixedRadixFloat.getImUnitRoot(transformLength); + new FFTSetup(K1); + new FFTSetup(K2); + break; + } + case PADDEDRADER: { + final int paddedLength = + lengths.get(new Integer(transformLength)).intValue(); + modular = DFTRader.getModularPowerShuffling(transformLength); + inverseModular = + DFTPaddedRader.getInverseModularPowerShuffling(modular, + paddedLength); + new FFTSetup(paddedLength); + final double[][] convolverD = + DFTPaddedRaderDouble.getConvolverReAndIm(modular, + paddedLength); + reConvolverDouble = convolverD[0]; + imConvolverDouble = convolverD[1]; + final float[][] convolverF = + DFTPaddedRaderFloat.getConvolverReAndIm(modular, + paddedLength); + reConvolverFloat = convolverF[0]; + imConvolverFloat = convolverF[1]; + break; + } + case RADER: { + modular = DFTRader.getModularPowerShuffling(transformLength); + inverseModular = DFTRader.getInverseModularPowerShuffling(modular); + new FFTSetup(transformLength - 1); + final double[][] convolverD = + DFTRaderDouble.getConvolverReAndIm(modular); + reConvolverDouble = convolverD[0]; + imConvolverDouble = convolverD[1]; + final float[][] convolverF = + DFTRaderFloat.getConvolverReAndIm(modular); + reConvolverFloat = convolverF[0]; + imConvolverFloat = convolverF[1]; + break; + } + case RADIX2: { + reUnitRootDouble = + DFTRadix2Double.getReUnitRoot(transformLength); + imUnitRootDouble = + DFTRadix2Double.getImUnitRoot(transformLength); + reUnitRootFloat = + DFTRadix2Float.getReUnitRoot(transformLength); + imUnitRootFloat = + DFTRadix2Float.getImUnitRoot(transformLength); + new FFTSetup(transformLength >> 1); + break; + } + case SPLITRADIX: { + reUnitRootDouble = + DFTSplitRadixDouble.getReUnitRoot(transformLength); + imUnitRootDouble = + DFTSplitRadixDouble.getImUnitRoot(transformLength); + reUnitRootFloat = + DFTSplitRadixFloat.getReUnitRoot(transformLength); + imUnitRootFloat = + DFTSplitRadixFloat.getImUnitRoot(transformLength); + new FFTSetup(transformLength >> 1); + new FFTSetup(transformLength >> 2); + break; + } + } +} /* end FFTSetup */ + +/*.................................................................... + FFTSetup static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (costs.containsKey(new Integer(transformLength))) { + return(costs.get(new Integer(transformLength)).longValue()); + } + final Vector<FFTCostPrediction> costPredictions = + new Vector<FFTCostPrediction>(); + switch (transformLength) { + case 1: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH1, -1, 0L)); + break; + } + case 2: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH2, -1, DFTLength2.cost())); + break; + } + case 3: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH3, -1, DFTLength3.cost())); + break; + } + case 4: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH4, -1, DFTLength4.cost())); + break; + } + case 5: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH5, -1, DFTLength5.cost())); + break; + } + case 6: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH6, -1, DFTLength6.cost())); + break; + } + case 8: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH8, -1, DFTLength8.cost())); + break; + } + default: { + final HashSet<Integer> divisors = divisors(transformLength); + if (divisors.isEmpty()) { + costPredictions.add(new FFTCostPrediction( + Algorithm.RADER, -1, DFTRader.cost(transformLength))); + while (futurePrime < transformLength) { + cost(futurePrime); + } + do { + futurePrime +=2; + } while (!isPrime(futurePrime)); + int minPaddedLength = 2 * transformLength - 3; + int maxPaddedLength = 1; + int n = minPaddedLength; + while (0 < n) { + n >>= 1; + maxPaddedLength <<= 1; + } + for (n = transformLength; (n < minPaddedLength); n += 2) { + if (costs.containsKey(new Integer(n))) { + continue; + } + if (isPrime(n)) { + taboos.add(new Integer(n)); + taboos.add(new Integer(2 * n)); + taboos.add(new Integer(3 * n)); + } + } + for (n = minPaddedLength; (n <= maxPaddedLength); n += 2) { + if (costs.containsKey(new Integer(n))) { + continue; + } + if (isPrime(n)) { + taboos.add(new Integer(n)); + taboos.add(new Integer(2 * n)); + } + } + for (n = minPaddedLength; (n <= maxPaddedLength); n++) { + costPredictions.add(new FFTCostPrediction( + Algorithm.PADDEDRADER, n, + DFTPaddedRader.cost(transformLength, n))); + } + taboos.clear(); + } + else { + for (Integer d: divisors) { + final int K1 = d.intValue(); + final int K2 = transformLength / K1; + costPredictions.add(new FFTCostPrediction( + Algorithm.MIXEDRADIX, K1, + DFTMixedRadix.cost(K1, K2))); + if (1 == greatestCommonDivisor(K1, K2)) { + costPredictions.add(new FFTCostPrediction( + Algorithm.COPRIMEFACTOR, K1, + DFTCoprimeFactor.cost(K1, K2))); + } + if (2 == K1) { + costPredictions.add(new FFTCostPrediction( + Algorithm.RADIX2, -1, + DFTRadix2.cost(transformLength))); + } + if (4 == K1) { + costPredictions.add(new FFTCostPrediction( + Algorithm.SPLITRADIX, -1, + DFTSplitRadix.cost(transformLength))); + } + } + } + } + } + FFTCostPrediction best = new FFTCostPrediction( + Algorithm.BRUTEFORCE, -1, DFTBruteForce.cost(transformLength)); + long cheapest = best.cost; + for (FFTCostPrediction predicted: costPredictions) { + final long current = predicted.cost; + if (0L <= current) { + if (current < cheapest) { + cheapest = current; + best = predicted; + } + } + } + algorithms.put(new Integer(transformLength), best.algorithm); + lengths.put(new Integer(transformLength), new Integer(best.length)); + costs.put(new Integer(transformLength), new Long(cheapest)); + return(cheapest); +} /* end cost */ + +/*------------------------------------------------------------------*/ +static void reset ( +) { + composites.clear(); + primes.clear(); + algorithms.clear(); + lengths.clear(); + transforms.clear(); + costs.clear(); + taboos.clear(); + initialize(); +} /* end reset */ + +/*.................................................................... + FFTSetup private methods +....................................................................*/ +/*------------------------------------------------------------------*/ +private static HashSet<Integer> divisors ( + int number +) { + final HashSet<Integer> divisors = new HashSet<Integer>(); + for (int k = (int)floor(sqrt(0.5 + (double)number)); (2 <= k); k--) { + if (number == (k * (number / k))) { + divisors.add(new Integer(k)); + divisors.add(new Integer(number / k)); + } + } + return(divisors); +} /* end divisors */ + +/*------------------------------------------------------------------*/ +private static int greatestCommonDivisor ( + int m, + int n +) { + m = (m < 0) ? (-m) : (m); + n = (n < 0) ? (-n) : (n); + while (0 != n) { + final int p = n; + n = m - n * (m / n); + m = p; + } + return(m); +} /* end greatestCommonDivisor */ + +/*------------------------------------------------------------------*/ +static private void initialize ( +) { + primes.add(new Integer(2)); + primes.add(new Integer(3)); + primes.add(new Integer(5)); + new FFTSetup(2); + new FFTSetup(3); + new FFTSetup(5); + futurePrime = 7; +} /* end initialize */ + +/*------------------------------------------------------------------*/ +static private boolean isPrime ( + final int number +) { + if (composites.contains(new Integer(number))) { + return(false); + } + if (primes.contains(new Integer(number))) { + return(true); + } + boolean isComposite = false; + for (int k = (int)floor(sqrt(0.5 + (double)number)); (1 < k); k--) { + if (number == (k * (number / k))) { + isComposite = true; + break; + } + } + if (isComposite) { + composites.add(new Integer(number)); + return(false); + } + primes.add(new Integer(number)); + return(true); +} /* end isPrime */ + +} /* end class FFTSetup */ + +/*==================================================================== +| FFTSetupDuoReal +\===================================================================*/ +static class FFTSetupDuoReal + extends FFTSetupReal + +{ /* begin class FFTSetupDuoReal */ + +/*.................................................................... + FFTSetupDuoReal static protected variables +....................................................................*/ +protected static final HashMap<Integer, Algorithm> algorithms = + new HashMap<Integer, Algorithm>(); +protected static final HashMap<Integer, Integer> lengths = + new HashMap<Integer, Integer>(); +protected static final HashMap<Integer, FFTSetupDuoReal> transforms = + new HashMap<Integer, FFTSetupDuoReal>(); +protected static final HashMap<Integer, Long> costs = + new HashMap<Integer, Long>(); + +/*.................................................................... + FFTSetupDuoReal protected variables +....................................................................*/ +protected Algorithm algorithm; + +/*.................................................................... + FFTSetupDuoReal static initialization block +....................................................................*/ +static { + initialize(); +} + +/*.................................................................... + FFTSetupDuoReal constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +FFTSetupDuoReal ( + final int transformLength +) { + super(transformLength); + if (transforms.containsKey(new Integer(transformLength))) { + return; + } + new FFTSetupReal(transformLength); + algorithm = cheapest(transformLength); + FFTSetupReal fft = + FFTSetupReal.transforms.get(new Integer(transformLength)); + imConvolverDouble = fft.imConvolverDouble; + imUnitRootDouble = fft.imUnitRootDouble; + imUnitRootEvenDouble = fft.imUnitRootEvenDouble; + imUnitRootOddDouble = fft.imUnitRootOddDouble; + reConvolverDouble = fft.reConvolverDouble; + reUnitRootDouble = fft.reUnitRootDouble; + reUnitRootEvenDouble = fft.reUnitRootEvenDouble; + reUnitRootOddDouble = fft.reUnitRootOddDouble; + imConvolverFloat = fft.imConvolverFloat; + imUnitRootEvenFloat = fft.imUnitRootEvenFloat; + imUnitRootFloat = fft.imUnitRootFloat; + imUnitRootOddFloat = fft.imUnitRootOddFloat; + reConvolverFloat = fft.reConvolverFloat; + reUnitRootEvenFloat = fft.reUnitRootEvenFloat; + reUnitRootFloat = fft.reUnitRootFloat; + reUnitRootOddFloat = fft.reUnitRootOddFloat; + chinese = fft.chinese; + inverseModular = fft.inverseModular; + modular = fft.modular; + ruritanian = fft.ruritanian; + K1 = fft.K1; + transforms.put(new Integer(transformLength), this); +} /* end FFTSetupDuoReal */ + +/*.................................................................... + FFTSetupDuoReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static Algorithm cheapest ( + final int transformLength +) { + if (transforms.containsKey(new Integer(transformLength))) { + return(transforms.get(new Integer(transformLength)).algorithm); + } + final Vector<FFTCostPrediction> costPredictions = + new Vector<FFTCostPrediction>(); + costPredictions.add(new FFTCostPrediction( + FFTSetupReal.algorithms.get(new Integer(transformLength)), + FFTSetupReal.lengths.get(new Integer(transformLength)).intValue(), + 2L * FFTSetupReal.costs.get(new Integer(transformLength)).longValue())); + FFTCostPrediction best = new FFTCostPrediction( + Algorithm.DUOREAL, -1, DFTDuoReal.cost(transformLength)); + long cheapest = best.cost; + for (FFTCostPrediction predicted: costPredictions) { + final long current = predicted.cost; + if (0L <= current) { + if (current < cheapest) { + cheapest = current; + best = predicted; + } + } + } + algorithms.put(new Integer(transformLength), best.algorithm); + lengths.put(new Integer(transformLength), new Integer(best.length)); + costs.put(new Integer(transformLength), new Long(cheapest)); + return(best.algorithm); +} /* end cheapest */ + +/*------------------------------------------------------------------*/ +static void reset ( +) { + transforms.clear(); + initialize(); +} /* end reset */ + +/*------------------------------------------------------------------*/ +static private void initialize ( +) { + new FFTSetupDuoReal(2); + new FFTSetupDuoReal(3); + new FFTSetupDuoReal(5); +} /* end initialize */ + +} /* end class FFTSetupDuoReal */ + +/*==================================================================== +| FFTSetupReal +\===================================================================*/ +static class FFTSetupReal + extends FFTSetup + +{ /* begin class FFTSetupReal */ + +/*.................................................................... + FFTSetupReal static protected variables +....................................................................*/ +protected static final HashMap<Integer, Algorithm> algorithms = + new HashMap<Integer, Algorithm>(); +protected static final HashMap<Integer, Integer> lengths = + new HashMap<Integer, Integer>(); +protected static final HashMap<Integer, FFTSetupReal> transforms = + new HashMap<Integer, FFTSetupReal>(); +protected static final HashMap<Integer, Long> costs = + new HashMap<Integer, Long>(); + +/*.................................................................... + FFTSetupReal static private variables +....................................................................*/ +private static int futurePrime = 7; + +/*.................................................................... + FFTSetupReal protected variables +....................................................................*/ +protected Algorithm algorithm; +protected double[] imConvolverDouble; +protected double[] imUnitRootDouble; +protected double[] imUnitRootEvenDouble; +protected double[] imUnitRootOddDouble; +protected double[] reConvolverDouble; +protected double[] reUnitRootDouble; +protected double[] reUnitRootEvenDouble; +protected double[] reUnitRootOddDouble; +protected float[] imConvolverFloat; +protected float[] imUnitRootEvenFloat; +protected float[] imUnitRootFloat; +protected float[] imUnitRootOddFloat; +protected float[] reConvolverFloat; +protected float[] reUnitRootEvenFloat; +protected float[] reUnitRootFloat; +protected float[] reUnitRootOddFloat; +protected int[] chinese; +protected int[] inverseModular; +protected int[] modular; +protected int[] ruritanian; +protected int K1; + +/*.................................................................... + FFTSetupReal static initialization block +....................................................................*/ +static { + initialize(); +} + +/*.................................................................... + FFTSetupReal constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +FFTSetupReal ( + final int transformLength +) { + super(transformLength); + if (transforms.containsKey(new Integer(transformLength))) { + return; + } + transforms.put(new Integer(transformLength), this); + cost(transformLength); + algorithm = algorithms.get(new Integer(transformLength)); + switch (algorithm) { + case BRUTEFORCE: { + reUnitRootDouble = + DFTBruteForceDouble.getReUnitRoot(transformLength); + imUnitRootDouble = + DFTBruteForceDouble.getImUnitRoot(transformLength); + reUnitRootFloat = + DFTBruteForceFloat.getReUnitRoot(transformLength); + imUnitRootFloat = + DFTBruteForceFloat.getImUnitRoot(transformLength); + break; + } + case COPRIMEFACTOR: { + K1 = lengths.get(new Integer(transformLength)).intValue(); + final int K2 = transformLength / K1; + ruritanian = DFTCoprimeFactor.getRuritanianShuffling(K1, K2); + chinese = + DFTCoprimeFactorReal.getTruncatedChineseRemainderShuffling( + K1, K2); + new FFTSetup(K1); + new FFTSetupReal(K2); + new FFTSetupDuoReal(K2); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + reUnitRootDouble = + DFTEvenRealDouble.getReUnitRoot(transformLength); + imUnitRootDouble = + DFTEvenRealDouble.getImUnitRoot(transformLength); + reUnitRootFloat = + DFTEvenRealFloat.getReUnitRoot(transformLength); + imUnitRootFloat = + DFTEvenRealFloat.getImUnitRoot(transformLength); + new FFTSetup(transformLength >> 1); + break; + } + case LENGTH1: { + break; + } + case LENGTH2: { + break; + } + case LENGTH3: { + break; + } + case LENGTH4: { + break; + } + case LENGTH5: { + break; + } + case LENGTH6: { + break; + } + case LENGTH8: { + break; + } + case MIXEDRADIX: { + K1 = lengths.get(new Integer(transformLength)).intValue(); + final int K2 = transformLength / K1; + reUnitRootDouble = + DFTMixedRadixDouble.getReUnitRoot(transformLength); + imUnitRootDouble = + DFTMixedRadixDouble.getImUnitRoot(transformLength); + reUnitRootFloat = + DFTMixedRadixFloat.getReUnitRoot(transformLength); + imUnitRootFloat = + DFTMixedRadixFloat.getImUnitRoot(transformLength); + new FFTSetup(K1); + new FFTSetupReal(K2); + new FFTSetupDuoReal(K2); + break; + } + case PADDEDRADER: { + final int paddedLength = + lengths.get(new Integer(transformLength)).intValue(); + modular = DFTRader.getModularPowerShuffling(transformLength); + inverseModular = + DFTPaddedRader.getInverseModularPowerShuffling(modular, + paddedLength); + new FFTSetup(paddedLength); + new FFTSetupReal(paddedLength); + final double[][] convolverD = + DFTPaddedRaderDouble.getConvolverReAndIm(modular, + paddedLength); + reConvolverDouble = convolverD[0]; + imConvolverDouble = convolverD[1]; + final float[][] convolverF = + DFTPaddedRaderFloat.getConvolverReAndIm(modular, + paddedLength); + reConvolverFloat = convolverF[0]; + imConvolverFloat = convolverF[1]; + break; + } + case RADER: { + modular = DFTRader.getModularPowerShuffling(transformLength); + inverseModular = DFTRader.getInverseModularPowerShuffling(modular); + new FFTSetup(transformLength - 1); + new FFTSetupReal(transformLength - 1); + final double[][] convolverD = + DFTRaderDouble.getConvolverReAndIm(modular); + reConvolverDouble = convolverD[0]; + imConvolverDouble = convolverD[1]; + final float[][] convolverF = + DFTRaderFloat.getConvolverReAndIm(modular); + reConvolverFloat = convolverF[0]; + imConvolverFloat = convolverF[1]; + break; + } + case RADIX2: { + reUnitRootEvenDouble = + DFTRadix2RealDouble.getReUnitRootEven(transformLength); + imUnitRootEvenDouble = + DFTRadix2RealDouble.getImUnitRootEven(transformLength); + reUnitRootOddDouble = + DFTRadix2RealDouble.getReUnitRootOdd(transformLength); + imUnitRootOddDouble = + DFTRadix2RealDouble.getImUnitRootOdd(transformLength); + reUnitRootEvenFloat = + DFTRadix2RealFloat.getReUnitRootEven(transformLength); + imUnitRootEvenFloat = + DFTRadix2RealFloat.getImUnitRootEven(transformLength); + reUnitRootOddFloat = + DFTRadix2RealFloat.getReUnitRootOdd(transformLength); + imUnitRootOddFloat = + DFTRadix2RealFloat.getImUnitRootOdd(transformLength); + new FFTSetupDuoReal(transformLength >> 1); + break; + } + case SPLITRADIX: { + reUnitRootDouble = + DFTSplitRadixDouble.getReUnitRoot(transformLength); + imUnitRootDouble = + DFTSplitRadixDouble.getImUnitRoot(transformLength); + reUnitRootFloat = + DFTSplitRadixFloat.getReUnitRoot(transformLength); + imUnitRootFloat = + DFTSplitRadixFloat.getImUnitRoot(transformLength); + new FFTSetupReal(transformLength >> 1); + new FFTSetupDuoReal(transformLength >> 2); + break; + } + } +} /* end FFTSetupReal */ + +/*.................................................................... + FFTSetupReal static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +static long cost ( + final int transformLength +) { + if (costs.containsKey(new Integer(transformLength))) { + return(costs.get(new Integer(transformLength)).longValue()); + } + final Vector<FFTCostPrediction> costPredictions = + new Vector<FFTCostPrediction>(); + switch (transformLength) { + case 1: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH1, -1, 0L)); + break; + } + case 2: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH2, -1, DFTLength2Real.cost())); + break; + } + case 3: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH3, -1, DFTLength3Real.cost())); + break; + } + case 4: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH4, -1, DFTLength4Real.cost())); + break; + } + case 5: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH5, -1, DFTLength5Real.cost())); + break; + } + case 6: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH6, -1, DFTLength6Real.cost())); + break; + } + case 8: { + costPredictions.add(new FFTCostPrediction( + Algorithm.LENGTH8, -1, DFTLength8Real.cost())); + break; + } + default: { + final HashSet<Integer> divisors = + FFTSetup.divisors(transformLength); + if (divisors.isEmpty()) { + costPredictions.add(new FFTCostPrediction( + Algorithm.RADER, -1, DFTRaderReal.cost(transformLength))); + while (futurePrime < transformLength) { + cost(futurePrime); + } + do { + futurePrime +=2; + } while (!FFTSetup.isPrime(futurePrime)); + int minPaddedLength = 2 * transformLength - 3; + int maxPaddedLength = 1; + int n = minPaddedLength; + while (0 < n) { + n >>= 1; + maxPaddedLength <<= 1; + } + for (n = transformLength; (n < minPaddedLength); n += 2) { + if (costs.containsKey(new Integer(n))) { + continue; + } + if (FFTSetup.isPrime(n)) { + taboos.add(new Integer(n)); + taboos.add(new Integer(2 * n)); + taboos.add(new Integer(3 * n)); + } + } + for (n = minPaddedLength; (n <= maxPaddedLength); n += 2) { + if (costs.containsKey(new Integer(n))) { + continue; + } + if (FFTSetup.isPrime(n)) { + taboos.add(new Integer(n)); + taboos.add(new Integer(2 * n)); + } + } + for (n = minPaddedLength; (n <= maxPaddedLength); n++) { + costPredictions.add(new FFTCostPrediction( + Algorithm.PADDEDRADER, n, + DFTPaddedRaderReal.cost(transformLength, n))); + } + taboos.clear(); + } + else { + for (Integer d: divisors) { + final int K1 = d.intValue(); + final int K2 = transformLength / K1; + costPredictions.add(new FFTCostPrediction( + Algorithm.MIXEDRADIX, K1, + DFTMixedRadixReal.cost(K1, K2))); + if (1 == FFTSetup.greatestCommonDivisor(K1, K2)) { + costPredictions.add(new FFTCostPrediction( + Algorithm.COPRIMEFACTOR, K1, + DFTCoprimeFactorReal.cost(K1, K2))); + } + if (2 == K1) { + costPredictions.add(new FFTCostPrediction( + Algorithm.EVENREAL, -1, + DFTEvenReal.cost(transformLength))); + costPredictions.add(new FFTCostPrediction( + Algorithm.RADIX2, -1, + DFTRadix2Real.cost(transformLength))); + } + if (4 == K1) { + costPredictions.add(new FFTCostPrediction( + Algorithm.SPLITRADIX, -1, + DFTSplitRadixReal.cost(transformLength))); + } + } + } + } + } + FFTCostPrediction best = new FFTCostPrediction( + Algorithm.BRUTEFORCE, -1, DFTBruteForceReal.cost(transformLength)); + long cheapest = best.cost; + for (FFTCostPrediction predicted: costPredictions) { + final long current = predicted.cost; + if (0L <= current) { + if (current < cheapest) { + cheapest = current; + best = predicted; + } + } + } + algorithms.put(new Integer(transformLength), best.algorithm); + lengths.put(new Integer(transformLength), new Integer(best.length)); + costs.put(new Integer(transformLength), new Long(cheapest)); + return(cheapest); +} /* end cost */ + +/*------------------------------------------------------------------*/ +static void reset ( +) { + algorithms.clear(); + lengths.clear(); + transforms.clear(); + costs.clear(); + initialize(); +} /* end reset */ + +/*------------------------------------------------------------------*/ +static private void initialize ( +) { + new FFTSetupReal(2); + new FFTSetupReal(3); + new FFTSetupReal(5); + futurePrime = 7; +} /* end initialize */ + +} /* end class FFTSetupReal */ + +/*.................................................................... + SlowFourierTransform constructors +....................................................................*/ +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This constructor prepares a one-dimensional Fourier transform. It + depends on the length of the sequence but not on the actual data + being transformed, so that it can be reused for different data. + It specifies the convention to adopt for locating the origin of the + Fourier transform. + </p> + @param width The length of the sequence. + @param fourierOrigin1 The origin of the Fourier transform in the + Fourier domain. + ********************************************************************/ +public AcademicFourierTransform ( + final int width, + final int fourierOrigin1 +) { + if (width <= 0) { + throw(new IllegalArgumentException()); + } + this.width = new Integer(width); + this.height = new Integer(1); + this.depth = new Integer(1); + this.fourierOrigin1 = fourierOrigin1; + this.fourierOrigin2 = 0; + this.fourierOrigin3 = 0; + dimensions = 1; + dataLength = width; + new FFTSetup(width); + new FFTSetupReal(width); + new FFTSetupDuoReal(width); + firstDimension = 1; +} /* end SlowFourierTransform */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This constructor prepares a two-dimensional Fourier transform. It + depends on the width and height of the image but not on the actual + data being transformed, so that it can be reused for different data. + It specifies the convention to adopt for locating the origin of the + Fourier transform. + </p> + @param width The width of the image. + @param height The height of the image. + @param fourierOrigin1 The horizontal component of the origin of the + Fourier transform in the Fourier domain. + @param fourierOrigin2 The vertical component of the origin of the + Fourier transform in the Fourier domain. + ********************************************************************/ +public AcademicFourierTransform ( + final int width, + final int height, + final int fourierOrigin1, + final int fourierOrigin2 +) { + if ((width <= 0) || (height <= 0)) { + throw(new IllegalArgumentException()); + } + this.width = new Integer(width); + this.height = new Integer(height); + this.depth = new Integer(1); + this.fourierOrigin1 = fourierOrigin1; + this.fourierOrigin2 = fourierOrigin2; + this.fourierOrigin3 = 0; + dimensions = 2; + dataLength = width * height; + new FFTSetup(width); + new FFTSetupReal(width); + new FFTSetupDuoReal(width); + new FFTSetup(height); + new FFTSetupReal(height); + new FFTSetupDuoReal(height); + final long K1 = (long)width; + final long K2 = (long)height; + final long k1 = K1 >> 1L; + final long k2 = K2 >> 1L; + final long costColumnFirst = FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * (k2 * 1L + k2 * ((K1 - 1L) * 1L)) + + FFTSetup.FLASSIGN * (k2 * 2L + k2 * ((K1 - 1L) * 2L)) + + FFTSetup.INTALLOC * 10L + + FFTSetup.INTOP * (5L + K1 * 2L + 1L + (k2 + 1L) * 3L + 2L + + k2 * 3L + 3L + k2 * (4L + (K1 - 1L) * 4L)) + + FFTSetup.INTASSIGN * (4L + K1 * 1L + 2L + (k2 + 1L) * 2L + 2L + + k2 * 2L + 3L + k2 * (6L + (K1 - 1L) * 3L)) + + FFTSetup.IDX * (k2 * 4L + k2 * ((K1 - 1L) * 4L)) + + FFTSetup.NEWOBJ * (K1 + (k2 + 1L)) + + k1 * FFTSetupDuoReal.cost(height) + + (k2 + 1L) * FFTSetup.cost(width); + final long costRowFirst = FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * (k1 * 1L + (K2 - 1L) * (k1 * 1L)) + + FFTSetup.FLASSIGN * (k1 * 2L + (K2 - 1L) * (k1 * 2L)) + + FFTSetup.INTALLOC * 9L + + FFTSetup.INTOP * (5L + K2 * 3L + 1L + (k1 + 1L) * 2L + + k1 * 3L + 3L + (K2 - 1L) * (4L + k1 * 4L)) + + FFTSetup.INTASSIGN * (5L + K2 * 2L + 1L + (k1 + 1L) * 1L + 2L + + k1 * 2L + 3L + (K2 - 1L) * (6L + k1 * 3L)) + + FFTSetup.IDX * (k1 * 4L + (K2 - 1L) * (k1 * 4L)) + + FFTSetup.NEWOBJ * (K2 + (k1 + 1L)) + + k2 * FFTSetupDuoReal.cost(width) + + (k1 + 1L) * FFTSetup.cost(height); + firstDimension = (costRowFirst < costColumnFirst) ? (1) : (2); +} /* end SlowFourierTransform */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This constructor prepares a three-dimensional Fourier transform. It + depends on the width, height, and depth of the volume but not on the + actual data being transformed, so that it can be reused for different + data. It specifies the convention to adopt for locating the origin of + the Fourier transform. + </p> + @param width The width of the volume. + @param height The height of the volume. + @param depth The depth of the volume. + @param fourierOrigin1 The horizontal component of the origin of the + Fourier transform in the Fourier domain. + @param fourierOrigin2 The vertical component of the origin of the + Fourier transform in the Fourier domain. + @param fourierOrigin3 The depth component of the origin of the + Fourier transform in the Fourier domain. + ********************************************************************/ +public AcademicFourierTransform ( + final int width, + final int height, + final int depth, + final int fourierOrigin1, + final int fourierOrigin2, + final int fourierOrigin3 +) { + if ((width <= 0) || (height <= 0) || (depth <= 0)) { + throw(new IllegalArgumentException()); + } + this.width = new Integer(width); + this.height = new Integer(height); + this.depth = new Integer(depth); + this.fourierOrigin1 = fourierOrigin1; + this.fourierOrigin2 = fourierOrigin2; + this.fourierOrigin3 = fourierOrigin3; + dimensions = 3; + dataLength = width * height* depth; + new FFTSetup(width); + new FFTSetupReal(width); + new FFTSetupDuoReal(width); + new FFTSetup(height); + new FFTSetupReal(height); + new FFTSetupDuoReal(height); + new FFTSetup(depth); + new FFTSetupReal(depth); + new FFTSetupDuoReal(depth); + final long K1 = (long)width; + final long K2 = (long)height; + final long K3 = (long)depth; + final long k1 = K1 >> 1L; + final long k2 = K2 >> 1L; + final long k3 = K3 >> 1L; + final long costAcrossFirst = FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * (k3 * 1L + k3 * ((K2 - 1L) * 1L) + + k3 * ((K1 - 1L) * 1L) + k3 * ((K2 - 1L) * ((K1 - 1L) * 1L))) + + FFTSetup.FLASSIGN * (k3 * 2L + k3 * ((K2 - 1L) * 2L) + + k3 * ((K1 - 1L) * 2L) + k3 * ((K2 - 1L) * ((K1 - 1L) * 2L))) + + FFTSetup.INTALLOC * 23L + + FFTSetup.INTOP * (6L + K2 * K1 * 2L + 1L + (k3 + 1L) * (2L + K2 * 3L) + + 1L + (k3 + 1L) * (3L + K1 * 3L) + 1L + k3 * 3L + 2L + + k3 * (4L + (K2 - 1L) * 4L) + 5L + k3 * (4L + (K1 - 1L) * 4L) + 3L + + k3 * (4L + (K2 - 1L) * (4L + (K1 - 1L) * 4L))) + + FFTSetup.INTASSIGN * (6L + K2 * K1 * 1L + 2L + + (k3 + 1L) * (2L + K2 * 2L) + 2L + (k3 + 1L) * (3L + K1 * 1L) + 2L + + k3 * 2L + 3L + k3 * (6L + (K2 - 1L) * 3L) + 3L + + k3 * (6L + (K1 - 1L) * 3L) + 3L + + k3 * (4L + (K2 - 1L) * (4L + (K1 - 1L) * 3L))) + + FFTSetup.IDX * (k3 * 4L + k3 * ((K2 - 1L) * 4L) + + k3 * ((K1 - 1L) * 4L) + k3 * ((K2 - 1L) * ((K1 - 1L) * 4L))) + + FFTSetup.NEWOBJ * (K2 * K1 + (k3 + 1L) * K2+ (k3 + 1L) * K1) + + ((K2 * K1) >> 1) * FFTSetupDuoReal.cost(depth) + + (k3 + 1L) * K2 * FFTSetup.cost(width) + + (k3 + 1L) * K1 * FFTSetup.cost(height); + final long costColumnFirst = FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * (k2 * 1L + k2 * ((K2 - 1L) * 1L) + + (K3 - 1L) * (k2 * 1L) + (K3 - 1L) * (k2 * ((K1 - 1L) * 1L))) + + FFTSetup.FLASSIGN * (k2 * 2L + k2 * ((K1 - 1L) * 2L) + + (K3 - 1L) * (k2 * 2L) + (K3 - 1L) * (k2 * ((K1 - 1L) * 2L))) + + FFTSetup.INTALLOC * 26L + + FFTSetup.INTOP * (8L + K3 * K1 * 5L + 3L + K3 * (3L + (k2 + 1L) * 3L) + + 1L + (k2 + 1L) * (2L + K1 * 3L) + 1L + k2 * 3L + 2L + + k2 * (4L + (K1 - 1L) * 4L) + 3L + (K3 - 1L) * (4L + k2 * 4L) + 3L + + (K3 - 1L) * (6L + k2 * (4L + (K1 - 1L) * 4L))) + + FFTSetup.INTASSIGN * (8L + K3 * K1 * 1L + 3L + + K3 * (3L + (k2 + 1L) * 2L) + 2L + (k2 + 1L) * (2L + K1 * 2L) + 2L + + k2 * 2L + 3L + k2 * (6L + (K1 - 1L) * 3L) + 3L + + (K3 - 1L) * (6L + k2 * 3L) + 3L + + (K3 - 1L) * (4L + k2 * (4L + (K1 - 1L) * 3L))) + + FFTSetup.IDX * (k2 * 4L + k2 * ((K1 - 1L) * 4L) + + (K3 - 1L) * (k2 * 4L) + (K3 - 1L) * (k2 * ((K1 - 1L) * 4L))) + + FFTSetup.NEWOBJ * (K3 * K1 + K3 * (k2 + 1L) + (k2 + 1L) * K1) + + ((K3 * K1) >> 1) * FFTSetupDuoReal.cost(height) + + K3 * (k2 + 1L) * FFTSetup.cost(width) + + (k2 + 1L) * K1 * FFTSetup.cost(depth); + final long costRowFirst = FFTSetup.FLALLOC * 0L + + FFTSetup.FLOP * (k1 * 1L + (K2 - 1L) * (k1 * 1L) + + (K3 - 1L) * (k1 * 1L) + (K3 - 1L) * ((K2 - 1L) * (k1 * 1L))) + + FFTSetup.FLASSIGN * (k1 * 2L + (K2 - 1L) * (k1 * 2L) + + (K3 - 1L) * (k1 * 2L) + (K3 - 1L) * ((K2 - 1L) * (k1 * 2L))) + + FFTSetup.INTALLOC * 22L + + FFTSetup.INTOP * (7L + K3 * K2 * 3L + 1L + K3 * (3L + (k1 + 1L) * 3L) + + 1L + K2 * (3L + (k1 + 1L) * 3L) + k1 * 3L + 2L + + (K2 - 1L) * (4L + k1 * 4L) + 5L + (K3 - 1L) * (4L + k1 * 4L) + 3L + + (K3 - 1L) * (4L + (K2 - 1L) * (4L + k1 * 4L))) + + FFTSetup.INTASSIGN * (8L + K3 * K2 * 2L + 2L + + K3 * (3L + (k1 + 1L) * 1L) + 2L + K2 * (3L + (k1 + 1L) * 1L) + 2L + + k1 * 2L + 3L + (K2 - 1L) * (6L + k1 * 3L) + 3L + + (K3 - 1L) * (6L + k1 * 3L) + 3L + + (K3 - 1L) * (4L + (K2 - 1L) * (4L + k1 * 3L))) + + FFTSetup.IDX * (k1 * 4L + (K2 - 1L) * (k1 * 4L) + + (K3 - 1L) * (k1 * 4L) + (K3 - 1L) * ((K2 - 1L) * (k1 * 4L))) + + FFTSetup.NEWOBJ * (K3 * K2 + K3 * (k1 + 1L) + K2 * (k1 + 1L)) + + ((K3 * K2) >> 1) * FFTSetupDuoReal.cost(width) + + K3 * (k1 + 1L) * FFTSetup.cost(height) + + K2 * (k1 + 1L) * FFTSetup.cost(depth); + firstDimension = (costRowFirst < costColumnFirst) + ? ((costRowFirst < costAcrossFirst) ? (1) : (3)) + : ((costColumnFirst < costAcrossFirst) ? (2) : (3)); +} /* end SlowFourierTransform */ + +/*.................................................................... + SlowFourierTransform static methods +....................................................................*/ +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method converts complex data from an amplitude-phase + representation to a real-imaginary representation. The phase is + assumed to be provided in radian units. + </p> + @param amToRe At input, the amplitude of the data; at output, the + real part of the data. The processing is in-place. + @param phToIm At input, the phase of the data; at output, the + imaginary part of the data. The processing is in-place. + ********************************************************************/ +static public void amplitudePhaseToRealImaginary ( + final double[] amToRe, + final double[] phToIm +) { + if (amToRe.length != phToIm.length) { + throw(new IllegalArgumentException()); + } + for (int k = 0, K = amToRe.length; (k < K); k++) { + final double am = amToRe[k]; + final double ph = phToIm[k]; + amToRe[k] = am * cos(ph); + phToIm[k] = am * sin(ph); + } +} /* end amplitudePhaseToRealImaginary */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method converts complex data from an amplitude-phase + representation to a real-imaginary representation. The phase is + assumed to be provided in radian units. + </p> + @param amToRe At input, the amplitude of the data; at output, the + real part of the data. The processing is in-place. + @param phToIm At input, the phase of the data; at output, the + imaginary part of the data. The processing is in-place. + ********************************************************************/ +static public void amplitudePhaseToRealImaginary ( + final float[] amToRe, + final float[] phToIm +) { + if (amToRe.length != phToIm.length) { + throw(new IllegalArgumentException()); + } + for (int k = 0, K = amToRe.length; (k < K); k++) { + final float am = amToRe[k]; + final float ph = phToIm[k]; + amToRe[k] = am * (float)cos((double)ph); + phToIm[k] = am * (float)sin((double)ph); + } +} /* end amplitudePhaseToRealImaginary */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method converts complex data from a real-imaginary + representation to an amplitude-phase representation. The resulting + phase is provided in radian units in the range [−π, + π]. + </p> + @param reToAm At input, the real part of the data; at output, the + amplitude of the data. The processing is in-place. + @param imToPh At input, the imaginary part of the data; at output, + the phase of the data. The processing is in-place. + ********************************************************************/ +static public void realImaginaryToAmplitudePhase ( + final double[] reToAm, + final double[] imToPh +) { + if (reToAm.length != imToPh.length) { + throw(new IllegalArgumentException()); + } + for (int k = 0, K = reToAm.length; (k < K); k++) { + final double am = sqrt(reToAm[k] * reToAm[k] + imToPh[k] * imToPh[k]); + final double ph = atan2(imToPh[k], reToAm[k]); + reToAm[k] = am; + imToPh[k] = ph; + } +} /* end realImaginaryToAmplitudePhase */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method converts complex data from a real-imaginary + representation to an amplitude-phase representation. The resulting + phase is provided in radian units in the range [−π, + π]. + </p> + @param reToAm At input, the real part of the data; at output, the + amplitude of the data. The processing is in-place. + @param imToPh At input, the imaginary part of the data; at output, + the phase of the data. The processing is in-place. + ********************************************************************/ +static public void realImaginaryToAmplitudePhase ( + final float[] reToAm, + final float[] imToPh +) { + if (reToAm.length != imToPh.length) { + throw(new IllegalArgumentException()); + } + for (int k = 0, K = reToAm.length; (k < K); k++) { + final float am = (float)sqrt((double)(reToAm[k] * reToAm[k] + + imToPh[k] * imToPh[k])); + final float ph = (float)atan2((double)imToPh[k], (double)reToAm[k]); + reToAm[k] = am; + imToPh[k] = ph; + } +} /* end realImaginaryToAmplitudePhase */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + Several <code>static</code> auxiliary data are stored by this class, + as needs arise, to be reused by subsequent instances of this class; + this method frees the associated memory. + </p> + ********************************************************************/ +static public void reset ( +) { + FFTSetup.reset(); + FFTSetupReal.reset(); + FFTSetupDuoReal.reset(); +} /* end reset */ + +/*.................................................................... + SlowFourierTransform public methods +....................................................................*/ +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method computes the circular convolution of data provided in a + real-imaginary representation. The number of dimensions of the data + is determined by the constructor of this object. Likewise, the + dimensions themselves must match those provided to the constructor of + this object. + </p> + @param reData1 At input, the real part of the first operand; at + output, the real part of the convolution result. The processing is + in-place. + @param imData1 At input, the imaginary part of the first operand; at + output, the imaginary part of the convolution result. The processing + is in-place. + @param reData2 At input, the real part of the second operand; at + output, the real part of the Fourier transform of the second operand. + The origin of the Fourier transform of the second operand follows the + conventions for this object. The processing is in-place. + @param imData2 At input, the imaginary part of the second operand; at + output, the imaginary part of the Fourier transform of the second + operand. The origin of the Fourier transform of the second operand + follows the conventions for this object. The processing is in-place. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData1.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData1.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + ********************************************************************/ +public void circularConvolution ( + final double[] reData1, + final double[] imData1, + final double[] reData2, + final double[] imData2, + double[] reBuffer, + double[] imBuffer +) { + if (null == reBuffer) { + reBuffer = new double[reData1.length]; + } + if (null == imBuffer) { + imBuffer = new double[imData1.length]; + } + if ((reData1.length != dataLength) + || (imData1.length != dataLength) + || (reData2.length != dataLength) + || (imData2.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reBufferDouble = reBuffer; + this.imBufferDouble = imBuffer; + this.reDataDouble = reData2; + this.imDataDouble = imData2; + transformDouble(InputDataType.COMPLEXINPUT); + this.reDataDouble = reData1; + this.imDataDouble = imData1; + transformDouble(InputDataType.COMPLEXINPUT); + final double norm = 1.0 / (double)dataLength; + for (int k = 0; (k < dataLength); k++) { + final double re1 = norm * reData1[k]; + final double im1 = norm * imData1[k]; + reData1[k] = re1 * reData2[k] - im1 * imData2[k]; + imData1[k] = re1 * imData2[k] + im1 * reData2[k]; + } + reverseDouble(); + transformDouble(InputDataType.COMPLEXINPUT); + this.reDataDouble = reData2; + this.imDataDouble = imData2; + this.reBufferDouble = reBuffer; + this.imBufferDouble = imBuffer; + switch (dimensions) { + case 1: { + shiftDouble(fourierOrigin1); + break; + } + case 2: { + shiftDouble(fourierOrigin1, fourierOrigin2); + break; + } + case 3: { + shiftDouble(fourierOrigin1, fourierOrigin2, fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } +} /* end circularConvolution */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method computes the circular convolution of data provided in a + real-imaginary representation. The number of dimensions of the data + is determined by the constructor of this object. Likewise, the + dimensions themselves must match those provided to the constructor of + this object. + </p> + @param reData1 At input, the real part of the first operand; at + output, the real part of the convolution result. The processing is + in-place. + @param imData1 At input, the imaginary part of the first operand; at + output, the imaginary part of the convolution result. The processing + is in-place. + @param reData2 At input, the real part of the second operand; at + output, the real part of the Fourier transform of the second operand. + The origin of the Fourier transform of the second operand follows the + conventions for this object. The processing is in-place. + @param imData2 At input, the imaginary part of the second operand; at + output, the imaginary part of the Fourier transform of the second + operand. The origin of the Fourier transform of the second operand + follows the conventions for this object. The processing is in-place. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData1.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData1.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + ********************************************************************/ +public void circularConvolution ( + final float[] reData1, + final float[] imData1, + final float[] reData2, + final float[] imData2, + float[] reBuffer, + float[] imBuffer +) { + if (null == reBuffer) { + reBuffer = new float[reData1.length]; + } + if (null == imBuffer) { + imBuffer = new float[imData1.length]; + } + if ((reData1.length != dataLength) + || (imData1.length != dataLength) + || (reData2.length != dataLength) + || (imData2.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reBufferFloat = reBuffer; + this.imBufferFloat = imBuffer; + this.reDataFloat = reData2; + this.imDataFloat = imData2; + transformFloat(InputDataType.COMPLEXINPUT); + this.reDataFloat = reData1; + this.imDataFloat = imData1; + transformFloat(InputDataType.COMPLEXINPUT); + final float norm = 1.0F / (float)dataLength; + for (int k = 0; (k < dataLength); k++) { + final float re1 = norm * reData1[k]; + final float im1 = norm * imData1[k]; + reData1[k] = re1 * reData2[k] - im1 * imData2[k]; + imData1[k] = re1 * imData2[k] + im1 * reData2[k]; + } + reverseFloat(); + transformFloat(InputDataType.COMPLEXINPUT); + this.reDataFloat = reData2; + this.imDataFloat = imData2; + this.reBufferFloat = reBuffer; + this.imBufferFloat = imBuffer; + switch (dimensions) { + case 1: { + shiftFloat(fourierOrigin1); + break; + } + case 2: { + shiftFloat(fourierOrigin1, fourierOrigin2); + break; + } + case 3: { + shiftFloat(fourierOrigin1, fourierOrigin2, fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } +} /* end circularConvolution */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method computes the circular convolution of data; the first + operand is provided in a real-imaginary representation while the + second operand is provided in a real-imaginary Fourier + representation. The number of dimensions of the data is determined by + the constructor of this object. Likewise, the dimensions themselves + must match those provided to the constructor of this object. + </p> + @param reData1 At input, the real part of the first operand; at + output, the real part of the convolution result. The processing is + in-place. + @param imData1 At input, the imaginary part of the first operand; at + output, the imaginary part of the convolution result. The processing + is in-place. + @param reFourierData2 Real part of the Fourier transform of the + second operand. The origin of the Fourier transform of the second + operand follows the conventions for this object. + @param imFourierData2 Imaginary part of the Fourier transform of the + second operand. The origin of the Fourier transform of the second + operand follows the conventions for this object. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData1.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData1.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + ********************************************************************/ +public void circularFourierConvolution ( + final double[] reData1, + final double[] imData1, + final double[] reFourierData2, + final double[] imFourierData2, + double[] reBuffer, + double[] imBuffer +) { + if (null == reBuffer) { + reBuffer = new double[reData1.length]; + } + if (null == imBuffer) { + imBuffer = new double[imData1.length]; + } + if ((reData1.length != dataLength) + || (imData1.length != dataLength) + || (reFourierData2.length != dataLength) + || (imFourierData2.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reBufferDouble = reBuffer; + this.imBufferDouble = imBuffer; + this.reDataDouble = reData1; + this.imDataDouble = imData1; + transformDouble(InputDataType.COMPLEXINPUT); + switch (dimensions) { + case 1: { + shiftDouble(fourierOrigin1); + break; + } + case 2: { + shiftDouble(fourierOrigin1, fourierOrigin2); + break; + } + case 3: { + shiftDouble(fourierOrigin1, fourierOrigin2, fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } + final double norm = 1.0 / (double)dataLength; + for (int k = 0; (k < dataLength); k++) { + final double re1 = norm * reData1[k]; + final double im1 = norm * imData1[k]; + reData1[k] = re1 * reFourierData2[k] - im1 * imFourierData2[k]; + imData1[k] = re1 * imFourierData2[k] + im1 * reFourierData2[k]; + } + switch (dimensions) { + case 1: { + shiftDouble(-fourierOrigin1); + break; + } + case 2: { + shiftDouble(-fourierOrigin1, -fourierOrigin2); + break; + } + case 3: { + shiftDouble(-fourierOrigin1, -fourierOrigin2, -fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } + reverseDouble(); + transformDouble(InputDataType.COMPLEXINPUT); +} /* circularFourierConvolution */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method computes the circular convolution of data; the first + operand is provided in a real-imaginary representation while the + second operand is provided in a real-imaginary Fourier + representation. The number of dimensions of the data is determined by + the constructor of this object. Likewise, the dimensions themselves + must match those provided to the constructor of this object. + </p> + @param reData1 At input, the real part of the first operand; at + output, the real part of the convolution result. The processing is + in-place. + @param imData1 At input, the imaginary part of the first operand; at + output, the imaginary part of the convolution result. The processing + is in-place. + @param reFourierData2 Real part of the Fourier transform of the + second operand. The origin of the Fourier transform of the second + operand follows the conventions for this object. + @param imFourierData2 Imaginary part of the Fourier transform of the + second operand. The origin of the Fourier transform of the second + operand follows the conventions for this object. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData1.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData1.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + ********************************************************************/ +public void circularFourierConvolution ( + final float[] reData1, + final float[] imData1, + final float[] reFourierData2, + final float[] imFourierData2, + float[] reBuffer, + float[] imBuffer +) { + if (null == reBuffer) { + reBuffer = new float[reData1.length]; + } + if (null == imBuffer) { + imBuffer = new float[imData1.length]; + } + if ((reData1.length != dataLength) + || (imData1.length != dataLength) + || (reFourierData2.length != dataLength) + || (imFourierData2.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reBufferFloat = reBuffer; + this.imBufferFloat = imBuffer; + this.reDataFloat = reData1; + this.imDataFloat = imData1; + transformFloat(InputDataType.COMPLEXINPUT); + switch (dimensions) { + case 1: { + shiftFloat(fourierOrigin1); + break; + } + case 2: { + shiftFloat(fourierOrigin1, fourierOrigin2); + break; + } + case 3: { + shiftFloat(fourierOrigin1, fourierOrigin2, fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } + final float norm = 1.0F / (float)dataLength; + for (int k = 0; (k < dataLength); k++) { + final float re1 = norm * reData1[k]; + final float im1 = norm * imData1[k]; + reData1[k] = re1 * reFourierData2[k] - im1 * imFourierData2[k]; + imData1[k] = re1 * imFourierData2[k] + im1 * reFourierData2[k]; + } + switch (dimensions) { + case 1: { + shiftFloat(-fourierOrigin1); + break; + } + case 2: { + shiftFloat(-fourierOrigin1, -fourierOrigin2); + break; + } + case 3: { + shiftFloat(-fourierOrigin1, -fourierOrigin2, -fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } + reverseFloat(); + transformFloat(InputDataType.COMPLEXINPUT); +} /* circularFourierConvolution */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method computes the Fourier transform of data provided in a + real-imaginary representation. The number of dimensions of the data + is determined by the constructor of this object. Likewise, the + dimensions themselves must match those provided to the constructor of + this object. + </p> + @param reData At input, the real part of the data; at output, the + real part of the Fourier transform of the data. The processing is + in-place. + @param imData At input, the imaginary part of the data; at output, + the imaginary part of the Fourier transform of the data. The + processing is in-place. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + @param inputDataType When set to + <code>SlowFourierTransform.InputDataType.REALINPUT</code>, disregards + the values provided in <code>imData</code> and assumes that every + element of <code>imData</code> is <code>0.0</code>; when set to + <code>SlowFourierTransform.InputDataType.COMPLEXINPUT</code>, honors + the values provided in <code>imData</code>. + ********************************************************************/ +public void directTransform ( + final double[] reData, + final double[] imData, + double[] reBuffer, + double[] imBuffer, + final InputDataType inputDataType +) { + if (null == reBuffer) { + reBuffer = new double[reData.length]; + } + if (null == imBuffer) { + imBuffer = new double[imData.length]; + } + if ((reData.length != dataLength) + || (imData.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reDataDouble = reData; + this.imDataDouble = imData; + this.reBufferDouble = reBuffer; + this.imBufferDouble = imBuffer; + transformDouble(inputDataType); + switch (dimensions) { + case 1: { + shiftDouble(fourierOrigin1); + break; + } + case 2: { + shiftDouble(fourierOrigin1, fourierOrigin2); + break; + } + case 3: { + shiftDouble(fourierOrigin1, fourierOrigin2, fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } +} /* end directTransform */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method computes the Fourier transform of data provided in a + real-imaginary representation. The number of dimensions of the data + is determined by the constructor of this object. Likewise, the + dimensions themselves must match those provided to the constructor of + this object. + </p> + @param reData At input, the real part of the data; at output, the + real part of the Fourier transform of the data. The processing is + in-place. + @param imData At input, the imaginary part of the data; at output, + the imaginary part of the Fourier transform of the data. The + processing is in-place. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + @param inputDataType When set to + <code>SlowFourierTransform.InputDataType.REALINPUT</code>, disregards + the values provided in <code>imData</code> and assumes that every + element of <code>imData</code> is <code>0.0</code>; when set to + <code>SlowFourierTransform.InputDataType.COMPLEXINPUT</code>, honors + the values provided in <code>imData</code>. + ********************************************************************/ +public void directTransform ( + final float[] reData, + final float[] imData, + float[] reBuffer, + float[] imBuffer, + final InputDataType inputDataType +) { + if (null == reBuffer) { + reBuffer = new float[reData.length]; + } + if (null == imBuffer) { + imBuffer = new float[imData.length]; + } + if ((reData.length != dataLength) + || (imData.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reDataFloat = reData; + this.imDataFloat = imData; + this.reBufferFloat = reBuffer; + this.imBufferFloat = imBuffer; + transformFloat(inputDataType); + switch (dimensions) { + case 1: { + shiftFloat(fourierOrigin1); + break; + } + case 2: { + shiftFloat(fourierOrigin1, fourierOrigin2); + break; + } + case 3: { + shiftFloat(fourierOrigin1, fourierOrigin2, fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } +} /* end directTransform */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method computes the inverse Fourier transform of data provided + in a real-imaginary representation. The number of dimensions of the + data is determined by the constructor of this object. Likewise, the + dimensions themselves must match those provided to the constructor of + this object. + </p> + @param reData At input, the real part of the data; at output, the + real part of the Fourier transform of the data. The processing is + in-place. + @param imData At input, the imaginary part of the data; at output, + the imaginary part of the Fourier transform of the data. The + processing is in-place. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + ********************************************************************/ +public void inverseTransform ( + final double[] reData, + final double[] imData, + double[] reBuffer, + double[] imBuffer +) { + if (null == reBuffer) { + reBuffer = new double[reData.length]; + } + if (null == imBuffer) { + imBuffer = new double[imData.length]; + } + if ((reData.length != dataLength) + || (imData.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reDataDouble = reData; + this.imDataDouble = imData; + this.reBufferDouble = reBuffer; + this.imBufferDouble = imBuffer; + final double norm = 1.0 / (double)dataLength; + for (int k = 0; (k < dataLength); k++) { + reData[k] *= norm; + imData[k] *= norm; + } + switch (dimensions) { + case 1: { + shiftDouble(-fourierOrigin1); + break; + } + case 2: { + shiftDouble(-fourierOrigin1, -fourierOrigin2); + break; + } + case 3: { + shiftDouble(-fourierOrigin1, -fourierOrigin2, -fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } + reverseDouble(); + transformDouble(InputDataType.COMPLEXINPUT); +} /* end inverseTransform */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method computes the inverse Fourier transform of data provided + in a real-imaginary representation. The number of dimensions of the + data is determined by the constructor of this object. Likewise, the + dimensions themselves must match those provided to the constructor of + this object. + </p> + @param reData At input, the real part of the data; at output, the + real part of the Fourier transform of the data. The processing is + in-place. + @param imData At input, the imaginary part of the data; at output, + the imaginary part of the Fourier transform of the data. The + processing is in-place. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + ********************************************************************/ +public void inverseTransform ( + final float[] reData, + final float[] imData, + float[] reBuffer, + float[] imBuffer +) { + if (null == reBuffer) { + reBuffer = new float[reData.length]; + } + if (null == imBuffer) { + imBuffer = new float[imData.length]; + } + if ((reData.length != dataLength) + || (imData.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reDataFloat = reData; + this.imDataFloat = imData; + this.reBufferFloat = reBuffer; + this.imBufferFloat = imBuffer; + final float norm = 1.0F / (float)dataLength; + for (int k = 0; (k < dataLength); k++) { + reData[k] *= norm; + imData[k] *= norm; + } + switch (dimensions) { + case 1: { + shiftFloat(-fourierOrigin1); + break; + } + case 2: { + shiftFloat(-fourierOrigin1, -fourierOrigin2); + break; + } + case 3: { + shiftFloat(-fourierOrigin1, -fourierOrigin2, -fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } + reverseFloat(); + transformFloat(InputDataType.COMPLEXINPUT); +} /* end inverseTransform */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method enforces Hermitian symmetry to Fourier data provided in a + real-imaginary representation. The number of dimensions of the data + is determined by the constructor of this object. Likewise, the + dimensions themselves must match those provided to the constructor of + this object. The output Fourier data <i>Y</i> satisfies + ℜ(<i>Y</i>[0]) = ℜ(<i>X</i>[0]), ℑ(<i>Y</i>[0]) = 0, + <i>Y</i>[<i>n</i>] = ℜ(<i>X</i>[<i>n</i>] + <i>X</i>[<i>K</i> + − <i>n</i>]) ∕ 2 + j ℑ(<i>X</i>[<i>n</i>] − + <i>X</i>[<i>K</i> − <i>n</i>]) ∕ 2 for <i>n</i> ∈ + [1…<i>K</i> − 1], where <i>X</i> is the input Fourier + data. + </p> + @param reData At input, the real part of the data; at output, the + real part is symmetric with respect to the origin. The processing is + in-place. + @param imData At input, the imaginary part of the data; at output, + the imaginary part is antisymmetric with respect to the origin. The + processing is in-place. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + ********************************************************************/ +public void makeHermitian ( + final double[] reData, + final double[] imData, + double[] reBuffer, + double[] imBuffer +) { + if (null == reBuffer) { + reBuffer = new double[reData.length]; + } + if (null == imBuffer) { + imBuffer = new double[imData.length]; + } + if ((reData.length != dataLength) + || (imData.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reDataDouble = reData; + this.imDataDouble = imData; + this.reBufferDouble = reBuffer; + this.imBufferDouble = imBuffer; + switch (dimensions) { + case 1: { + shiftDouble(-fourierOrigin1); + break; + } + case 2: { + shiftDouble(-fourierOrigin1, -fourierOrigin2); + break; + } + case 3: { + shiftDouble(-fourierOrigin1, -fourierOrigin2, -fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } + System.arraycopy(reData, 0, reBuffer, 0, dataLength); + System.arraycopy(imData, 0, imBuffer, 0, dataLength); + reverseDouble(); + for (int k = 0; (k < dataLength); k++) { + reData[k] = 0.5 * (reBuffer[k] + reData[k]); + imData[k] = 0.5 * (imBuffer[k] - imData[k]); + } + switch (dimensions) { + case 1: { + shiftDouble(fourierOrigin1); + break; + } + case 2: { + shiftDouble(fourierOrigin1, fourierOrigin2); + break; + } + case 3: { + shiftDouble(fourierOrigin1, fourierOrigin2, fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } +} /* end makeHermitian */ + +/*------------------------------------------------------------------*/ +/********************************************************************* + <p> + This method enforces Hermitian symmetry to Fourier data provided in a + real-imaginary representation. The number of dimensions of the data + is determined by the constructor of this object. Likewise, the + dimensions themselves must match those provided to the constructor of + this object. The output Fourier data <i>Y</i> satisfies + ℜ(<i>Y</i>[0]) = ℜ(<i>X</i>[0]), ℑ(<i>Y</i>[0]) = 0, + <i>Y</i>[<i>n</i>] = ℜ(<i>X</i>[<i>n</i>] + <i>X</i>[<i>K</i> + − <i>n</i>]) ∕ 2 + j ℑ(<i>X</i>[<i>n</i>] − + <i>X</i>[<i>K</i> − <i>n</i>]) ∕ 2 for <i>n</i> ∈ + [1…<i>K</i> − 1], where <i>X</i> is the input Fourier + data. + </p> + @param reData At input, the real part of the data; at output, the + real part is symmetric with respect to the origin. The processing is + in-place. + @param imData At input, the imaginary part of the data; at output, + the imaginary part is antisymmetric with respect to the origin. The + processing is in-place. + @param reBuffer Garbage in, garbage out. A temporary buffer of length + <code>reData.length</code> is created internally if + <code>reBuffer</code> is <code>null</code>. + @param imBuffer Garbage in, garbage out. A temporary buffer of length + <code>imData.length</code> is created internally if + <code>imBuffer</code> is <code>null</code>. + ********************************************************************/ +public void makeHermitian ( + final float[] reData, + final float[] imData, + float[] reBuffer, + float[] imBuffer +) { + if (null == reBuffer) { + reBuffer = new float[reData.length]; + } + if (null == imBuffer) { + imBuffer = new float[imData.length]; + } + if ((reData.length != dataLength) + || (imData.length != dataLength) + || (reBuffer.length != dataLength) + || (imBuffer.length != dataLength)) { + throw(new IllegalArgumentException()); + } + this.reDataFloat = reData; + this.imDataFloat = imData; + this.reBufferFloat = reBuffer; + this.imBufferFloat = imBuffer; + switch (dimensions) { + case 1: { + shiftFloat(-fourierOrigin1); + break; + } + case 2: { + shiftFloat(-fourierOrigin1, -fourierOrigin2); + break; + } + case 3: { + shiftFloat(-fourierOrigin1, -fourierOrigin2, -fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } + System.arraycopy(reData, 0, reBuffer, 0, dataLength); + System.arraycopy(imData, 0, imBuffer, 0, dataLength); + reverseFloat(); + for (int k = 0; (k < dataLength); k++) { + reData[k] = 0.5F * (reBuffer[k] + reData[k]); + imData[k] = 0.5F * (imBuffer[k] - imData[k]); + } + switch (dimensions) { + case 1: { + shiftFloat(fourierOrigin1); + break; + } + case 2: { + shiftFloat(fourierOrigin1, fourierOrigin2); + break; + } + case 3: { + shiftFloat(fourierOrigin1, fourierOrigin2, fourierOrigin3); + break; + } + default: { + throw(new IllegalStateException()); + } + } +} /* end makeHermitian */ + +/*.................................................................... + SlowFourierTransform private methods +....................................................................*/ +/*------------------------------------------------------------------*/ +private void reverseDouble ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + if (1 < K1) { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + int progressive = p; + int regressive = p + K1; + while (++progressive < --regressive) { + final double reSwap = reDataDouble[progressive]; + reDataDouble[progressive] = reDataDouble[regressive]; + reDataDouble[regressive] = reSwap; + final double imSwap = imDataDouble[progressive]; + imDataDouble[progressive] = imDataDouble[regressive]; + imDataDouble[regressive] = imSwap; + } + p += K1; + } + } + } + if (1 < K2) { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + int q = p; + for (int k1 = 0; (k1 < K1); k1++) { + int progressive = q + K1; + int regressive = q + K1 * (K2 - 1); + while (progressive < regressive) { + final double reSwap = reDataDouble[progressive]; + reDataDouble[progressive] = reDataDouble[regressive]; + reDataDouble[regressive] = reSwap; + final double imSwap = imDataDouble[progressive]; + imDataDouble[progressive] = imDataDouble[regressive]; + imDataDouble[regressive] = imSwap; + progressive += K1; + regressive -= K1; + } + q++; + } + p += K1K2; + } + } + if (1 < K3) { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + int progressive = p + K1K2; + int regressive = p + K1K2 * (K3 - 1); + while (progressive < regressive) { + final double reSwap = reDataDouble[progressive]; + reDataDouble[progressive] = reDataDouble[regressive]; + reDataDouble[regressive] = reSwap; + final double imSwap = imDataDouble[progressive]; + imDataDouble[progressive] = imDataDouble[regressive]; + imDataDouble[regressive] = imSwap; + progressive += K1K2; + regressive -= K1K2; + } + p++; + } + } + } +} /* end reverseDouble */ + +/*------------------------------------------------------------------*/ +private void reverseFloat ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + if (1 < K1) { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + int progressive = p; + int regressive = p + K1; + while (++progressive < --regressive) { + final float reSwap = reDataFloat[progressive]; + reDataFloat[progressive] = reDataFloat[regressive]; + reDataFloat[regressive] = reSwap; + final float imSwap = imDataFloat[progressive]; + imDataFloat[progressive] = imDataFloat[regressive]; + imDataFloat[regressive] = imSwap; + } + p += K1; + } + } + } + if (1 < K2) { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + int q = p; + for (int k1 = 0; (k1 < K1); k1++) { + int progressive = q + K1; + int regressive = q + K1 * (K2 - 1); + while (progressive < regressive) { + final float reSwap = reDataFloat[progressive]; + reDataFloat[progressive] = reDataFloat[regressive]; + reDataFloat[regressive] = reSwap; + final float imSwap = imDataFloat[progressive]; + imDataFloat[progressive] = imDataFloat[regressive]; + imDataFloat[regressive] = imSwap; + progressive += K1; + regressive -= K1; + } + q++; + } + p += K1K2; + } + } + if (1 < K3) { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + int progressive = p + K1K2; + int regressive = p + K1K2 * (K3 - 1); + while (progressive < regressive) { + final float reSwap = reDataFloat[progressive]; + reDataFloat[progressive] = reDataFloat[regressive]; + reDataFloat[regressive] = reSwap; + final float imSwap = imDataFloat[progressive]; + imDataFloat[progressive] = imDataFloat[regressive]; + imDataFloat[regressive] = imSwap; + progressive += K1K2; + regressive -= K1K2; + } + p++; + } + } + } +} /* end reverseFloat */ + +/*------------------------------------------------------------------*/ +private void shiftDouble ( + int o1 +) { + final int K1 = width.intValue(); + o1 = (o1 < 0) ? (o1 + K1 * ((K1 - 1 - o1) / K1)) : (o1 - K1 * (o1 / K1)); + if (0 == o1) { + return; + } + final int range1 = K1 - o1; + System.arraycopy(reDataDouble, 0, reBufferDouble, o1, + range1); + System.arraycopy(imDataDouble, 0, imBufferDouble, o1, + range1); + System.arraycopy(reDataDouble, range1, reBufferDouble, 0, + o1); + System.arraycopy(imDataDouble, range1, imBufferDouble, 0, + o1); + System.arraycopy(reBufferDouble, 0, reDataDouble, 0, + K1); + System.arraycopy(imBufferDouble, 0, imDataDouble, 0, + K1); +} /* end shiftDouble */ + +/*------------------------------------------------------------------*/ +private void shiftDouble ( + int o1, + int o2 +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + o1 = (o1 < 0) ? (o1 + K1 * ((K1 - 1 - o1) / K1)) : (o1 - K1 * (o1 / K1)); + o2 = (o2 < 0) ? (o2 + K2 * ((K2 - 1 - o2) / K2)) : (o2 - K2 * (o2 / K2)); + if ((0 == o1) && (0 == o2)) { + return; + } + final int range1 = K1 - o1; + final int range2 = K2 - o2; + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + System.arraycopy(reDataDouble, p, reBufferDouble, p + o1, + range1); + System.arraycopy(imDataDouble, p, imBufferDouble, p + o1, + range1); + System.arraycopy(reDataDouble, p + range1, reBufferDouble, p, + o1); + System.arraycopy(imDataDouble, p + range1, imBufferDouble, p, + o1); + p += K1; + } + System.arraycopy(reBufferDouble, 0, reDataDouble, o2 * K1, + range2 * K1); + System.arraycopy(imBufferDouble, 0, imDataDouble, o2 * K1, + range2 * K1); + System.arraycopy(reBufferDouble, range2 * K1, reDataDouble, 0, + o2 * K1); + System.arraycopy(imBufferDouble, range2 * K1, imDataDouble, 0, + o2 * K1); +} /* end shiftDouble */ + +/*------------------------------------------------------------------*/ +private void shiftDouble ( + int o1, + int o2, + int o3 +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + o1 = (o1 < 0) ? (o1 + K1 * ((K1 - 1 - o1) / K1)) : (o1 - K1 * (o1 / K1)); + o2 = (o2 < 0) ? (o2 + K2 * ((K2 - 1 - o2) / K2)) : (o2 - K2 * (o2 / K2)); + o3 = (o3 < 0) ? (o3 + K3 * ((K3 - 1 - o3) / K3)) : (o3 - K3 * (o3 / K3)); + if ((0 == o1) && (0 == o2) && (0 == o3)) { + return; + } + final int K1K2 = K1 * K2; + final int range1 = K1 - o1; + final int range2 = K2 - o2; + final int range3 = K3 - o3; + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + System.arraycopy(reDataDouble, p, reBufferDouble, p + o1, + range1); + System.arraycopy(imDataDouble, p, imBufferDouble, p + o1, + range1); + System.arraycopy(reDataDouble, p + range1, reBufferDouble, p, + o1); + System.arraycopy(imDataDouble, p + range1, imBufferDouble, p, + o1); + p += K1; + } + } + p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + System.arraycopy(reBufferDouble, p, reDataDouble, o2 * K1, + range2 * K1); + System.arraycopy(imBufferDouble, p, imDataDouble, o2 * K1, + range2 * K1); + System.arraycopy(reBufferDouble, range2 * K1, reDataDouble, p, + o2 * K1); + System.arraycopy(imBufferDouble, range2 * K1, imDataDouble, p, + fourierOrigin2 * K1); + p += K1K2; + } + System.arraycopy(reDataDouble, 0, reBufferDouble, o3 * K1K2, + range3 * K1K2); + System.arraycopy(imDataDouble, 0, imBufferDouble, o3 * K1K2, + range3 * K1K2); + System.arraycopy(reDataDouble, range3 * K1K2, reBufferDouble, 0, + o3 * K1K2); + System.arraycopy(imDataDouble, range3 * K1K2, imBufferDouble, 0, + o3 * K1K2); + System.arraycopy(reBufferDouble, 0, reDataDouble, 0, + dataLength); + System.arraycopy(imBufferDouble, 0, imDataDouble, 0, + dataLength); +} /* end shiftDouble */ + +/*------------------------------------------------------------------*/ +private void shiftFloat ( + int o1 +) { + final int K1 = width.intValue(); + o1 = (o1 < 0) ? (o1 + K1 * ((K1 - 1 - o1) / K1)) : (o1 - K1 * (o1 / K1)); + if (0 == o1) { + return; + } + final int range1 = K1 - o1; + System.arraycopy(reDataFloat, 0, reBufferFloat, o1, + range1); + System.arraycopy(imDataFloat, 0, imBufferFloat, o1, + range1); + System.arraycopy(reDataFloat, range1, reBufferFloat, 0, + o1); + System.arraycopy(imDataFloat, range1, imBufferFloat, 0, + o1); + System.arraycopy(reBufferFloat, 0, reDataFloat, 0, + K1); + System.arraycopy(imBufferFloat, 0, imDataFloat, 0, + K1); +} /* end shiftFloat */ + +/*------------------------------------------------------------------*/ +private void shiftFloat ( + int o1, + int o2 +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + o1 = (o1 < 0) ? (o1 + K1 * ((K1 - 1 - o1) / K1)) : (o1 - K1 * (o1 / K1)); + o2 = (o2 < 0) ? (o2 + K2 * ((K2 - 1 - o2) / K2)) : (o2 - K2 * (o2 / K2)); + if ((0 == o1) && (0 == o2)) { + return; + } + final int range1 = K1 - o1; + final int range2 = K2 - o2; + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + System.arraycopy(reDataFloat, p, reBufferFloat, p + o1, + range1); + System.arraycopy(imDataFloat, p, imBufferFloat, p + o1, + range1); + System.arraycopy(reDataFloat, p + range1, reBufferFloat, p, + o1); + System.arraycopy(imDataFloat, p + range1, imBufferFloat, p, + o1); + p += K1; + } + System.arraycopy(reBufferFloat, 0, reDataFloat, o2 * K1, + range2 * K1); + System.arraycopy(imBufferFloat, 0, imDataFloat, o2 * K1, + range2 * K1); + System.arraycopy(reBufferFloat, range2 * K1, reDataFloat, 0, + o2 * K1); + System.arraycopy(imBufferFloat, range2 * K1, imDataFloat, 0, + o2 * K1); +} /* end shiftFloat */ + +/*------------------------------------------------------------------*/ +private void shiftFloat ( + int o1, + int o2, + int o3 +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + o1 = (o1 < 0) ? (o1 + K1 * ((K1 - 1 - o1) / K1)) : (o1 - K1 * (o1 / K1)); + o2 = (o2 < 0) ? (o2 + K2 * ((K2 - 1 - o2) / K2)) : (o2 - K2 * (o2 / K2)); + o3 = (o3 < 0) ? (o3 + K3 * ((K3 - 1 - o3) / K3)) : (o3 - K3 * (o3 / K3)); + if ((0 == o1) && (0 == o2) && (0 == o3)) { + return; + } + final int K1K2 = K1 * K2; + final int range1 = K1 - o1; + final int range2 = K2 - o2; + final int range3 = K3 - o3; + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + System.arraycopy(reDataFloat, p, reBufferFloat, p + o1, + range1); + System.arraycopy(imDataFloat, p, imBufferFloat, p + o1, + range1); + System.arraycopy(reDataFloat, p + range1, reBufferFloat, p, + o1); + System.arraycopy(imDataFloat, p + range1, imBufferFloat, p, + o1); + p += K1; + } + } + p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + System.arraycopy(reBufferFloat, p, reDataFloat, o2 * K1, + range2 * K1); + System.arraycopy(imBufferFloat, p, imDataFloat, o2 * K1, + range2 * K1); + System.arraycopy(reBufferFloat, range2 * K1, reDataFloat, p, + o2 * K1); + System.arraycopy(imBufferFloat, range2 * K1, imDataFloat, p, + fourierOrigin2 * K1); + p += K1K2; + } + System.arraycopy(reDataFloat, 0, reBufferFloat, o3 * K1K2, + range3 * K1K2); + System.arraycopy(imDataFloat, 0, imBufferFloat, o3 * K1K2, + range3 * K1K2); + System.arraycopy(reDataFloat, range3 * K1K2, reBufferFloat, 0, + o3 * K1K2); + System.arraycopy(imDataFloat, range3 * K1K2, imBufferFloat, 0, + o3 * K1K2); + System.arraycopy(reBufferFloat, 0, reDataFloat, 0, + dataLength); + System.arraycopy(imBufferFloat, 0, imDataFloat, 0, + dataLength); +} /* end shiftFloat */ + +/*------------------------------------------------------------------*/ +private void transformDouble ( + final InputDataType inputDataType +) { + switch (inputDataType) { + case COMPLEXINPUT: { + switch (dimensions) { + case 1: { + transformDouble1D(); + break; + } + case 2: { + transformDouble2D(); + break; + } + case 3: { + transformDouble3D(); + break; + } + default: { + throw(new IllegalStateException()); + } + } + break; + } + case REALINPUT: { + switch (dimensions) { + case 1: { + transformRealDouble1D(); + break; + } + case 2: { + switch (firstDimension) { + case 1: { + transformRealDouble2DRowFirst(); + break; + } + case 2: { + transformRealDouble2DColumnFirst(); + break; + } + default: { + throw(new IllegalStateException()); + } + } + break; + } + case 3: { + switch (firstDimension) { + case 1: { + transformRealDouble3DRowFirst(); + break; + } + case 2: { + transformRealDouble3DColumnFirst(); + break; + } + case 3: { + transformRealDouble3DAcrossFirst(); + break; + } + default: { + throw(new IllegalStateException()); + } + } + break; + } + default: { + throw(new IllegalStateException()); + } + } + break; + } + } +} /* end transformDouble */ + +/*------------------------------------------------------------------*/ +private void transformDouble1D ( +) { + final FFTSetup fft = FFTSetup.transforms.get(width); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Double(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH3: { + new DFTLength3Double(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH4: { + new DFTLength4Double(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH5: { + new DFTLength5Double(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH6: { + new DFTLength6Double(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH8: { + new DFTLength8Double(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderDouble(reDataDouble, imDataDouble, 0, 1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Double(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } +} /* end transformDouble1D */ + +/*------------------------------------------------------------------*/ +private void transformDouble2D ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + // Rows + final FFTSetup fft1 = FFTSetup.transforms.get(width); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + p += K1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH3: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH4: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH5: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH6: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH8: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble, fft1.K1)); + p += K1; + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p, 1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADER: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADIX2: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft2 = FFTSetup.transforms.get(height); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + break; + } + case COPRIMEFACTOR: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength2Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH3: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength3Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH4: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength4Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH5: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength5Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH6: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength6Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH8: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength8Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case MIXEDRADIX: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, fft2.K1)); + } + break; + } + case PADDEDRADER: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, k1, K1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + } + break; + } + case RADER: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + } + break; + } + case RADIX2: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + break; + } + case SPLITRADIX: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } +} /* end transformDouble2D */ + +/*------------------------------------------------------------------*/ +private void transformDouble3D ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + // Rows + final FFTSetup fft1 = FFTSetup.transforms.get(width); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + p += K1; + } + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble, fft1.K1)); + p += K1; + } + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p, 1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + p += K1; + } + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + p += K1; + } + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft2 = FFTSetup.transforms.get(height); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft2.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + p += K1K2; + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + } + p += K1K2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, fft2.K1)); + } + p += K1K2; + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p + k1, K1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + } + p += K1K2; + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + } + p += K1K2; + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + p += K1K2; + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + p += K1K2; + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Across + final FFTSetup fft3 = FFTSetup.transforms.get(depth); + final ExecutorService executor3 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft3.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + p++; + } + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.ruritanian, fft3.chinese, fft3.K1)); + p++; + } + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH3: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH4: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH5: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH6: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH8: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble, fft3.K1)); + p++; + } + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p, K1K2, + fft3.reConvolverDouble, fft3.imConvolverDouble, + fft3.modular, fft3.inverseModular)); + p++; + } + } + break; + } + case RADER: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reConvolverDouble, fft3.imConvolverDouble, + fft3.modular, fft3.inverseModular)); + p++; + } + } + break; + } + case RADIX2: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + p++; + } + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + p++; + } + } + break; + } + } + try { + executor3.shutdown(); + executor3.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } +} /* end transformDouble3D */ + +/*------------------------------------------------------------------*/ +private void transformFloat ( + final InputDataType inputDataType +) { + switch (inputDataType) { + case COMPLEXINPUT: { + switch (dimensions) { + case 1: { + transformFloat1D(); + break; + } + case 2: { + transformFloat2D(); + break; + } + case 3: { + transformFloat3D(); + break; + } + default: { + throw(new IllegalStateException()); + } + } + break; + } + case REALINPUT: { + switch (dimensions) { + case 1: { + transformRealFloat1D(); + break; + } + case 2: { + switch (firstDimension) { + case 1: { + transformRealFloat2DRowFirst(); + break; + } + case 2: { + transformRealFloat2DColumnFirst(); + break; + } + default: { + throw(new IllegalStateException()); + } + } + break; + } + case 3: { + switch (firstDimension) { + case 1: { + transformRealFloat3DRowFirst(); + break; + } + case 2: { + transformRealFloat3DColumnFirst(); + break; + } + case 3: { + transformRealFloat3DAcrossFirst(); + break; + } + default: { + throw(new IllegalStateException()); + } + } + break; + } + default: { + throw(new IllegalStateException()); + } + } + break; + } + } +} /* end transformFloat */ + +/*------------------------------------------------------------------*/ +private void transformFloat1D ( +) { + final FFTSetup fft = FFTSetup.transforms.get(width); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + new DFTLength2Float(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH3: { + new DFTLength3Float(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH4: { + new DFTLength4Float(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH5: { + new DFTLength5Float(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH6: { + new DFTLength6Float(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH8: { + new DFTLength8Float(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderFloat(reDataFloat, imDataFloat, 0, 1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2Float(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } +} /* end transformFloat1D */ + +/*------------------------------------------------------------------*/ +private void transformFloat2D ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + // Rows + final FFTSetup fft1 = FFTSetup.transforms.get(width); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + p += K1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH3: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH4: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH5: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH6: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH8: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat, fft1.K1)); + p += K1; + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p, 1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADER: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADIX2: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft2 = FFTSetup.transforms.get(height); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + break; + } + case COPRIMEFACTOR: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength2Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH3: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength3Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH4: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength4Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH5: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength5Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH6: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength6Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH8: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength8Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case MIXEDRADIX: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, fft2.K1)); + } + break; + } + case PADDEDRADER: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, k1, K1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + } + break; + } + case RADER: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + } + break; + } + case RADIX2: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + break; + } + case SPLITRADIX: { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } +} /* end transformFloat2D */ + +/*------------------------------------------------------------------*/ +private void transformFloat3D ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + // Rows + final FFTSetup fft1 = FFTSetup.transforms.get(width); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + p += K1; + } + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat, + fft1.K1)); + p += K1; + } + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p, 1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + p += K1; + } + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + p += K1; + } + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor1.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft2 = FFTSetup.transforms.get(height); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft2.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + p += K1K2; + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + } + p += K1K2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, fft2.K1)); + } + p += K1K2; + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p + k1, K1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + } + p += K1K2; + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + } + p += K1K2; + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + p += K1K2; + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor2.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + p += K1K2; + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Across + final FFTSetup fft3 = FFTSetup.transforms.get(depth); + final ExecutorService executor3 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft3.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + p++; + } + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.ruritanian, fft3.chinese, fft3.K1)); + p++; + } + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH3: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH4: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH5: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH6: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH8: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat, fft3.K1)); + p++; + } + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p, K1K2, + fft3.reConvolverFloat, fft3.imConvolverFloat, + fft3.modular, fft3.inverseModular)); + p++; + } + } + break; + } + case RADER: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reConvolverFloat, fft3.imConvolverFloat, + fft3.modular, fft3.inverseModular)); + p++; + } + } + break; + } + case RADIX2: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + p++; + } + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + p++; + } + } + break; + } + } + try { + executor3.shutdown(); + executor3.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } +} /* end transformFloat3D */ + +/*------------------------------------------------------------------*/ +private void transformRealDouble1D ( +) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(width); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + } + case LENGTH1: { + imDataDouble[0] = 0.0; + break; + } + case LENGTH2: { + new DFTLength2RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reDataDouble, imDataDouble, 0, 1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootEvenDouble, fft.imUnitRootEvenDouble, + fft.reUnitRootOddDouble, fft.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + int progressive = 0; + int regressive = width.intValue(); + while (++progressive < --regressive) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + } +} /* end transformRealDouble1D */ + +/*------------------------------------------------------------------*/ +private void transformRealDouble2DColumnFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int halfK2 = (K2 >> 1) + 1; + int k1 = -1; + // First column for an odd width + if (1 == (K1 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(height); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + imDataDouble[0] = 0.0; + break; + } + case LENGTH2: { + new DFTLength2RealDouble(reDataDouble, imDataDouble, + 0, K1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble(reDataDouble, imDataDouble, + 0, K1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble(reDataDouble, imDataDouble, + 0, K1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble(reDataDouble, imDataDouble, + 0, K1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble(reDataDouble, imDataDouble, + 0, K1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reDataDouble, imDataDouble, + 0, K1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootDouble, fft.imUnitRootDouble, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reDataDouble, imDataDouble, 0, K1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootEvenDouble, fft.imUnitRootEvenDouble, + fft.reUnitRootOddDouble, fft.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + k1 = 0; + } + // Remaining columns + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(height); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (++k1 < K1) { + executor1.execute(new DFTBruteForceRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + } + break; + } + case COPRIMEFACTOR: { + while (++k1 < K1) { + executor1.execute(new DFTCoprimeFactorRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + } + break; + } + case DUOREAL: { + while (++k1 < K1) { + executor1.execute(new DFTDuoRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, k1 + 1, K1, K2)); + ++k1; + } + break; + } + case EVENREAL: { + while (++k1 < K1) { + executor1.execute(new DFTEvenRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + } + break; + } + case LENGTH1: { + while (++k1 < K1) { + imDataDouble[k1] = 0.0; + } + break; + } + case LENGTH2: { + while (++k1 < K1) { + executor1.execute(new DFTLength2RealDouble( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH3: { + while (++k1 < K1) { + executor1.execute(new DFTLength3RealDouble( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH4: { + while (++k1 < K1) { + executor1.execute(new DFTLength4RealDouble( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH5: { + while (++k1 < K1) { + executor1.execute(new DFTLength5RealDouble( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH6: { + while (++k1 < K1) { + executor1.execute(new DFTLength6RealDouble( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH8: { + while (++k1 < K1) { + executor1.execute(new DFTLength8RealDouble( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case MIXEDRADIX: { + while (++k1 < K1) { + executor1.execute(new DFTMixedRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble, fft1.K1)); + } + break; + } + case PADDEDRADER: { + while (++k1 < K1) { + executor1.execute(new DFTPaddedRaderRealDouble( + reDataDouble, imDataDouble, k1, K1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADER: { + while (++k1 < K1) { + executor1.execute(new DFTRaderRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADIX2: { + while (++k1 < K1) { + executor1.execute(new DFTRadix2RealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft1.reUnitRootEvenDouble, fft1.imUnitRootEvenDouble, + fft1.reUnitRootOddDouble, fft1.imUnitRootOddDouble)); + } + break; + } + case SPLITRADIX: { + while (++k1 < K1) { + executor1.execute(new DFTSplitRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Rows + final FFTSetup fft2 = FFTSetup.transforms.get(width); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + int p = 0; + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + p += K1; + } + break; + } + case COPRIMEFACTOR: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + p += K1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH3: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH4: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH5: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH6: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH8: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case MIXEDRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, fft2.K1)); + p += K1; + } + break; + } + case PADDEDRADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p, 1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + p += K1; + } + break; + } + case RADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + p += K1; + } + break; + } + case RADIX2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + p += K1; + } + break; + } + case SPLITRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + p += K1; + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = K1; + int regressive = K1 * (K2 - 1); + while (progressive < regressive) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive += K1; + regressive -= K1; + } + p = K1 + 1; + int q = K1 * K2 - 1; + for (int k2 = halfK2; (k2 < K2); k2++) { + progressive = p; + regressive = q; + for (k1 = 1; (k1 < K1); k1++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive++; + regressive--; + } + p += K1; + q -= K1; + } +} /* end transformRealDouble2DColumnFirst */ + +/*------------------------------------------------------------------*/ +private void transformRealDouble2DRowFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int halfK1 = (K1 >> 1) + 1; + int p = 0; + int k2 = 0; + // First row for an odd height + if (1 == (K2 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(width); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + imDataDouble[0] = 0.0; + break; + } + case LENGTH2: { + new DFTLength2RealDouble(reDataDouble, imDataDouble, + 0, 1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble(reDataDouble, imDataDouble, + 0, 1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble(reDataDouble, imDataDouble, + 0, 1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble(reDataDouble, imDataDouble, + 0, 1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble(reDataDouble, imDataDouble, + 0, 1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reDataDouble, imDataDouble, + 0, 1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reDataDouble, imDataDouble, 0, 1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootEvenDouble, fft.imUnitRootEvenDouble, + fft.reUnitRootOddDouble, fft.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + p = K1; + k2 = 1; + } + // Remaining rows + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(width); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (k2++ < K2) { + executor1.execute(new DFTBruteForceRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + break; + } + case COPRIMEFACTOR: { + while (k2++ < K2) { + executor1.execute(new DFTCoprimeFactorRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + p += K1; + } + break; + } + case DUOREAL: { + while (k2++ < K2) { + executor1.execute(new DFTDuoRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, p + K1, 1, K1)); + p += 2 * K1; + k2++; + } + break; + } + case EVENREAL: { + while (k2++ < K2) { + executor1.execute(new DFTEvenRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + break; + } + case LENGTH1: { + while (k2++ < K2) { + imDataDouble[p] = 0.0; + p += K1; + } + break; + } + case LENGTH2: { + while (k2++ < K2) { + executor1.execute(new DFTLength2RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH3: { + while (k2++ < K2) { + executor1.execute(new DFTLength3RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH4: { + while (k2++ < K2) { + executor1.execute(new DFTLength4RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH5: { + while (k2++ < K2) { + executor1.execute(new DFTLength5RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH6: { + while (k2++ < K2) { + executor1.execute(new DFTLength6RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH8: { + while (k2++ < K2) { + executor1.execute(new DFTLength8RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case MIXEDRADIX: { + while (k2++ < K2) { + executor1.execute(new DFTMixedRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble, fft1.K1)); + p += K1; + } + break; + } + case PADDEDRADER: { + while (k2++ < K2) { + executor1.execute(new DFTPaddedRaderRealDouble( + reDataDouble, imDataDouble, p, 1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADER: { + while (k2++ < K2) { + executor1.execute(new DFTRaderRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADIX2: { + while (k2++ < K2) { + executor1.execute(new DFTRadix2RealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootEvenDouble, fft1.imUnitRootEvenDouble, + fft1.reUnitRootOddDouble, fft1.imUnitRootOddDouble)); + p += K1; + } + break; + } + case SPLITRADIX: { + while (k2++ < K2) { + executor1.execute(new DFTSplitRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft2 = FFTSetup.transforms.get(height); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + break; + } + case COPRIMEFACTOR: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength2Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH3: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength3Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH4: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength4Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH5: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength5Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH6: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength6Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case LENGTH8: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength8Double( + reDataDouble, imDataDouble, k1, K1)); + } + break; + } + case MIXEDRADIX: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, fft2.K1)); + } + break; + } + case PADDEDRADER: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, k1, K1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + } + break; + } + case RADER: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + } + break; + } + case RADIX2: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + break; + } + case SPLITRADIX: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = 0; + int regressive = K1; + while (++progressive < --regressive) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + } + p = K1 + 1; + int q = K1 * K2 - 1; + for (k2 = 1; (k2 < K2); k2++) { + progressive = p; + regressive = q; + for (int k1 = halfK1; (k1 < K1); k1++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive++; + regressive--; + } + p += K1; + q -= K1; + } +} /* end transformRealDouble2DRowFirst */ + +/*------------------------------------------------------------------*/ +private void transformRealDouble3DAcrossFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + final int halfK3 = (K3 >> 1) + 1; + int k = -1; + // First across for an odd (width * height) + if (1 == (K1K2 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(depth); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1K2, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1K2, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1K2, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + imDataDouble[0] = 0.0; + break; + } + case LENGTH2: { + new DFTLength2RealDouble(reDataDouble, imDataDouble, + 0, K1K2).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble(reDataDouble, imDataDouble, + 0, K1K2).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble(reDataDouble, imDataDouble, + 0, K1K2).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble(reDataDouble, imDataDouble, + 0, K1K2).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble(reDataDouble, imDataDouble, + 0, K1K2).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reDataDouble, imDataDouble, + 0, K1K2).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1K2, + fft.reUnitRootDouble, fft.imUnitRootDouble, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble( + reDataDouble, imDataDouble, 0, K1K2, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1K2, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1K2, + fft.reUnitRootEvenDouble, fft.imUnitRootEvenDouble, + fft.reUnitRootOddDouble, fft.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1K2, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + k = 0; + } + // Remaining across + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(depth); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (++k < K1K2) { + executor1.execute(new DFTBruteForceRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k, K1K2, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + } + break; + } + case COPRIMEFACTOR: { + while (++k < K1K2) { + executor1.execute(new DFTCoprimeFactorRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k, K1K2, + fft1.ruritanian, fft1.chinese, fft1.K1)); + } + break; + } + case DUOREAL: { + while (++k < K1K2) { + executor1.execute(new DFTDuoRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k, k + 1, K1K2, K3)); + k++; + } + break; + } + case EVENREAL: { + while (++k < K1K2) { + executor1.execute(new DFTEvenRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k, K1K2, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + } + break; + } + case LENGTH1: { + while (++k < K1K2) { + imDataDouble[k] = 0.0; + } + break; + } + case LENGTH2: { + while (++k < K1K2) { + executor1.execute(new DFTLength2RealDouble( + reDataDouble, imDataDouble, k, K1K2)); + } + break; + } + case LENGTH3: { + while (++k < K1K2) { + executor1.execute(new DFTLength3RealDouble( + reDataDouble, imDataDouble, k, K1K2)); + } + break; + } + case LENGTH4: { + while (++k < K1K2) { + executor1.execute(new DFTLength4RealDouble( + reDataDouble, imDataDouble, k, K1K2)); + } + break; + } + case LENGTH5: { + while (++k < K1K2) { + executor1.execute(new DFTLength5RealDouble( + reDataDouble, imDataDouble, k, K1K2)); + } + break; + } + case LENGTH6: { + while (++k < K1K2) { + executor1.execute(new DFTLength6RealDouble( + reDataDouble, imDataDouble, k, K1K2)); + } + break; + } + case LENGTH8: { + while (++k < K1K2) { + executor1.execute(new DFTLength8RealDouble( + reDataDouble, imDataDouble, k, K1K2)); + } + break; + } + case MIXEDRADIX: { + while (++k < K1K2) { + executor1.execute(new DFTMixedRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k, K1K2, + fft1.reUnitRootDouble, fft1.imUnitRootDouble, fft1.K1)); + } + break; + } + case PADDEDRADER: { + while (++k < K1K2) { + executor1.execute(new DFTPaddedRaderRealDouble( + reDataDouble, imDataDouble, k, K1K2, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADER: { + while (++k < K1K2) { + executor1.execute(new DFTRaderRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k, K1K2, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADIX2: { + while (++k < K1K2) { + executor1.execute(new DFTRadix2RealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k, K1K2, + fft1.reUnitRootEvenDouble, fft1.imUnitRootEvenDouble, + fft1.reUnitRootOddDouble, fft1.imUnitRootOddDouble)); + } + break; + } + case SPLITRADIX: { + while (++k < K1K2) { + executor1.execute(new DFTSplitRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k, K1K2, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Rows + final FFTSetup fft2 = FFTSetup.transforms.get(width); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft2.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + p += K1; + } + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + p += K1; + } + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1)); + p += K1; + } + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p, 1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + p += K1; + } + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + p += K1; + } + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + p += K1; + } + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + p += K1; + } + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft3 = FFTSetup.transforms.get(height); + final ExecutorService executor3 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft3.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + } + p += K1K2; + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft3.ruritanian, fft3.chinese, fft3.K1)); + } + p += K1K2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft3.reUnitRootDouble, fft3.imUnitRootDouble, fft3.K1)); + } + p += K1K2; + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p + k1, K1, + fft3.reConvolverDouble, fft3.imConvolverDouble, + fft3.modular, fft3.inverseModular)); + } + p += K1K2; + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft3.reConvolverDouble, fft3.imConvolverDouble, + fft3.modular, fft3.inverseModular)); + } + p += K1K2; + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + } + p += K1K2; + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + } + p += K1K2; + } + break; + } + } + try { + executor3.shutdown(); + executor3.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = K1K2; + int regressive = dataLength - K1K2; + while (progressive < regressive) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive += K1K2; + regressive -= K1K2; + } + int p = K1K2 + K1; + int q = dataLength - K1; + for (int k3 = halfK3; (k3 < K3); k3++) { + progressive = p; + regressive = q; + for (int k2 = 1; (k2 < K2); k2++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive += K1; + regressive -= K1; + } + p += K1K2; + q -= K1K2; + } + p = K1K2 + 1; + q = K1K2 * (K3 - 1) + K1 - 1; + for (int k3 = halfK3; (k3 < K3); k3++) { + progressive = p; + regressive = q; + for (int k1 = 1; (k1 < K1); k1++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive++; + regressive--; + } + p += K1K2; + q -= K1K2; + } + progressive = K1K2 + K1 + 1; + regressive = dataLength - 1; + for (int k3 = halfK3; (k3 < K3); k3++) { + for (int k2 = 1; (k2 < K2); k2++) { + for (int k1 = 1; (k1 < K1); k1++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive++; + regressive--; + } + progressive++; + regressive--; + } + progressive += K1; + regressive -= K1; + } +} /* end transformRealDouble3DAcrossFirst */ + +/*------------------------------------------------------------------*/ +private void transformRealDouble3DColumnFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + final int k1K2 = K1K2 - K1; + final int K1K3 = K1 * K3; + final int halfK2 = (K2 >> 1) + 1; + int k = -1; + // First column for an odd (width * depth) + if (1 == (K1K3 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(height); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + imDataDouble[0] = 0.0; + break; + } + case LENGTH2: { + new DFTLength2RealDouble( + reDataDouble, imDataDouble, 0, K1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble( + reDataDouble, imDataDouble, 0, K1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble( + reDataDouble, imDataDouble, 0, K1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble( + reDataDouble, imDataDouble, 0, K1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble( + reDataDouble, imDataDouble, 0, K1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble( + reDataDouble, imDataDouble, 0, K1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootDouble, fft.imUnitRootDouble, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reDataDouble, imDataDouble, 0, K1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootEvenDouble, fft.imUnitRootEvenDouble, + fft.reUnitRootOddDouble, fft.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, K1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + k = 0; + } + // Remaining columns + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(height); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (++k < K1K3) { + executor1.execute(new DFTBruteForceRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + } + break; + } + case COPRIMEFACTOR: { + while (++k < K1K3) { + executor1.execute(new DFTCoprimeFactorRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1K2 * (k / K1) + k, K1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + } + break; + } + case DUOREAL: { + while (++k < K1K3) { + final int p = k1K2 * (k / K1) + k; + k++; + final int q = k1K2 * (k / K1) + k; + executor1.execute(new DFTDuoRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, q, K1, K2)); + } + break; + } + case EVENREAL: { + while (++k < K1K3) { + executor1.execute(new DFTEvenRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + } + break; + } + case LENGTH1: { + while (++k < K1K3) { + imDataDouble[k] = 0.0; + } + break; + } + case LENGTH2: { + while (++k < K1K3) { + executor1.execute(new DFTLength2RealDouble( + reDataDouble, imDataDouble, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH3: { + while (++k < K1K3) { + executor1.execute(new DFTLength3RealDouble( + reDataDouble, imDataDouble, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH4: { + while (++k < K1K3) { + executor1.execute(new DFTLength4RealDouble( + reDataDouble, imDataDouble, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH5: { + while (++k < K1K3) { + executor1.execute(new DFTLength5RealDouble( + reDataDouble, imDataDouble, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH6: { + while (++k < K1K3) { + executor1.execute(new DFTLength6RealDouble( + reDataDouble, imDataDouble, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH8: { + while (++k < K1K3) { + executor1.execute(new DFTLength8RealDouble( + reDataDouble, imDataDouble, k1K2 * (k / K1) + k, K1)); + } + break; + } + case MIXEDRADIX: { + while (++k < K1K3) { + executor1.execute(new DFTMixedRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble, fft1.K1)); + } + break; + } + case PADDEDRADER: { + while (++k < K1K3) { + executor1.execute(new DFTPaddedRaderRealDouble( + reDataDouble, imDataDouble, k1K2 * (k / K1) + k, K1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADER: { + while (++k < K1K3) { + executor1.execute(new DFTRaderRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1K2 * (k / K1) + k, K1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADIX2: { + while (++k < K1K3) { + executor1.execute(new DFTRadix2RealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootEvenDouble, fft1.imUnitRootEvenDouble, + fft1.reUnitRootOddDouble, fft1.imUnitRootOddDouble)); + } + break; + } + case SPLITRADIX: { + while (++k < K1K3) { + executor1.execute(new DFTSplitRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Rows + final FFTSetup fft2 = FFTSetup.transforms.get(width); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + final int skippedRows = (K2 - halfK2) * K1; + switch (fft2.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + p += K1; + } + p += skippedRows; + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + p += K1; + } + p += skippedRows; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, + fft2.K1)); + p += K1; + } + p += skippedRows; + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p, 1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + p += K1; + } + p += skippedRows; + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + p += K1; + } + p += skippedRows; + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + p += K1; + } + p += skippedRows; + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + p += K1; + } + p += skippedRows; + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Across + final FFTSetup fft3 = FFTSetup.transforms.get(depth); + final ExecutorService executor3 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft3.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + p++; + } + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.ruritanian, fft3.chinese, fft3.K1)); + p++; + } + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH3: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH4: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH5: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH6: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case LENGTH8: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p, K1K2)); + p++; + } + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble, fft3.K1)); + p++; + } + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p, K1K2, + fft3.reConvolverDouble, fft3.imConvolverDouble, + fft3.modular, fft3.inverseModular)); + p++; + } + } + break; + } + case RADER: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reConvolverDouble, fft3.imConvolverDouble, + fft3.modular, fft3.inverseModular)); + p++; + } + } + break; + } + case RADIX2: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + p++; + } + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + p++; + } + } + break; + } + } + try { + executor3.shutdown(); + executor3.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = K1; + int regressive = K1K2 - K1; + while (progressive < regressive) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive += K1; + regressive -= K1; + } + int p = K1 + 1; + int q = K1K2 - 1; + for (int k2 = halfK2; (k2 < K2); k2++) { + progressive = p; + regressive = q; + for (int k1 = 1; (k1 < K1); k1++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive++; + regressive--; + } + p += K1; + q -= K1; + } + p = K1K2 + K1; + q = dataLength - K1; + for (int k3 = 1; (k3 < K3); k3++) { + progressive = p; + regressive = q; + for (int k2 = halfK2; (k2 < K2); k2++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive += K1; + regressive -= K1; + } + p += K1K2; + q -= K1K2; + } + progressive = K1K2 + K1 + 1; + regressive = dataLength - 1; + for (int k3 = 1; (k3 < K3); k3++) { + for (int k2 = halfK2; (k2 < K2); k2++) { + for (int k1 = 1; (k1 < K1); k1++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive++; + regressive--; + } + progressive++; + regressive--; + } + progressive += halfK2 * K1; + regressive -= halfK2 * K1; + } +} /* end transformRealDouble3DColumnFirst */ + +/*------------------------------------------------------------------*/ +private void transformRealDouble3DRowFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + final int K2K3 = K2 * K3; + final int halfK1 = (K1 >> 1) + 1; + int k = 0; + int p = 0; + // First row for an odd (height * depth) + if (1 == (K2K3 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(width); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + case LENGTH1: { + imDataDouble[0] = 0.0; + break; + } + case LENGTH2: { + new DFTLength2RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealDouble(reDataDouble, imDataDouble, 0, 1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealDouble(reDataDouble, imDataDouble, 0, 1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reConvolverDouble, fft.imConvolverDouble, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootEvenDouble, fft.imUnitRootEvenDouble, + fft.reUnitRootOddDouble, fft.imUnitRootOddDouble).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealDouble(reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, 0, 1, + fft.reUnitRootDouble, fft.imUnitRootDouble).run(); + break; + } + } + k = 1; + p = K1; + } + // Remaining rows + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(width); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (k++ < K2K3) { + executor1.execute(new DFTBruteForceRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + break; + } + case COPRIMEFACTOR: { + while (k++ < K2K3) { + executor1.execute(new DFTCoprimeFactorRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + p += K1; + } + break; + } + case DUOREAL: { + while (k++ < K2K3) { + executor1.execute(new DFTDuoRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, p + K1, 1, K1)); + p += 2 * K1; + k++; + } + break; + } + case EVENREAL: { + while (k++ < K2K3) { + executor1.execute(new DFTEvenRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + break; + } + case LENGTH1: { + while (k++ < K2K3) { + imDataDouble[p] = 0.0; + p += K1; + } + break; + } + case LENGTH2: { + while (k++ < K2K3) { + executor1.execute(new DFTLength2RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH3: { + while (k++ < K2K3) { + executor1.execute(new DFTLength3RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH4: { + while (k++ < K2K3) { + executor1.execute(new DFTLength4RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH5: { + while (k++ < K2K3) { + executor1.execute(new DFTLength5RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH6: { + while (k++ < K2K3) { + executor1.execute(new DFTLength6RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case LENGTH8: { + while (k++ < K2K3) { + executor1.execute(new DFTLength8RealDouble( + reDataDouble, imDataDouble, p, 1)); + p += K1; + } + break; + } + case MIXEDRADIX: { + while (k++ < K2K3) { + executor1.execute(new DFTMixedRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble, fft1.K1)); + p += K1; + } + break; + } + case PADDEDRADER: { + while (k++ < K2K3) { + executor1.execute(new DFTPaddedRaderRealDouble( + reDataDouble, imDataDouble, p, 1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADER: { + while (k++ < K2K3) { + executor1.execute(new DFTRaderRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reConvolverDouble, fft1.imConvolverDouble, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADIX2: { + while (k++ < K2K3) { + executor1.execute(new DFTRadix2RealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootEvenDouble, fft1.imUnitRootEvenDouble, + fft1.reUnitRootOddDouble, fft1.imUnitRootOddDouble)); + p += K1; + } + break; + } + case SPLITRADIX: { + while (k++ < K2K3) { + executor1.execute(new DFTSplitRadixRealDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p, 1, + fft1.reUnitRootDouble, fft1.imUnitRootDouble)); + p += K1; + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft2 = FFTSetup.transforms.get(height); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + p = 0; + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + p += K1K2; + } + break; + } + case COPRIMEFACTOR: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + } + p += K1K2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH3: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH4: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH5: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH6: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH8: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p + k1, K1)); + } + p += K1K2; + } + break; + } + case MIXEDRADIX: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble, fft2.K1)); + } + p += K1K2; + } + break; + } + case PADDEDRADER: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p + k1, K1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + } + p += K1K2; + } + break; + } + case RADER: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reConvolverDouble, fft2.imConvolverDouble, + fft2.modular, fft2.inverseModular)); + } + p += K1K2; + } + break; + } + case RADIX2: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + p += K1K2; + } + break; + } + case SPLITRADIX: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1, + fft2.reUnitRootDouble, fft2.imUnitRootDouble)); + } + p += K1K2; + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Across + final FFTSetup fft3 = FFTSetup.transforms.get(depth); + final ExecutorService executor3 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + p = 0; + switch (fft3.algorithm) { + case BRUTEFORCE: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTBruteForceDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + } + p += K1; + } + break; + } + case COPRIMEFACTOR: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTCoprimeFactorDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1K2, + fft3.ruritanian, fft3.chinese, fft3.K1)); + } + p += K1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength2Double( + reDataDouble, imDataDouble, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH3: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength3Double( + reDataDouble, imDataDouble, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH4: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength4Double( + reDataDouble, imDataDouble, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH5: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength5Double( + reDataDouble, imDataDouble, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH6: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength6Double( + reDataDouble, imDataDouble, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH8: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength8Double( + reDataDouble, imDataDouble, p + k1, K1K2)); + } + p += K1; + } + break; + } + case MIXEDRADIX: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTMixedRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble, fft3.K1)); + } + p += K1; + } + break; + } + case PADDEDRADER: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTPaddedRaderDouble( + reDataDouble, imDataDouble, p + k1, K1K2, + fft3.reConvolverDouble, fft3.imConvolverDouble, + fft3.modular, fft3.inverseModular)); + } + p += K1; + } + break; + } + case RADER: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTRaderDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1K2, + fft3.reConvolverDouble, fft3.imConvolverDouble, + fft3.modular, fft3.inverseModular)); + } + p += K1; + } + break; + } + case RADIX2: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTRadix2Double( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + } + p += K1; + } + break; + } + case SPLITRADIX: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTSplitRadixDouble( + reDataDouble, imDataDouble, + reBufferDouble, imBufferDouble, p + k1, K1K2, + fft3.reUnitRootDouble, fft3.imUnitRootDouble)); + } + p += K1; + } + break; + } + } + try { + executor3.shutdown(); + executor3.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = 0; + int regressive = K1; + while (++progressive < --regressive) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + } + p = K1 + 1; + int q = K1K2 - 1; + for (int k2 = 1; (k2 < K2); k2++) { + progressive = p; + regressive = q; + for (int k1 = halfK1; (k1 < K1); k1++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive++; + regressive--; + } + p += K1; + q -= K1; + } + p = K1K2 + 1; + q = K1K2 * (K3 - 1) + K1 - 1; + for (int k3 = 1; (k3 < K3); k3++) { + progressive = p; + regressive = q; + for (int k1 = halfK1; (k1 < K1); k1++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive++; + regressive--; + } + p += K1K2; + q -= K1K2; + } + progressive = K1K2 + K1 + 1; + regressive = dataLength - 1; + for (int k3 = 1; (k3 < K3); k3++) { + for (int k2 = 1; (k2 < K2); k2++) { + for (int k1 = halfK1; (k1 < K1); k1++) { + reDataDouble[regressive] = reDataDouble[progressive]; + imDataDouble[regressive] = -imDataDouble[progressive]; + progressive++; + regressive--; + } + progressive += halfK1; + regressive -= halfK1; + } + progressive += K1; + regressive -= K1; + } +} /* end transformRealDouble3DRowFirst */ + +/*------------------------------------------------------------------*/ +private void transformRealFloat1D ( +) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(width); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + } + case LENGTH1: { + imDataFloat[0] = 0.0F; + break; + } + case LENGTH2: { + new DFTLength2RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reDataFloat, imDataFloat, 0, 1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootEvenFloat, fft.imUnitRootEvenFloat, + fft.reUnitRootOddFloat, fft.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + int progressive = 0; + int regressive = width.intValue(); + while (++progressive < --regressive) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + } +} /* end transformRealFloat1D */ + +/*------------------------------------------------------------------*/ +private void transformRealFloat2DColumnFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int halfK2 = (K2 >> 1) + 1; + int k1 = -1; + // First column for an odd width + if (1 == (K1 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(height); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + imDataFloat[0] = 0.0F; + break; + } + case LENGTH2: { + new DFTLength2RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootFloat, fft.imUnitRootFloat, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reDataFloat, imDataFloat, 0, K1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootEvenFloat, fft.imUnitRootEvenFloat, + fft.reUnitRootOddFloat, fft.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + k1 = 0; + } + // Remaining columns + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(height); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (++k1 < K1) { + executor1.execute(new DFTBruteForceRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + } + break; + } + case COPRIMEFACTOR: { + while (++k1 < K1) { + executor1.execute(new DFTCoprimeFactorRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + } + break; + } + case DUOREAL: { + while (++k1 < K1) { + executor1.execute(new DFTDuoRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, k1 + 1, K1, K2)); + ++k1; + } + break; + } + case EVENREAL: { + while (++k1 < K1) { + executor1.execute(new DFTEvenRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + } + break; + } + case LENGTH1: { + while (++k1 < K1) { + imDataFloat[k1] = 0.0F; + } + break; + } + case LENGTH2: { + while (++k1 < K1) { + executor1.execute(new DFTLength2RealFloat( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH3: { + while (++k1 < K1) { + executor1.execute(new DFTLength3RealFloat( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH4: { + while (++k1 < K1) { + executor1.execute(new DFTLength4RealFloat( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH5: { + while (++k1 < K1) { + executor1.execute(new DFTLength5RealFloat( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH6: { + while (++k1 < K1) { + executor1.execute(new DFTLength6RealFloat( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH8: { + while (++k1 < K1) { + executor1.execute(new DFTLength8RealFloat( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case MIXEDRADIX: { + while (++k1 < K1) { + executor1.execute(new DFTMixedRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat, fft1.K1)); + } + break; + } + case PADDEDRADER: { + while (++k1 < K1) { + executor1.execute(new DFTPaddedRaderRealFloat( + reDataFloat, imDataFloat, k1, K1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADER: { + while (++k1 < K1) { + executor1.execute(new DFTRaderRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADIX2: { + while (++k1 < K1) { + executor1.execute(new DFTRadix2RealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft1.reUnitRootEvenFloat, fft1.imUnitRootEvenFloat, + fft1.reUnitRootOddFloat, fft1.imUnitRootOddFloat)); + } + break; + } + case SPLITRADIX: { + while (++k1 < K1) { + executor1.execute(new DFTSplitRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Rows + final FFTSetup fft2 = FFTSetup.transforms.get(width); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + int p = 0; + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + p += K1; + } + break; + } + case COPRIMEFACTOR: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + p += K1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH3: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH4: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH5: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH6: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH8: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case MIXEDRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, fft2.K1)); + p += K1; + } + break; + } + case PADDEDRADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p, 1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + p += K1; + } + break; + } + case RADER: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + p += K1; + } + break; + } + case RADIX2: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + p += K1; + } + break; + } + case SPLITRADIX: { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + p += K1; + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = K1; + int regressive = K1 * (K2 - 1); + while (progressive < regressive) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive += K1; + regressive -= K1; + } + p = K1 + 1; + int q = K1 * K2 - 1; + for (int k2 = halfK2; (k2 < K2); k2++) { + progressive = p; + regressive = q; + for (k1 = 1; (k1 < K1); k1++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive++; + regressive--; + } + p += K1; + q -= K1; + } +} /* transformRealFloat2DColumnFirst */ + +/*------------------------------------------------------------------*/ +private void transformRealFloat2DRowFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int halfK1 = (K1 >> 1) + 1; + int p = 0; + int k2 = 0; + // First row for an odd height + if (1 == (K2 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(width); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + imDataFloat[0] = 0.0F; + break; + } + case LENGTH2: { + new DFTLength2RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reDataFloat, imDataFloat, 0, 1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootEvenFloat, fft.imUnitRootEvenFloat, + fft.reUnitRootOddFloat, fft.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + p = K1; + k2 = 1; + } + // Remaining rows + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(width); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (k2++ < K2) { + executor1.execute(new DFTBruteForceRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + break; + } + case COPRIMEFACTOR: { + while (k2++ < K2) { + executor1.execute(new DFTCoprimeFactorRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + p += K1; + } + break; + } + case DUOREAL: { + while (k2++ < K2) { + executor1.execute(new DFTDuoRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, p + K1, 1, K1)); + p += 2 * K1; + k2++; + } + break; + } + case EVENREAL: { + while (k2++ < K2) { + executor1.execute(new DFTEvenRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + break; + } + case LENGTH1: { + while (k2++ < K2) { + imDataFloat[p] = 0.0F; + p += K1; + } + break; + } + case LENGTH2: { + while (k2++ < K2) { + executor1.execute(new DFTLength2RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH3: { + while (k2++ < K2) { + executor1.execute(new DFTLength3RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH4: { + while (k2++ < K2) { + executor1.execute(new DFTLength4RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH5: { + while (k2++ < K2) { + executor1.execute(new DFTLength5RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH6: { + while (k2++ < K2) { + executor1.execute(new DFTLength6RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH8: { + while (k2++ < K2) { + executor1.execute(new DFTLength8RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case MIXEDRADIX: { + while (k2++ < K2) { + executor1.execute(new DFTMixedRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat, fft1.K1)); + p += K1; + } + break; + } + case PADDEDRADER: { + while (k2++ < K2) { + executor1.execute(new DFTPaddedRaderRealFloat( + reDataFloat, imDataFloat, p, 1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADER: { + while (k2++ < K2) { + executor1.execute(new DFTRaderRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADIX2: { + while (k2++ < K2) { + executor1.execute(new DFTRadix2RealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootEvenFloat, fft1.imUnitRootEvenFloat, + fft1.reUnitRootOddFloat, fft1.imUnitRootOddFloat)); + p += K1; + } + break; + } + case SPLITRADIX: { + while (k2++ < K2) { + executor1.execute(new DFTSplitRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft2 = FFTSetup.transforms.get(height); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + break; + } + case COPRIMEFACTOR: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength2Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH3: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength3Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH4: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength4Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH5: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength5Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH6: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength6Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case LENGTH8: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength8Float( + reDataFloat, imDataFloat, k1, K1)); + } + break; + } + case MIXEDRADIX: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, fft2.K1)); + } + break; + } + case PADDEDRADER: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, k1, K1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + } + break; + } + case RADER: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + } + break; + } + case RADIX2: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + break; + } + case SPLITRADIX: { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = 0; + int regressive = K1; + while (++progressive < --regressive) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + } + p = K1 + 1; + int q = K1 * K2 - 1; + for (k2 = 1; (k2 < K2); k2++) { + progressive = p; + regressive = q; + for (int k1 = halfK1; (k1 < K1); k1++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive++; + regressive--; + } + p += K1; + q -= K1; + } +} /* end transformRealFloat2DRowFirst */ + +/*------------------------------------------------------------------*/ +private void transformRealFloat3DAcrossFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + final int halfK3 = (K3 >> 1) + 1; + int k = -1; + // First across for an odd (width * height) + if (1 == (K1K2 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(depth); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1K2, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1K2, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1K2, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + imDataFloat[0] = 0.0F; + break; + } + case LENGTH2: { + new DFTLength2RealFloat(reDataFloat, imDataFloat, + 0, K1K2).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reDataFloat, imDataFloat, + 0, K1K2).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reDataFloat, imDataFloat, + 0, K1K2).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reDataFloat, imDataFloat, + 0, K1K2).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reDataFloat, imDataFloat, + 0, K1K2).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reDataFloat, imDataFloat, + 0, K1K2).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1K2, + fft.reUnitRootFloat, fft.imUnitRootFloat, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reDataFloat, imDataFloat, 0, K1K2, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1K2, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1K2, + fft.reUnitRootEvenFloat, fft.imUnitRootEvenFloat, + fft.reUnitRootOddFloat, fft.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1K2, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + k = 0; + } + // Remaining across + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(depth); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (++k < K1K2) { + executor1.execute(new DFTBruteForceRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k, K1K2, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + } + break; + } + case COPRIMEFACTOR: { + while (++k < K1K2) { + executor1.execute(new DFTCoprimeFactorRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k, K1K2, + fft1.ruritanian, fft1.chinese, fft1.K1)); + } + break; + } + case DUOREAL: { + while (++k < K1K2) { + executor1.execute(new DFTDuoRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k, k + 1, K1K2, K3)); + k++; + } + break; + } + case EVENREAL: { + while (++k < K1K2) { + executor1.execute(new DFTEvenRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k, K1K2, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + } + break; + } + case LENGTH1: { + while (++k < K1K2) { + imDataFloat[k] = 0.0F; + } + break; + } + case LENGTH2: { + while (++k < K1K2) { + executor1.execute(new DFTLength2RealFloat( + reDataFloat, imDataFloat, k, K1K2)); + } + break; + } + case LENGTH3: { + while (++k < K1K2) { + executor1.execute(new DFTLength3RealFloat( + reDataFloat, imDataFloat, k, K1K2)); + } + break; + } + case LENGTH4: { + while (++k < K1K2) { + executor1.execute(new DFTLength4RealFloat( + reDataFloat, imDataFloat, k, K1K2)); + } + break; + } + case LENGTH5: { + while (++k < K1K2) { + executor1.execute(new DFTLength5RealFloat( + reDataFloat, imDataFloat, k, K1K2)); + } + break; + } + case LENGTH6: { + while (++k < K1K2) { + executor1.execute(new DFTLength6RealFloat( + reDataFloat, imDataFloat, k, K1K2)); + } + break; + } + case LENGTH8: { + while (++k < K1K2) { + executor1.execute(new DFTLength8RealFloat( + reDataFloat, imDataFloat, k, K1K2)); + } + break; + } + case MIXEDRADIX: { + while (++k < K1K2) { + executor1.execute(new DFTMixedRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k, K1K2, + fft1.reUnitRootFloat, fft1.imUnitRootFloat, fft1.K1)); + } + break; + } + case PADDEDRADER: { + while (++k < K1K2) { + executor1.execute(new DFTPaddedRaderRealFloat( + reDataFloat, imDataFloat, k, K1K2, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADER: { + while (++k < K1K2) { + executor1.execute(new DFTRaderRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k, K1K2, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADIX2: { + while (++k < K1K2) { + executor1.execute(new DFTRadix2RealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k, K1K2, + fft1.reUnitRootEvenFloat, fft1.imUnitRootEvenFloat, + fft1.reUnitRootOddFloat, fft1.imUnitRootOddFloat)); + } + break; + } + case SPLITRADIX: { + while (++k < K1K2) { + executor1.execute(new DFTSplitRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k, K1K2, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Rows + final FFTSetup fft2 = FFTSetup.transforms.get(width); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft2.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + p += K1; + } + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + p += K1; + } + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1)); + p += K1; + } + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p, 1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + p += K1; + } + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + p += K1; + } + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + p += K1; + } + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k2 = 0; (k2 < K2); k2++) { + executor2.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + p += K1; + } + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft3 = FFTSetup.transforms.get(height); + final ExecutorService executor3 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft3.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + } + p += K1K2; + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft3.ruritanian, fft3.chinese, fft3.K1)); + } + p += K1K2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft3.reUnitRootFloat, fft3.imUnitRootFloat, fft3.K1)); + } + p += K1K2; + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p + k1, K1, + fft3.reConvolverFloat, fft3.imConvolverFloat, + fft3.modular, fft3.inverseModular)); + } + p += K1K2; + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft3.reConvolverFloat, fft3.imConvolverFloat, + fft3.modular, fft3.inverseModular)); + } + p += K1K2; + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + } + p += K1K2; + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < halfK3); k3++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + } + p += K1K2; + } + break; + } + } + try { + executor3.shutdown(); + executor3.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = K1K2; + int regressive = dataLength - K1K2; + while (progressive < regressive) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive += K1K2; + regressive -= K1K2; + } + int p = K1K2 + K1; + int q = dataLength - K1; + for (int k3 = halfK3; (k3 < K3); k3++) { + progressive = p; + regressive = q; + for (int k2 = 1; (k2 < K2); k2++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive += K1; + regressive -= K1; + } + p += K1K2; + q -= K1K2; + } + p = K1K2 + 1; + q = K1K2 * (K3 - 1) + K1 - 1; + for (int k3 = halfK3; (k3 < K3); k3++) { + progressive = p; + regressive = q; + for (int k1 = 1; (k1 < K1); k1++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive++; + regressive--; + } + p += K1K2; + q -= K1K2; + } + progressive = K1K2 + K1 + 1; + regressive = dataLength - 1; + for (int k3 = halfK3; (k3 < K3); k3++) { + for (int k2 = 1; (k2 < K2); k2++) { + for (int k1 = 1; (k1 < K1); k1++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive++; + regressive--; + } + progressive++; + regressive--; + } + progressive += K1; + regressive -= K1; + } +} /* end transformRealFloat3DAcrossFirst */ + +/*------------------------------------------------------------------*/ +private void transformRealFloat3DColumnFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + final int k1K2 = K1K2 - K1; + final int K1K3 = K1 * K3; + final int halfK2 = (K2 >> 1) + 1; + int k = -1; + // First column for an odd (width * depth) + if (1 == (K1K3 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(height); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + imDataFloat[0] = 0.0F; + break; + } + case LENGTH2: { + new DFTLength2RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reDataFloat, imDataFloat, 0, K1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootFloat, fft.imUnitRootFloat, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reDataFloat, imDataFloat, 0, K1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootEvenFloat, fft.imUnitRootEvenFloat, + fft.reUnitRootOddFloat, fft.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, K1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + k = 0; + } + // Remaining columns + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(height); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (++k < K1K3) { + executor1.execute(new DFTBruteForceRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + } + break; + } + case COPRIMEFACTOR: { + while (++k < K1K3) { + executor1.execute(new DFTCoprimeFactorRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1K2 * (k / K1) + k, K1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + } + break; + } + case DUOREAL: { + while (++k < K1K3) { + final int p = k1K2 * (k / K1) + k; + k++; + final int q = k1K2 * (k / K1) + k; + executor1.execute(new DFTDuoRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, q, K1, K2)); + } + break; + } + case EVENREAL: { + while (++k < K1K3) { + executor1.execute(new DFTEvenRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + } + break; + } + case LENGTH1: { + while (++k < K1K3) { + imDataFloat[k] = 0.0F; + } + break; + } + case LENGTH2: { + while (++k < K1K3) { + executor1.execute(new DFTLength2RealFloat( + reDataFloat, imDataFloat, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH3: { + while (++k < K1K3) { + executor1.execute(new DFTLength3RealFloat( + reDataFloat, imDataFloat, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH4: { + while (++k < K1K3) { + executor1.execute(new DFTLength4RealFloat( + reDataFloat, imDataFloat, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH5: { + while (++k < K1K3) { + executor1.execute(new DFTLength5RealFloat( + reDataFloat, imDataFloat, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH6: { + while (++k < K1K3) { + executor1.execute(new DFTLength6RealFloat( + reDataFloat, imDataFloat, k1K2 * (k / K1) + k, K1)); + } + break; + } + case LENGTH8: { + while (++k < K1K3) { + executor1.execute(new DFTLength8RealFloat( + reDataFloat, imDataFloat, k1K2 * (k / K1) + k, K1)); + } + break; + } + case MIXEDRADIX: { + while (++k < K1K3) { + executor1.execute(new DFTMixedRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat, fft1.K1)); + } + break; + } + case PADDEDRADER: { + while (++k < K1K3) { + executor1.execute(new DFTPaddedRaderRealFloat( + reDataFloat, imDataFloat, k1K2 * (k / K1) + k, K1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADER: { + while (++k < K1K3) { + executor1.execute(new DFTRaderRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1K2 * (k / K1) + k, K1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + } + break; + } + case RADIX2: { + while (++k < K1K3) { + executor1.execute(new DFTRadix2RealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootEvenFloat, fft1.imUnitRootEvenFloat, + fft1.reUnitRootOddFloat, fft1.imUnitRootOddFloat)); + } + break; + } + case SPLITRADIX: { + while (++k < K1K3) { + executor1.execute(new DFTSplitRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, k1K2 * (k / K1) + k, K1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Rows + final FFTSetup fft2 = FFTSetup.transforms.get(width); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + final int skippedRows = (K2 - halfK2) * K1; + switch (fft2.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + p += K1; + } + p += skippedRows; + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + p += K1; + } + p += skippedRows; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH3: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH4: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH5: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH6: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case LENGTH8: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + p += skippedRows; + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, + fft2.K1)); + p += K1; + } + p += skippedRows; + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p, 1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + p += K1; + } + p += skippedRows; + } + break; + } + case RADER: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + p += K1; + } + p += skippedRows; + } + break; + } + case RADIX2: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + p += K1; + } + p += skippedRows; + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k3 = 0; (k3 < K3); k3++) { + for (int k2 = 0; (k2 < halfK2); k2++) { + executor2.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + p += K1; + } + p += skippedRows; + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Across + final FFTSetup fft3 = FFTSetup.transforms.get(depth); + final ExecutorService executor3 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft3.algorithm) { + case BRUTEFORCE: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + p++; + } + } + break; + } + case COPRIMEFACTOR: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.ruritanian, fft3.chinese, fft3.K1)); + p++; + } + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH3: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH4: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH5: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH6: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case LENGTH8: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p, K1K2)); + p++; + } + } + break; + } + case MIXEDRADIX: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat, fft3.K1)); + p++; + } + } + break; + } + case PADDEDRADER: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p, K1K2, + fft3.reConvolverFloat, fft3.imConvolverFloat, + fft3.modular, fft3.inverseModular)); + p++; + } + } + break; + } + case RADER: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reConvolverFloat, fft3.imConvolverFloat, + fft3.modular, fft3.inverseModular)); + p++; + } + } + break; + } + case RADIX2: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + p++; + } + } + break; + } + case SPLITRADIX: { + int p = 0; + for (int k2 = 0; (k2 < halfK2); k2++) { + for (int k1 = 0; (k1 < K1); k1++) { + executor3.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + p++; + } + } + break; + } + } + try { + executor3.shutdown(); + executor3.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = K1; + int regressive = K1K2 - K1; + while (progressive < regressive) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive += K1; + regressive -= K1; + } + int p = K1 + 1; + int q = K1K2 - 1; + for (int k2 = halfK2; (k2 < K2); k2++) { + progressive = p; + regressive = q; + for (int k1 = 1; (k1 < K1); k1++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive++; + regressive--; + } + p += K1; + q -= K1; + } + p = K1K2 + K1; + q = dataLength - K1; + for (int k3 = 1; (k3 < K3); k3++) { + progressive = p; + regressive = q; + for (int k2 = halfK2; (k2 < K2); k2++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive += K1; + regressive -= K1; + } + p += K1K2; + q -= K1K2; + } + progressive = K1K2 + K1 + 1; + regressive = dataLength - 1; + for (int k3 = 1; (k3 < K3); k3++) { + for (int k2 = halfK2; (k2 < K2); k2++) { + for (int k1 = 1; (k1 < K1); k1++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive++; + regressive--; + } + progressive++; + regressive--; + } + progressive += halfK2 * K1; + regressive -= halfK2 * K1; + } +} /* end transformRealFloat3DColumnFirst */ + +/*------------------------------------------------------------------*/ +private void transformRealFloat3DRowFirst ( +) { + final int K1 = width.intValue(); + final int K2 = height.intValue(); + final int K3 = depth.intValue(); + final int K1K2 = K1 * K2; + final int K2K3 = K2 * K3; + final int halfK1 = (K1 >> 1) + 1; + int k = 0; + int p = 0; + // First row for an odd (height * depth) + if (1 == (K2K3 & 1)) { + final FFTSetupReal fft = FFTSetupReal.transforms.get(width); + switch (fft.algorithm) { + case BRUTEFORCE: { + new DFTBruteForceRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case COPRIMEFACTOR: { + new DFTCoprimeFactorRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.ruritanian, fft.chinese, fft.K1).run(); + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + new DFTEvenRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + case LENGTH1: { + imDataFloat[0] = 0.0F; + break; + } + case LENGTH2: { + new DFTLength2RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH3: { + new DFTLength3RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH4: { + new DFTLength4RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH5: { + new DFTLength5RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH6: { + new DFTLength6RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case LENGTH8: { + new DFTLength8RealFloat(reDataFloat, imDataFloat, 0, 1).run(); + break; + } + case MIXEDRADIX: { + new DFTMixedRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat, fft.K1).run(); + break; + } + case PADDEDRADER: { + new DFTPaddedRaderRealFloat(reDataFloat, imDataFloat, 0, 1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADER: { + new DFTRaderRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reConvolverFloat, fft.imConvolverFloat, + fft.modular, fft.inverseModular).run(); + break; + } + case RADIX2: { + new DFTRadix2RealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootEvenFloat, fft.imUnitRootEvenFloat, + fft.reUnitRootOddFloat, fft.imUnitRootOddFloat).run(); + break; + } + case SPLITRADIX: { + new DFTSplitRadixRealFloat(reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, 0, 1, + fft.reUnitRootFloat, fft.imUnitRootFloat).run(); + break; + } + } + k = 1; + p = K1; + } + // Remaining rows + final FFTSetupDuoReal fft1 = FFTSetupDuoReal.transforms.get(width); + final ExecutorService executor1 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + switch (fft1.algorithm) { + case BRUTEFORCE: { + while (k++ < K2K3) { + executor1.execute(new DFTBruteForceRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + break; + } + case COPRIMEFACTOR: { + while (k++ < K2K3) { + executor1.execute(new DFTCoprimeFactorRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.ruritanian, fft1.chinese, fft1.K1)); + p += K1; + } + break; + } + case DUOREAL: { + while (k++ < K2K3) { + executor1.execute(new DFTDuoRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, p + K1, 1, K1)); + p += 2 * K1; + k++; + } + break; + } + case EVENREAL: { + while (k++ < K2K3) { + executor1.execute(new DFTEvenRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + break; + } + case LENGTH1: { + while (k++ < K2K3) { + imDataFloat[p] = 0.0F; + p += K1; + } + break; + } + case LENGTH2: { + while (k++ < K2K3) { + executor1.execute(new DFTLength2RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH3: { + while (k++ < K2K3) { + executor1.execute(new DFTLength3RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH4: { + while (k++ < K2K3) { + executor1.execute(new DFTLength4RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH5: { + while (k++ < K2K3) { + executor1.execute(new DFTLength5RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH6: { + while (k++ < K2K3) { + executor1.execute(new DFTLength6RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case LENGTH8: { + while (k++ < K2K3) { + executor1.execute(new DFTLength8RealFloat( + reDataFloat, imDataFloat, p, 1)); + p += K1; + } + break; + } + case MIXEDRADIX: { + while (k++ < K2K3) { + executor1.execute(new DFTMixedRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat, fft1.K1)); + p += K1; + } + break; + } + case PADDEDRADER: { + while (k++ < K2K3) { + executor1.execute(new DFTPaddedRaderRealFloat( + reDataFloat, imDataFloat, p, 1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADER: { + while (k++ < K2K3) { + executor1.execute(new DFTRaderRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reConvolverFloat, fft1.imConvolverFloat, + fft1.modular, fft1.inverseModular)); + p += K1; + } + break; + } + case RADIX2: { + while (k++ < K2K3) { + executor1.execute(new DFTRadix2RealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootEvenFloat, fft1.imUnitRootEvenFloat, + fft1.reUnitRootOddFloat, fft1.imUnitRootOddFloat)); + p += K1; + } + break; + } + case SPLITRADIX: { + while (k++ < K2K3) { + executor1.execute(new DFTSplitRadixRealFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p, 1, + fft1.reUnitRootFloat, fft1.imUnitRootFloat)); + p += K1; + } + break; + } + } + try { + executor1.shutdown(); + executor1.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Columns + final FFTSetup fft2 = FFTSetup.transforms.get(height); + final ExecutorService executor2 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + p = 0; + switch (fft2.algorithm) { + case BRUTEFORCE: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + p += K1K2; + } + break; + } + case COPRIMEFACTOR: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.ruritanian, fft2.chinese, fft2.K1)); + } + p += K1K2; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH3: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH4: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH5: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH6: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case LENGTH8: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p + k1, K1)); + } + p += K1K2; + } + break; + } + case MIXEDRADIX: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat, fft2.K1)); + } + p += K1K2; + } + break; + } + case PADDEDRADER: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p + k1, K1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + } + p += K1K2; + } + break; + } + case RADER: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reConvolverFloat, fft2.imConvolverFloat, + fft2.modular, fft2.inverseModular)); + } + p += K1K2; + } + break; + } + case RADIX2: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + p += K1K2; + } + break; + } + case SPLITRADIX: { + for (int k3 = 0; (k3 < K3); k3++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor2.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1, + fft2.reUnitRootFloat, fft2.imUnitRootFloat)); + } + p += K1K2; + } + break; + } + } + try { + executor2.shutdown(); + executor2.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + // Across + final FFTSetup fft3 = FFTSetup.transforms.get(depth); + final ExecutorService executor3 = + (PARALLELPROCESSING) ? (Executors.newFixedThreadPool( + Runtime.getRuntime().availableProcessors())) + : (Executors.newSingleThreadExecutor()); + p = 0; + switch (fft3.algorithm) { + case BRUTEFORCE: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTBruteForceFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + } + p += K1; + } + break; + } + case COPRIMEFACTOR: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTCoprimeFactorFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1K2, + fft3.ruritanian, fft3.chinese, fft3.K1)); + } + p += K1; + } + break; + } + case DUOREAL: { + throw(new IllegalStateException()); + } + case EVENREAL: { + throw(new IllegalStateException()); + } + case LENGTH1: { + break; + } + case LENGTH2: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength2Float( + reDataFloat, imDataFloat, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH3: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength3Float( + reDataFloat, imDataFloat, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH4: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength4Float( + reDataFloat, imDataFloat, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH5: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength5Float( + reDataFloat, imDataFloat, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH6: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength6Float( + reDataFloat, imDataFloat, p + k1, K1K2)); + } + p += K1; + } + break; + } + case LENGTH8: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTLength8Float( + reDataFloat, imDataFloat, p + k1, K1K2)); + } + p += K1; + } + break; + } + case MIXEDRADIX: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTMixedRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat, fft3.K1)); + } + p += K1; + } + break; + } + case PADDEDRADER: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTPaddedRaderFloat( + reDataFloat, imDataFloat, p + k1, K1K2, + fft3.reConvolverFloat, fft3.imConvolverFloat, + fft3.modular, fft3.inverseModular)); + } + p += K1; + } + break; + } + case RADER: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTRaderFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1K2, + fft3.reConvolverFloat, fft3.imConvolverFloat, + fft3.modular, fft3.inverseModular)); + } + p += K1; + } + break; + } + case RADIX2: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTRadix2Float( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + } + p += K1; + } + break; + } + case SPLITRADIX: { + for (int k2 = 0; (k2 < K2); k2++) { + for (int k1 = 0; (k1 < halfK1); k1++) { + executor3.execute(new DFTSplitRadixFloat( + reDataFloat, imDataFloat, + reBufferFloat, imBufferFloat, p + k1, K1K2, + fft3.reUnitRootFloat, fft3.imUnitRootFloat)); + } + p += K1; + } + break; + } + } + try { + executor3.shutdown(); + executor3.awaitTermination((long)(Integer.MAX_VALUE), TimeUnit.DAYS); + } + catch (InterruptedException ignored) { + } + int progressive = 0; + int regressive = K1; + while (++progressive < --regressive) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + } + p = K1 + 1; + int q = K1K2 - 1; + for (int k2 = 1; (k2 < K2); k2++) { + progressive = p; + regressive = q; + for (int k1 = halfK1; (k1 < K1); k1++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive++; + regressive--; + } + p += K1; + q -= K1; + } + p = K1K2 + 1; + q = K1K2 * (K3 - 1) + K1 - 1; + for (int k3 = 1; (k3 < K3); k3++) { + progressive = p; + regressive = q; + for (int k1 = halfK1; (k1 < K1); k1++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive++; + regressive--; + } + p += K1K2; + q -= K1K2; + } + progressive = K1K2 + K1 + 1; + regressive = dataLength - 1; + for (int k3 = 1; (k3 < K3); k3++) { + for (int k2 = 1; (k2 < K2); k2++) { + for (int k1 = halfK1; (k1 < K1); k1++) { + reDataFloat[regressive] = reDataFloat[progressive]; + imDataFloat[regressive] = -imDataFloat[progressive]; + progressive++; + regressive--; + } + progressive += halfK1; + regressive -= halfK1; + } + progressive += K1; + regressive -= K1; + } +} /* end transformRealFloat3DRowFirst */ + +} /* end class SlowFourierTransform */ diff --git a/src/bilib/src/bilib/optimization/.DS_Store b/src/bilib/src/bilib/optimization/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1819d85b732e46e0739ef8393b27c7199da021a0 Binary files /dev/null and b/src/bilib/src/bilib/optimization/.DS_Store differ diff --git a/src/bilib/src/bilib/optimization/levenbergmarquardt/Cholesky.java b/src/bilib/src/bilib/optimization/levenbergmarquardt/Cholesky.java new file mode 100644 index 0000000000000000000000000000000000000000..49fe8290d71f8a0820bda79f6c6a23fba22f8433 --- /dev/null +++ b/src/bilib/src/bilib/optimization/levenbergmarquardt/Cholesky.java @@ -0,0 +1,111 @@ +package bilib.optimization.levenbergmarquardt; + +/** + * + * <p> + * Title: Cholesky Decomposition + * </p> + * <p> + * Description: Performs a Cholesky decomposition of a matrix and solve a linear + * system using this decomposition. Ported to Java from the Numerical Recipes in + * C. Press, Teukolsky, Vetterling,and Flannery. 2nd edition. Cambridge + * University Press, 1992. + * </p> + */ + +public class Cholesky { + + /** + * Given a positive-definite symmetric matrix A[1..n][1..n], this method + * constructs its Cholesky decomposition, A = L � L' . On input, only the + * upper triangle of a need be given; it is not modified. The Cholesky + * factor L is returned in the lower triangle of a, except for its diagonal + * elements which are returned in p[1..n]. + * + * @param A + * double[][] Input matrix. + * @param p + * double[] + * @return boolean Returns false if the decomposition is not possible. + */ + public static boolean decomp(double[][] A, double[] p) { + int n = A.length; + int i, j, k; + double sum; + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + sum = A[i][j]; + for (k = i - 1; k >= 0; k--) { + sum -= (A[i][k] * A[j][k]); + } + if (i == j) { + if (sum <= 0.) { + return false; // not positive definite + } + p[i] = Math.sqrt(sum); + } + else { + A[j][i] = sum / p[i]; + } + } + } + return true; + } // decomp + + /** + * Solves a the linear system Ax=b. + * + * @param A + * double[][] Is the result of decomp(A) + * @param p + * double[] The resulting diagonal vector. + * @param b + * double[] + * @param x + * double[] + */ + private static void solve(double[][] A, double[] p, double[] b, double[] x) { + int n = A.length; + int i, k; + double sum; + // Solve L � y = b, storing y in x. + for (i = 0; i < n; i++) { + sum = b[i]; + for (k = i - 1; k >= 0; k--) { + sum -= (A[i][k] * x[k]); + } + x[i] = sum / p[i]; + } + + // Solve L' � x = y. + for (i = n - 1; i >= 0; i--) { + sum = x[i]; + for (k = i + 1; k < n; k++) { + sum -= (A[k][i] * x[k]); + } + x[i] = sum / p[i]; + } + } // solve + + /** + * Solves the linear system Ax=b. + * + * @param A + * double[][] + * @param x + * double[] + * @param b + * double[] + * @return boolean returns false if the system can not be solved using + * Cholesky decomposition. + */ + public static boolean solve(double[][] A, double[] x, double[] b) { + double[] p = new double[A.length]; + if (!decomp(A, p)) { + return false; + } + solve(A, p, b, x); + return true; + } // solve + +} // Cholesky diff --git a/src/bilib/src/bilib/optimization/levenbergmarquardt/Function.java b/src/bilib/src/bilib/optimization/levenbergmarquardt/Function.java new file mode 100644 index 0000000000000000000000000000000000000000..8adc8be5dd76f2194a8bdf5af4fa4901e3c99b81 --- /dev/null +++ b/src/bilib/src/bilib/optimization/levenbergmarquardt/Function.java @@ -0,0 +1,32 @@ +package bilib.optimization.levenbergmarquardt; + +/** + */ +public interface Function { + + /** + * Evaluates the model at point x (may be mulidimensional). + * + * @param x + * double[] Point where we evaluate the model function. + * @param a + * double[] Model estimators. + * @return double + */ + public abstract double eval(double[] x, double[] a); + + /** + * Returns the kth component of the gradient df(x,a)/da_k + * + * @param x + * double[] + * @param a + * double[] + * @param ak + * int + * @return double + */ + public abstract double grad(double[] x, double[] a, int ak); + + public abstract void setDebug(boolean debug); +} diff --git a/src/bilib/src/bilib/optimization/levenbergmarquardt/LevenbergMarquardt.java b/src/bilib/src/bilib/optimization/levenbergmarquardt/LevenbergMarquardt.java new file mode 100644 index 0000000000000000000000000000000000000000..3ef29f8720ccc3472fbb766fea869e1f37f5d0cf --- /dev/null +++ b/src/bilib/src/bilib/optimization/levenbergmarquardt/LevenbergMarquardt.java @@ -0,0 +1,297 @@ +package bilib.optimization.levenbergmarquardt; + +/** + * + * <p> + * Title: Levenberg-Marquardt + * </p> + * <p> + * Description: Perfoms data fitting to a non linear model using the + * Levenberg-Marquadrt method. Ported to Java from the Numerical Recipes in C. + * Press, Teukolsky, Vetterling,and Flannery. 2nd edition. Cambridge University + * Press, 1992. + * </p> + */ + +public class LevenbergMarquardt { + + private Function f; + private double lambdaInitial = 0.0001; + private int itmax = 1000; + private boolean print = false; + private int iter; + private double tolerance = 0.001; + + /** + * Levenberg-Marquardt constructor. Supply a Function object, f, that + * evaluates the fitting function y, and its derivatives dyda[1..ma] with + * respect to the fitting parameters a at x. On the first call provide an + * initial guess for the parameters a, and set alamda to some small value, + * e.g. alambda=0.001. If a step succeeds chisq becomes smaller and alamda + * decreases by a factor of 10. If a step fails alamda grows by a factor of + * 10. + * + * @param f + * Function + * @param lambdaInitial + * double + * @param itmax + * int + */ + public LevenbergMarquardt(Function f, double lambdaInitial, int itmax, boolean print) { + this.f = f; + this.lambdaInitial = lambdaInitial; + this.itmax = itmax; + this.print = print; + if (print) { + System.out.print("CONSTRUCTOR \tlambda:" + lambdaInitial + " max iterations: " + itmax); + } + } + + public LevenbergMarquardt(Function f, int itmax, double tolerance) { + this.f = f; + this.itmax = itmax; + this.tolerance = tolerance; + } + + public LevenbergMarquardt(Function f, int itmax) { + this.f = f; + this.itmax = itmax; + } + + public LevenbergMarquardt(Function f, boolean print) { + this.f = f; + this.print = print; + } + + public LevenbergMarquardt(Function f) { + this.f = f; + } + + public void setPrint(boolean print) { + this.print = print; + } + + /** + * Levenberg-Marquardt method, attempting to reduce the value chi2 of a fit + * between a set of data points x[1..ndata], y[1..ndata] with individual + * standard deviations sig[1..ndata], and a nonlinear function dependent on + * ma coefficients a[1..ma]. The input array ia[1..ma] indicates by true, + * entries those components of a that should be fitted for, and by false, + * entries those components that should be held fixed at their input values. + * The program returns current best-fit values for the parameters a[1..ma], + * and chi2 = chisq. + * + * @param x + * double[] + * @param y + * double[] + * @param sig + * double[] + * @param a + * double[] + * @return double + * + */ + public double minimize(double x[], double y[], double sig[], double a[]) { + iter = 0; + double lambda = lambdaInitial; + + boolean ia[] = new boolean[a.length]; + for (int i = 0; i < a.length; i++) + ia[i] = true; + + int rep = 0; + boolean done = false; + double eps = 0; + int mfit = 0; + int j, k, l; + int ma = a.length; + double ochisq = 0, chisq; + + double[][] covar = new double[ma][ma]; + double[][] alpha = new double[ma][ma]; + double[] beta = new double[ma]; + double[] atry = new double[ma]; + double[] da = new double[ma]; + + double[] oneda; + + // initialization + for (mfit = 0, j = 0; j < ma; j++) { + if (ia[j]) { + mfit++; + } + } + oneda = new double[mfit]; + + chisq = mrqcof(x, y, sig, a, ia, alpha, beta); + ochisq = chisq; + for (j = 0; j < ma; j++) { + atry[j] = a[j]; + } + + do { + // Alter linearized fitting matrix, by augmenting diagonal elements. + for (j = 0; j < mfit; j++) { + for (k = 0; k < mfit; k++) { + covar[j][k] = alpha[j][k]; + } + covar[j][j] = alpha[j][j] * (1.0 + lambda); + oneda[j] = beta[j]; + } + + Cholesky.solve(covar, oneda, oneda); // Matrix solution. + + for (j = 0; j < mfit; j++) { + da[j] = oneda[j]; + } + + for (j = 0, l = 0; l < ma; l++) { + if (ia[l]) { + atry[l] = a[l] + da[j++]; + } + } + chisq = mrqcof(x, y, sig, atry, ia, covar, da); + eps = Math.abs(chisq - ochisq); + if (print) { + System.out.print("#" + iter + "\t chi:" + Math.round(Math.sqrt(chisq) * 1000) / 1000.0 + " \tlambda:" + lambda + " eps:" + eps); + for (int i = 0; i < a.length; i++) + System.out.print("\t a[" + i + "]=" + atry[i]); + System.out.println(";"); + } + if (chisq < ochisq) { + // Success, accept the new solution. + lambda *= 0.1; + ochisq = chisq; + for (j = 0; j < mfit; j++) { + for (k = 0; k < mfit; k++) { + alpha[j][k] = covar[j][k]; + } + beta[j] = da[j]; + } + for (l = 0; l < ma; l++) { + a[l] = atry[l]; + } + } + else { + // Failure, increase alamda and return. + lambda *= 10.0; + chisq = ochisq; + } + iter++; + if (eps > tolerance) { + rep = 0; + } + else { + rep++; + if (rep == 4) { + done = true; + } + } + + } + while (iter < itmax && !done); + if (print) + System.out.println("Final iter" + iter + "\t rep:" + rep + " \tdone:" + done + " eps:" + eps + " tolerance:" + tolerance); + + return Math.sqrt(chisq); + } + + /** + * Return the number of iterations after minimization. + * + * @return number of iteration + */ + public int getIteration() { + return iter; + } + + /** + * Used by mrqmin to evaluate the linearized fitting matrix alpha, and + * vector beta as in "NR in C"(15.5.8), and calculate chi2. + * + * @param x + * double[] + * @param y + * double[] + * @param sig + * double[] + * @param a + * double[] + * @param ia + * boolean[] + * @param alpha + * double[][] + * @param beta + * double[] + * @param f + * LMfunc + * @return double + */ + private double mrqcof(double x[], double y[], double sig[], double a[], boolean ia[], double alpha[][], double beta[]) { + + int ndata = x.length; + int ma = a.length; + double chisq; + int i, j, k, l, m, mfit = 0; + double ymod, wt, sig2i, dy; + double[] dyda = new double[ma]; + + for (j = 0; j < ma; j++) { + if (ia[j]) { + mfit++; + } + } + + // Initialize(symmetric) alpha, beta. + for (j = 0; j < mfit; j++) { + for (k = 0; k <= j; k++) { + alpha[j][k] = 0; + } + beta[j] = 0; + } + + chisq = 0; + + // Summation loop over all data. + for (i = 0; i < ndata; i++) { + double[] xi = new double[1]; + xi[0] = x[i]; + ymod = f.eval(xi, a); + for (k = 0; k < a.length; k++) { + dyda[k] = f.grad(xi, a, k); + } + + /* + * if (print) { System.out.print("D" + iter); for(int p=0; + * p<dyda.length; p++) System.out.print("\t da["+p+"]=" + dyda[p]); + * System.out.println(";"); } + */ + sig2i = 1.0 / (sig[i] * sig[i]); + dy = y[i] - ymod; + for (j = 0, l = 0; l < ma; l++) { + if (ia[l]) { + wt = dyda[l] * sig2i; + for (k = 0, m = 0; m <= l; m++) { + if (ia[m]) { + alpha[j][k++] += wt * dyda[m]; + } + } + beta[j] += dy * wt; + j++; + } + } + chisq += dy * dy * sig2i; // And find chi2. + } + + // Fill in the symmetric side of alpha + for (j = 1; j < mfit; j++) { + for (k = 0; k < j; k++) { + alpha[k][j] = alpha[j][k]; + } + } + return chisq; + } + +} diff --git a/src/bilib/src/ijtools/Convolver1D.java b/src/bilib/src/ijtools/Convolver1D.java new file mode 100644 index 0000000000000000000000000000000000000000..c8a6b34195d1d7eab08acf785570162c0e22a5ed --- /dev/null +++ b/src/bilib/src/ijtools/Convolver1D.java @@ -0,0 +1,118 @@ +package ijtools; + +/** + * Fast 1-D convolution routines for symmetric kernels. All methods require only + * the causal half of the kernel, i.e., elements [0..n], assuming a support of + * [-n..n]. Only kernels with odd support are implemented. Mirror border + * conditions are applied. + * + * @author Francois Aguet + * @version 1.0 + */ +public class Convolver1D { + + /** + * Convolution with a symmetric kernel. + */ + public static double[] convolveEven(double[] input, double[] kernel) { + + int nx = input.length; + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + double[] output = new double[nx]; + + for (int x = 0; x < k_1; x++) { + output[x] = kernel[0] * input[x]; + for (int i = 1; i <= x; i++) { + output[x] += kernel[i] * (input[x - i] + input[x + i]); + } + for (int i = x + 1; i < k; i++) { + output[x] += kernel[i] * (input[i - x] + input[x + i]); + } + } + for (int x = k_1; x <= nx - k; x++) { + output[x] = kernel[0] * input[x]; + for (int i = 1; i < k; i++) { + output[x] += kernel[i] * (input[x - i] + input[x + i]); + } + } + for (int x = nx - k_1; x < nx; x++) { + output[x] = kernel[0] * input[x]; + for (int i = 1; i < nx - x; i++) { + output[x] += kernel[i] * (input[x - i] + input[x + i]); + } + for (int i = nx - x; i < k; i++) { + output[x] += kernel[i] * (input[b - i - x] + input[x - i]); + } + } + return output; + } + + /** + * Convolution with an anti-symmetric kernel. + */ + public static double[] convolveOdd(double[] input, double[] kernel) { + + int nx = input.length; + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + double[] output = new double[nx]; + + for (int x = 0; x < k_1; x++) { + output[x] = 0.0; + for (int i = 1; i <= x; i++) { + output[x] += kernel[i] * (input[x + i] - input[x - i]); + } + for (int i = x + 1; i < k; i++) { + output[x] += kernel[i] * (input[x + i] - input[i - x]); + } + } + for (int x = k_1; x <= nx - k; x++) { + output[x] = 0.0; + for (int i = 1; i < k; i++) { + output[x] += kernel[i] * (input[x + i] - input[x - i]); + } + } + for (int x = nx - k_1; x < nx; x++) { + output[x] = 0.0; + for (int i = 1; i < nx - x; i++) { + output[x] += kernel[i] * (input[x + i] - input[x - i]); + } + for (int i = nx - x; i < k; i++) { + output[x] += kernel[i] * (input[b - i - x] - input[x - i]); + } + } + return output; + } + + /** + * Moving sum filter. The length of the output is extended by 'length-1'. + */ + public static double[] movingSum(double[] input, int length) { + + int nx = input.length; + double[] output = new double[nx + length - 1]; + output[0] = input[0]; + for (int i = 1; i < length; i++) { + output[0] += input[i]; + } + for (int i = 1; i < length; i++) { + output[i] = output[i - 1] - input[length - i] + input[i]; // 0 - + // (idx-w) + } + for (int i = length; i < nx; i++) { + output[i] = output[i - 1] - input[i - length] + input[i]; + } + for (int i = nx; i < nx + length - 1; i++) { + output[i] = output[i - 1] - input[i - length] + input[2 * nx - i - 2]; // nx-1 + // - + // (i-(nx-1)) + } + return output; + } + +} diff --git a/src/bilib/src/ijtools/Convolver2D.java b/src/bilib/src/ijtools/Convolver2D.java new file mode 100644 index 0000000000000000000000000000000000000000..43bec6247b7a1b4975ccac4cfbd0b193a59b82f2 --- /dev/null +++ b/src/bilib/src/ijtools/Convolver2D.java @@ -0,0 +1,1133 @@ +package ijtools; + +/** + * Fast 2-D convolution routines for symmetric kernels. All methods require only + * the causal half of the kernel, i.e., elements [0..n], assuming a support of + * [-n..n]. Only kernels with odd support are implemented. Mirror border + * conditions are applied. + * + * @author Francois Aguet + * @version 1.0 + */ +public class Convolver2D { + + /** + * Moving sum filter, applied to both dimensions. Each dimension of the + * output is extended by 'length-1'. + */ + public static double[][] movingSum(double[][] input, int length) { + + int nx = input.length; + int ny = input[0].length; + + double[][] output = new double[nx + length - 1][ny + length - 1]; + + for (int y = 0; y < ny; y++) { + output[0][y] = input[0][y]; + for (int x = 1; x < length; x++) { + output[0][y] += input[x][y]; + } + for (int x = 1; x < length; x++) { + output[x][y] = output[x - 1][y] - input[length - x][y] + input[x][y]; + } + for (int x = length; x < nx; x++) { + output[x][y] = output[x - 1][y] - input[x - length][y] + input[x][y]; + } + for (int x = nx; x < nx + length; x++) { + output[x][y] = output[x - 1][y] - input[x - length][y] + input[2 * nx - x - 2][y]; + } + } + + for (int x = 0; x < nx + length - 1; x++) { + output[x][0] = output[x][0]; + for (int y = 1; y < length; y++) { + output[x][0] += output[x][y]; + } + for (int y = 1; y < length; y++) { + output[x][y] = output[x][y - 1] - output[x][length - y] + output[x][y]; + } + for (int y = length; y < ny; y++) { + output[x][y] = output[x][y - 1] - output[x][y - length] + output[x][y]; + } + for (int y = ny; y < ny + length - y; y++) { + output[x][y] = output[x][y - 1] - output[x][y - length] + output[x][2 * ny - y - 2]; + } + } + + return output; + } + + /** + * Moving sum filter, applied to the x-dimension. The x-dimension of the + * output is extended by 'length-1'. + */ + public static double[][] movingSumX(double[][] input, int length) { + + int nx = input.length; + int ny = input[0].length; + + double[][] output = new double[nx + length - 1][ny + length - 1]; + + for (int y = 0; y < ny; y++) { + output[0][y] = input[0][y]; + for (int x = 1; x < length; x++) { + output[0][y] += input[x][y]; + } + for (int x = 1; x < length; x++) { + output[x][y] = output[x - 1][y] - input[length - x][y] + input[x][y]; + } + for (int x = length; x < nx; x++) { + output[x][y] = output[x - 1][y] - input[x - length][y] + input[x][y]; + } + for (int x = nx; x < nx + length; x++) { + output[x][y] = output[x - 1][y] - input[x - length][y] + input[2 * nx - x - 2][y]; + } + } + return output; + } + + /** + * Moving sum filter, applied to the y-dimension. The y-dimension of the + * output is extended by 'length-1'. + */ + public static double[][] movingSumY(double[][] input, int length) { + + int nx = input.length; + int ny = input[0].length; + + double[][] output = new double[nx + length - 1][ny + length - 1]; + + for (int x = 0; x < nx + length - 1; x++) { + output[x][0] = output[x][0]; + for (int y = 1; y < length; y++) { + output[x][0] += output[x][y]; + } + for (int y = 1; y < length; y++) { + output[x][y] = output[x][y - 1] - output[x][length - y] + output[x][y]; + } + for (int y = length; y < ny; y++) { + output[x][y] = output[x][y - 1] - output[x][y - length] + output[x][y]; + } + for (int y = ny; y < ny + length - y; y++) { + output[x][y] = output[x][y - 1] - output[x][y - length] + output[x][2 * ny - y - 2]; + } + } + + return output; + } + + /** + * Convolution with a symmetric kernel along x. + */ + public static double[][] convolveEvenX(double[][] input, double[] kernel) { + + int nx = input.length; + int ny = input[0].length; + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + double[][] output = new double[nx][ny]; + + int idx = 0; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < k_1; x++) { + output[x][y] = kernel[0] * input[x][y]; + for (int i = 1; i <= x; i++) { + output[x][y] += kernel[i] * (input[x - i][y] + input[x + i][y]); + } + for (int i = x + 1; i < k; i++) { + output[x][y] += kernel[i] * (input[i - x][y] + input[x + i][y]); + } + } + for (int x = k_1; x <= nx - k; x++) { + output[x][y] = kernel[0] * input[x][y]; + for (int i = 1; i < k; i++) { + output[x][y] += kernel[i] * (input[x - i][y] + input[x + i][y]); + } + } + for (int x = nx - k_1; x < nx; x++) { + output[x][y] = kernel[0] * input[x][y]; + for (int i = 1; i < nx - x; i++) { + output[x][y] += kernel[i] * (input[x - i][y] + input[x + i][y]); + } + for (int i = nx - x; i < k; i++) { + output[x][y] += kernel[i] * (input[b - i - x][y] + input[x - i][y]); + } + } + } + return output; + } + + /** + * Convolution with a symmetric kernel along x, for an image defined as a + * 1-D array. + */ + public static double[] convolveEvenX(double[] input, double[] kernel, int nx, int ny) { + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + double[] output = new double[nx * ny]; + + int idx = 0; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < k_1; x++) { + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i <= x; i++) { + output[idx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + for (int i = x + 1; i < k; i++) { + output[idx] += kernel[i] * (input[i - x + y * nx] + input[idx + i]); + } + idx++; + } + for (int x = k_1; x <= nx - k; x++) { + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + output[idx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + idx++; + } + for (int x = nx - k_1; x < nx; x++) { + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i < nx - x; i++) { + output[idx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + for (int i = nx - x; i < k; i++) { + output[idx] += kernel[i] * (input[b - i - x + y * nx] + input[idx - i]); + } + idx++; + } + } + return output; + } + + /** + * Convolution with a symmetric kernel along x, for an image defined as a + * 1-D array. + */ + public static float[] convolveEvenX(float[] input, float[] kernel, int nx, int ny) { + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + float[] output = new float[nx * ny]; + + int idx = 0; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < k_1; x++) { + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i <= x; i++) { + output[idx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + for (int i = x + 1; i < k; i++) { + output[idx] += kernel[i] * (input[i - x + y * nx] + input[idx + i]); + } + idx++; + } + for (int x = k_1; x <= nx - k; x++) { + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + output[idx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + idx++; + } + for (int x = nx - k_1; x < nx; x++) { + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i < nx - x; i++) { + output[idx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + for (int i = nx - x; i < k; i++) { + output[idx] += kernel[i] * (input[b - i - x + y * nx] + input[idx - i]); + } + idx++; + } + } + return output; + } + + /** + * Convolution with a symmetric kernel along y. + */ + public static double[][] convolveEvenY(double[][] input, double[] kernel) { + + int nx = input.length; + int ny = input[0].length; + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * ny - 2; + + double[][] output = new double[nx][ny]; + + for (int x = 0; x < nx; x++) { + for (int y = 0; y < k_1; y++) { + output[x][y] = kernel[0] * input[x][y]; + for (int i = 1; i <= y; i++) { + output[x][y] += kernel[i] * (input[x][y - i] + input[x][y + i]); + } + for (int i = y + 1; i < k; i++) { + output[x][y] += kernel[i] * (input[x][i - y] + input[x][y + i]); + } + } + for (int y = k_1; y <= ny - k; y++) { + output[x][y] = kernel[0] * input[x][y]; + for (int i = 1; i < k; i++) { + output[x][y] += kernel[i] * (input[x][y - i] + input[x][y + i]); + } + } + for (int y = ny - k_1; y < ny; y++) { + output[x][y] = kernel[0] * input[x][y]; + for (int i = 1; i < ny - y; i++) { + output[x][y] += kernel[i] * (input[x][y - i] + input[x][y + i]); + } + for (int i = ny - y; i < k; i++) { + output[x][y] += kernel[i] * (input[x][b - i - y] + input[x][y - i]); + } + } + } + return output; + } + + /** + * Convolution with a symmetric kernel along y, for an image defined as a + * 1-D array. + */ + public static double[] convolveEvenY(double[] input, double[] kernel, int nx, int ny) { + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * ny - 2; + + double[] output = new double[nx * ny]; + + int idx, inx; + for (int x = 0; x < nx; x++) { + for (int y = 0; y < k_1; y++) { + idx = x + y * nx; + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i <= y; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + for (int i = y + 1; i < k; i++) { + output[idx] += kernel[i] * (input[(i - y) * nx + x] + input[idx + i * nx]); + } + } + for (int y = k_1; y <= ny - k; y++) { + idx = x + y * nx; + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + } + for (int y = ny - k_1; y < ny; y++) { + idx = x + y * nx; + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i < ny - y; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + for (int i = ny - y; i < k; i++) { + output[idx] += kernel[i] * (input[(b - i - y) * nx + x] + input[idx - i * nx]); + } + } + } + return output; + } + + /** + * Convolution with a symmetric kernel along y, for an image defined as a + * 1-D array. + */ + public static float[] convolveEvenY(float[] input, float[] kernel, int nx, int ny) { + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * ny - 2; + + float[] output = new float[nx * ny]; + + int idx, inx; + for (int x = 0; x < nx; x++) { + for (int y = 0; y < k_1; y++) { + idx = x + y * nx; + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i <= y; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + for (int i = y + 1; i < k; i++) { + output[idx] += kernel[i] * (input[(i - y) * nx + x] + input[idx + i * nx]); + } + } + for (int y = k_1; y <= ny - k; y++) { + idx = x + y * nx; + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + } + for (int y = ny - k_1; y < ny; y++) { + idx = x + y * nx; + output[idx] = kernel[0] * input[idx]; + for (int i = 1; i < ny - y; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + for (int i = ny - y; i < k; i++) { + output[idx] += kernel[i] * (input[(b - i - y) * nx + x] + input[idx - i * nx]); + } + } + } + return output; + } + + /** + * Convolution with an anti-symmetric kernel along x. + */ + public static double[][] convolveOddX(double[][] input, double[] kernel) { + + int nx = input.length; + int ny = input[0].length; + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + double[][] output = new double[nx][ny]; + + for (int y = 0; y < ny; y++) { + for (int x = 0; x < k_1; x++) { + output[x][y] = 0.0; + for (int i = 1; i <= x; i++) { + output[x][y] += kernel[i] * (input[x + i][y] - input[x - i][y]); + } + for (int i = x + 1; i < k; i++) { + output[x][y] += kernel[i] * (input[x + i][y] - input[i - x][y]); + } + } + for (int x = k_1; x <= nx - k; x++) { + output[x][y] = 0.0; + for (int i = 1; i < k; i++) { + output[x][y] += kernel[i] * (input[x + i][y] - input[x - i][y]); + } + } + for (int x = nx - k_1; x < nx; x++) { + output[x][y] = 0.0; + for (int i = 1; i < nx - x; i++) { + output[x][y] += kernel[i] * (input[x + i][y] - input[x - i][y]); + } + for (int i = nx - x; i < k; i++) { + output[x][y] += kernel[i] * (input[b - i - x][y] - input[x - i][y]); + } + } + } + return output; + } + + /** + * Convolution with an anti-symmetric kernel along x, for an image defined + * as a 1-D array. + */ + public static double[] convolveOddX(double[] input, double[] kernel, int nx, int ny) { + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + double[] output = new double[nx * ny]; + + int idx = 0; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < k_1; x++) { + output[idx] = 0.0; + for (int i = 1; i <= x; i++) { + output[idx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + for (int i = x + 1; i < k; i++) { + output[idx] += kernel[i] * (input[idx + i] - input[i - x + y * nx]); + } + idx++; + } + for (int x = k_1; x <= nx - k; x++) { + output[idx] = 0.0; + for (int i = 1; i < k; i++) { + output[idx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + idx++; + } + for (int x = nx - k_1; x < nx; x++) { + output[idx] = 0.0; + for (int i = 1; i < nx - x; i++) { + output[idx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + for (int i = nx - x; i < k; i++) { + output[idx] += kernel[i] * (input[b - i - x + y * nx] - input[idx - i]); + } + idx++; + } + } + return output; + } + + /** + * Convolution with an anti-symmetric kernel along x, for an image defined + * as a 1-D array. + */ + public static float[] convolveOddX(float[] input, float[] kernel, int nx, int ny) { + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + float[] output = new float[nx * ny]; + + int idx = 0; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < k_1; x++) { + output[idx] = 0.0f; + for (int i = 1; i <= x; i++) { + output[idx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + for (int i = x + 1; i < k; i++) { + output[idx] += kernel[i] * (input[idx + i] - input[i - x + y * nx]); + } + idx++; + } + for (int x = k_1; x <= nx - k; x++) { + output[idx] = 0.0f; + for (int i = 1; i < k; i++) { + output[idx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + idx++; + } + for (int x = nx - k_1; x < nx; x++) { + output[idx] = 0.0f; + for (int i = 1; i < nx - x; i++) { + output[idx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + for (int i = nx - x; i < k; i++) { + output[idx] += kernel[i] * (input[b - i - x + y * nx] - input[idx - i]); + } + idx++; + } + } + return output; + } + + /** + * Convolution with an anti-symmetric kernel along y. + */ + public static double[][] convolveOddY(double[][] input, double[] kernel) { + + int nx = input.length; + int ny = input.length; + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * ny - 2; + + double[][] output = new double[nx][ny]; + + for (int x = 0; x < nx; x++) { + for (int y = 0; y < k_1; y++) { + output[x][y] = 0.0; + for (int i = 1; i <= y; i++) { + output[x][y] += kernel[i] * (input[x][y + i] - input[x][y - i]); + } + for (int i = y + 1; i < k; i++) { + output[x][y] += kernel[i] * (input[x][y + i] - input[x][i - y]); + } + } + for (int y = k_1; y <= ny - k; y++) { + output[x][y] = 0.0; + for (int i = 1; i < k; i++) { + output[x][y] += kernel[i] * (input[x][y + i] - input[x][y - i]); + } + } + for (int y = ny - k_1; y < ny; y++) { + output[x][y] = 0.0; + for (int i = 1; i < ny - y; i++) { + output[x][y] += kernel[i] * (input[x][y + i] - input[x][y - i]); + } + for (int i = ny - y; i < k; i++) { + output[x][y] += kernel[i] * (input[x][b - i - y] - input[x][y - i]); + } + } + } + return output; + } + + /** + * Convolution with an anti-symmetric kernel along y, for an image defined + * as a 1-D array. + */ + public static double[] convolveOddY(double[] input, double[] kernel, int nx, int ny) { + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * ny - 2; + + double[] output = new double[nx * ny]; + + int idx, inx; + for (int x = 0; x < nx; x++) { + for (int y = 0; y < k_1; y++) { + idx = x + y * nx; + output[idx] = 0.0; + for (int i = 1; i <= y; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + for (int i = y + 1; i < k; i++) { + output[idx] += kernel[i] * (input[idx + i * nx] - input[(i - y) * nx + x]); + } + } + for (int y = k_1; y <= ny - k; y++) { + idx = x + y * nx; + output[idx] = 0.0; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + } + for (int y = ny - k_1; y < ny; y++) { + idx = x + y * nx; + output[idx] = 0.0; + for (int i = 1; i < ny - y; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + for (int i = ny - y; i < k; i++) { + output[idx] += kernel[i] * (input[(b - i - y) * nx + x] - input[idx - i * nx]); + } + } + } + return output; + } + + /** + * Convolution with an anti-symmetric kernel along y, for an image defined + * as a 1-D array. + */ + public static float[] convolveOddY(float[] input, float[] kernel, int nx, int ny) { + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * ny - 2; + + float[] output = new float[nx * ny]; + + int idx, inx; + for (int x = 0; x < nx; x++) { + for (int y = 0; y < k_1; y++) { + idx = x + y * nx; + output[idx] = 0.0f; + for (int i = 1; i <= y; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + for (int i = y + 1; i < k; i++) { + output[idx] += kernel[i] * (input[idx + i * nx] - input[(i - y) * nx + x]); + } + } + for (int y = k_1; y <= ny - k; y++) { + idx = x + y * nx; + output[idx] = 0.0f; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + } + for (int y = ny - k_1; y < ny; y++) { + idx = x + y * nx; + output[idx] = 0.0f; + for (int i = 1; i < ny - y; i++) { + inx = i * nx; + output[idx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + for (int i = ny - y; i < k; i++) { + output[idx] += kernel[i] * (input[(b - i - y) * nx + x] - input[idx - i * nx]); + } + } + } + return output; + } + + /** + * Convolution with a symmetric kernel along x, for an image defined as a + * 1-D array, in a region bounded by [x1..x2] and [y1..y2]. Usage: + * convolve{Even,Odd}X followed by convolve{Even,Odd}Y is mandatory. + */ + public static double[] convolveEvenX(double[] input, double[] kernel, int[] dims, int x1, int x2, int y1, int y2) { + + int nx = dims[0]; + int ny = dims[1]; + int nxy = nx * ny; + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + double[] output = new double[(x2 - x1 + 1) * (y2 - y1 + 1)]; + int idx; + int odx = 0; + + if (x1 < k_1 && x2 > nx - k) { // 2 border conditions + for (int y = y1; y <= y2; y++) { + for (int x = x1; x < k_1; x++) { + idx = x + y * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i <= x; i++) { + output[odx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + for (int i = x + 1; i < k; i++) { + output[odx] += kernel[i] * (input[i - x + y * nx] + input[idx + i]); + } + odx++; + } + for (int x = k_1; x < x2 - k_1; x++) { + idx = x + y * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + odx++; + } + for (int x = x2 - k_1; x <= x2; x++) { + idx = x + y * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < nx - x; i++) { + output[odx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + for (int i = nx - x; i < k; i++) { + output[odx] += kernel[i] * (input[b - i - x + y * nx] + input[idx - i]); + } + odx++; + } + } + } + else if (x1 < k_1 && x2 <= nx - k) { // left border conditions + for (int y = y1; y <= y2; y++) { + for (int x = x1; x < k_1; x++) { + idx = x + y * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i <= x; i++) { + output[odx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + for (int i = x + 1; i < k; i++) { + output[odx] += kernel[i] * (input[i - x + y * nx] + input[idx + i]); + } + odx++; + } + for (int x = k_1; x <= x2; x++) { + idx = x + y * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + odx++; + } + } + } + else if (x1 >= k_1 && x2 > nx - k) { // right border conditions + for (int y = y1; y <= y2; y++) { + for (int x = x1; x < x2 - k_1; x++) { + idx = x + y * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + odx++; + } + for (int x = x2 - k_1; x <= x2; x++) { + idx = x + y * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < nx - x; i++) { + output[odx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + for (int i = nx - x; i < k; i++) { + output[odx] += kernel[i] * (input[b - i - x + y * nx] + input[idx - i]); + } + odx++; + } + } + } + else { // no border conditions + for (int y = y1; y <= y2; y++) { + for (int x = x1; x <= x2; x++) { + idx = x + y * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx - i] + input[idx + i]); + } + odx++; + } + } + } + return output; + } + + /** + * Convolution with an anti-symmetric kernel along x, for an image defined + * as a 1-D array, in a region bounded by [x1..x2] and [y1..y2]. Usage: + * convolve{Even,Odd}X followed by convolve{Even,Odd}Y is mandatory. + */ + public static double[] convolveOddX(double[] input, double[] kernel, int[] dims, int x1, int x2, int y1, int y2) { + + int nx = dims[0]; + int ny = dims[1]; + int nxy = nx * ny; + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * nx - 2; + + double[] output = new double[(x2 - x1 + 1) * (y2 - y1 + 1)]; + + int idx; + int odx = 0; + + if (x1 < k_1 && x2 > nx - k) { // 2 border conditions + for (int y = y1; y <= y2; y++) { + for (int x = x1; x < k_1; x++) { + idx = x + y * nx; + output[odx] = 0.0; + for (int i = 1; i <= x; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + for (int i = x + 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[i - x + y * nx]); + } + odx++; + } + for (int x = k_1; x < x2 - k_1; x++) { + idx = x + y * nx; + output[odx] = 0.0; + for (int i = 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + odx++; + } + for (int x = x2 - k_1; x <= x2; x++) { + idx = x + y * nx; + output[odx] = 0.0; + for (int i = 1; i < nx - x; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + for (int i = nx - x; i < k; i++) { + output[odx] += kernel[i] * (input[b - i - x + y * nx] - input[idx - i]); + } + odx++; + } + } + } + else if (x1 < k_1 && x2 <= nx - k) { // left border conditions + for (int y = y1; y <= y2; y++) { + for (int x = x1; x < k_1; x++) { + idx = x + y * nx; + output[odx] = 0.0; + for (int i = 1; i <= x; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + for (int i = x + 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[i - x + y * nx]); + } + odx++; + } + for (int x = k_1; x <= x2; x++) { + idx = x + y * nx; + output[odx] = 0.0; + for (int i = 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + odx++; + } + } + } + else if (x1 >= k_1 && x2 > nx - k) { // right border conditions + for (int y = y1; y <= y2; y++) { + for (int x = x1; x < x2 - k_1; x++) { + idx = x + y * nx; + output[odx] = 0.0; + for (int i = 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + odx++; + } + for (int x = x2 - k_1; x <= x2; x++) { + idx = x + y * nx; + output[odx] = 0.0; + for (int i = 1; i < nx - x; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + for (int i = nx - x; i < k; i++) { + output[odx] += kernel[i] * (input[b - i - x + y * nx] - input[idx - i]); + } + odx++; + } + } + } + else { // no border conditions + for (int y = y1; y <= y2; y++) { + for (int x = x1; x <= x2; x++) { + idx = x + y * nx; + output[odx] = 0.0; + for (int i = 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx + i] - input[idx - i]); + } + odx++; + } + } + } + return output; + } + + /** + * Convolution with a symmetric kernel along x, for an image defined as a + * 1-D array, in a region bounded by [x1..x2] and [y1..y2]. Usage: + * convolve{Even,Odd}X followed by convolve{Even,Odd}Y is mandatory. + */ + public static double[] convolveEvenY(double[] input, double[] kernel, int[] dims, int y1, int y2) { + + int nx = dims[0]; + int ny = dims[1]; + int nxy = nx * ny; + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * ny - 2; + double[] output = new double[nx * (y2 - y1 + 1)]; + + int idx, inx; + int odx = 0; + + if (y1 < k_1 && y2 > ny - k) { // 2 border conditions + for (int x = 0; x < nx; x++) { + for (int y = y1; y < k_1; y++) { + idx = x + y * nx; + odx = idx - y1 * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i <= y; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + for (int i = y + 1; i < k; i++) { + output[odx] += kernel[i] * (input[(i - y) * nx + x] + input[idx + i * nx]); + } + } + for (int y = k_1; y < y2 - k_1; y++) { + idx = x + y * nx; + odx = idx - y1 * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + } + for (int y = y2 - k_1; y <= y2; y++) { + idx = x + y * nx; + odx = idx - y1 * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < ny - y; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + for (int i = ny - y; i < k; i++) { + output[odx] += kernel[i] * (input[(b - i - y) * nx + x] + input[idx - i * nx]); + } + } + } + } + else if (y1 < k_1 && y2 <= ny - k) { // top border conditions + for (int x = 0; x < nx; x++) { + for (int y = y1; y < k_1; y++) { + idx = x + y * nx; + odx = idx - y1 * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i <= y; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + for (int i = y + 1; i < k; i++) { + output[odx] += kernel[i] * (input[(i - y) * nx + x] + input[idx + i * nx]); + } + } + for (int y = k_1; y <= y2; y++) { + idx = x + y * nx; + odx = idx - y1 * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + } + } + } + else if (y1 >= k_1 && y2 > ny - k) { // bottom border conditions + for (int x = 0; x < nx; x++) { + for (int y = y1; y < ny - k_1; y++) { + idx = x + y * nx; + odx = idx - y1 * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + } + for (int y = ny - k_1; y <= y2; y++) { + idx = x + y * nx; + odx = idx - y1 * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < ny - y; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + for (int i = ny - y; i < k; i++) { + output[odx] += kernel[i] * (input[(b - i - y) * nx + x] + input[idx - i * nx]); + } + } + } + } + else { // no border conditions + for (int x = 0; x < nx; x++) { + for (int y = y1; y <= y2; y++) { + idx = x + y * nx; + odx = idx - y1 * nx; + output[odx] = kernel[0] * input[idx]; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx - inx] + input[idx + inx]); + } + } + } + } + return output; + } + + /** + * Convolution with an anti-symmetric kernel along y, for an image defined + * as a 1-D array, in a region bounded by [x1..x2] and [y1..y2]. Usage: + * convolve{Even,Odd}X followed by convolve{Even,Odd}Y is mandatory. + */ + public static double[] convolveOddY(double[] input, double[] kernel, int[] dims, int y1, int y2) { + + int nx = dims[0]; + int ny = dims[1]; + int nxy = nx * ny; + + int k = kernel.length; + int k_1 = k - 1; + int b = 2 * ny - 2; + + double[] output = new double[nx * (y2 - y1 + 1)]; + + int idx, inx; + int odx = 0; + + if (y1 < k_1 && y2 > ny - k) { // 2 border conditions + for (int x = 0; x < nx; x++) { + for (int y = y1; y < k_1; y++) { + idx = x + y * nx; + odx = x + (y - y1) * nx; + output[odx] = 0.0; + for (int i = 1; i <= y; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + for (int i = y + 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx + i * nx] - input[(i - y) * nx + x]); + } + } + for (int y = k_1; y <= ny - k; y++) { + idx = x + y * nx; + odx = x + (y - y1) * nx; + output[odx] = 0.0; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + } + for (int y = ny - k_1; y <= y2; y++) { + idx = x + y * nx; + odx = x + (y - y1) * nx; + output[odx] = 0.0; + for (int i = 1; i < ny - y; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + for (int i = ny - y; i < k; i++) { + output[odx] += kernel[i] * (input[(b - i - y) * nx + x] - input[idx - i * nx]); + } + } + } + } + else if (y1 < k_1 && y2 <= ny - k) { // left border conditions + for (int x = 0; x < nx; x++) { + for (int y = y1; y < k_1; y++) { + idx = x + y * nx; + odx = x + (y - y1) * nx; + output[odx] = 0.0; + for (int i = 1; i <= y; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + for (int i = y + 1; i < k; i++) { + output[odx] += kernel[i] * (input[idx + i * nx] - input[(i - y) * nx + x]); + } + } + for (int y = k_1; y <= y2; y++) { + idx = x + y * nx; + odx = x + (y - y1) * nx; + output[odx] = 0.0; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + } + } + } + else if (y1 >= k_1 && y2 > ny - k) { // right border conditions + for (int x = 0; x < nx; x++) { + for (int y = y1; y <= ny - k; y++) { + idx = x + y * nx; + odx = x + (y - y1) * nx; + output[odx] = 0.0; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + } + for (int y = ny - k_1; y < y2; y++) { + idx = x + y * nx; + odx = x + (y - y1) * nx; + output[odx] = 0.0; + for (int i = 1; i < ny - y; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + for (int i = ny - y; i < k; i++) { + output[odx] += kernel[i] * (input[(b - i - y) * nx + x] - input[idx - i * nx]); + } + } + } + } + else { // no border conditions + for (int x = 0; x < nx; x++) { + for (int y = y1; y <= y2; y++) { + idx = x + y * nx; + odx = x + (y - y1) * nx; + output[odx] = 0.0; + for (int i = 1; i < k; i++) { + inx = i * nx; + output[odx] += kernel[i] * (input[idx + inx] - input[idx - inx]); + } + } + } + } + return output; + } +} \ No newline at end of file diff --git a/src/bilib/src/ijtools/IJmath.java b/src/bilib/src/ijtools/IJmath.java new file mode 100644 index 0000000000000000000000000000000000000000..89eebb98338e89f650e45085398c5c249b6eaa21 --- /dev/null +++ b/src/bilib/src/ijtools/IJmath.java @@ -0,0 +1,549 @@ +package ijtools; + +/** + * Various methods for polynomial manipulation and basic image arithmetic. + * Polynomial are defined by the set of coefficients a[]: f(x) = a[0] + a[1]*x + + * a[2]*x^2 + ... + * + * @author Francois Aguet + * @version 1.0 + */ +public class IJmath { + + /** + * Returns the real roots of a quadratic polynomial. The input is of the + * form: x^2 + a1*x + a0. The size of the returned array corresponds to the + * number of real roots. + */ + public static double[] quadraticRoots(double a1, double a0) { + + double[] roots; + double delta = a1 * a1 - 4.0 * a0; + if (delta < 0.0) { + roots = new double[0]; + } + else { + roots = new double[2]; + delta = Math.sqrt(delta); + roots[0] = (-a1 + delta) / 2.0; + roots[1] = (-a1 - delta) / 2.0; + } + return roots; + } + + /** + * Returns the real roots of a cubic polynomial. The input is of the form: + * x^3 + a2*x^2 + a1*x + a0. References: Numerical Recipes in C, pp. + * 184-185, http://mathworld.wolfram.com/CubicFormula.html The size of the + * returned array corresponds to the number of real roots. + */ + public static double[] cubicRoots(double a2, double a1, double a0) { + + double theta, A, B; + double q = a2 * a2 - 3.0 * a1; + double Q = q / 9.0; + double R = (2.0 * a2 * a2 * a2 - 9.0 * a2 * a1 + 27.0 * a0) / 54.0; + double roots[]; + double signR, delta; + + if (a0 == 0.0) { + delta = a2 * a2 - 4.0 * a1; + if (delta >= 0.0) { + roots = new double[3]; + roots[0] = 0.0; + roots[1] = (-a2 + Math.sqrt(delta)) / 2.0; + roots[2] = (-a2 - Math.sqrt(delta)) / 2.0; + } + else { + roots = new double[1]; + roots[0] = 0.0; + } + } + else { + if (R >= 0.0) { + signR = 1.0; + } + else { + signR = -1.0; + } + if (R * R <= Q * Q * Q) { // REF: R2 < Q3 + roots = new double[3]; + theta = Math.acos(R / Math.sqrt(Q * Q * Q)); + roots[0] = -2.0 * Math.sqrt(Q) * Math.cos(theta / 3.0) - (a2 / 3.0); + roots[1] = -2.0 * Math.sqrt(Q) * Math.cos((theta + 2.0 * Math.PI) / 3.0) - (a2 / 3.0); + roots[2] = -2.0 * Math.sqrt(Q) * Math.cos((theta - 2.0 * Math.PI) / 3.0) - (a2 / 3.0); + } + else { + A = -signR * Math.pow(Math.abs(R) + Math.sqrt(R * R - Q * Q * Q), 1.0 / 3.0); + if (A == 0.0) { + B = 0.0; + } + else { + B = Q / A; + } + roots = new double[1]; + roots[0] = A + B - (a2 / 3.0); + } + } + return roots; + } + + /** + * Returns the real roots of a quartic polynomial. The input is of the form: + * x^4 + a3*x^3 + a2*x^2 + a1*x + a0. Reference: + * http://mathworld.wolfram.com/QuarticEquation.html The size of the + * returned array corresponds to the number of real roots. + */ + public static double[] quarticRoots(double a3, double a2, double a1, double a0) { + + double[] roots; + + if (a3 == 0.0 && a1 == 0.0) { // quadratic equation in x^2 + double[] x2roots = quadraticRoots(a2, a0); + if (x2roots.length != 0) { + if ((x2roots[0] >= 0.0) && (x2roots[1] >= 0.0)) { + roots = new double[4]; + roots[0] = Math.sqrt(x2roots[0]); + roots[1] = -roots[0]; + roots[2] = Math.sqrt(x2roots[1]); + roots[3] = roots[2]; + } + else if ((x2roots[0] < 0.0) && (x2roots[1] < 0.0)) { + roots = new double[0]; + } + else { + roots = new double[2]; + if (x2roots[0] >= 0.0) { + roots[0] = Math.sqrt(x2roots[0]); + roots[1] = -roots[0]; + } + else { + roots[0] = Math.sqrt(x2roots[1]); + roots[1] = -roots[0]; + } + } + } + else { + roots = new double[0]; + } + } + else { // solve quartic + + double[] crr = cubicRoots(-a2, a1 * a3 - 4.0 * a0, 4.0 * a2 * a0 - a1 * a1 - a3 * a3 * a0); + double y1 = crr[0]; + + double deltaR = 0.25 * a3 * a3 - a2 + y1; + double R; + + if (deltaR < 0.0) { // 4 complex roots + roots = new double[0]; + } + else { + R = Math.sqrt(deltaR); + double D, E; + double deltaD, deltaE; + if (R == 0.0) { + deltaD = 0.75 * a3 * a3 - 2.0 * a2 + 2.0 * Math.sqrt(y1 * y1 - 4.0 * a0); + deltaE = 0.75 * a3 * a3 - 2.0 * a2 - 2.0 * Math.sqrt(y1 * y1 - 4.0 * a0); + if (deltaD >= 0.0) { + D = Math.sqrt(deltaD); + if (deltaE >= 0.0) { + E = Math.sqrt(deltaE); + roots = new double[4]; + roots[0] = -0.25 * a3 + 0.5 * D; + roots[1] = -0.25 * a3 - 0.5 * D; + roots[2] = -0.25 * a3 + 0.5 * E; + roots[3] = -0.25 * a3 - 0.5 * E; + } + else { + roots = new double[2]; + roots[0] = -0.25 * a3 + 0.5 * D; + roots[1] = -0.25 * a3 - 0.5 * D; + } + } + else { + if (deltaE >= 0.0) { + E = Math.sqrt(deltaE); + roots = new double[2]; + roots[0] = -0.25 * a3 + 0.5 * E; + roots[1] = -0.25 * a3 - 0.5 * E; + } + else { + roots = new double[0]; + } + } + } + else { + deltaD = 0.75 * a3 * a3 - R * R - 2.0 * a2 + (a3 * a2 - 2.0 * a1 - 0.25 * a3 * a3 * a3) / R; + deltaE = 0.75 * a3 * a3 - R * R - 2.0 * a2 - (a3 * a2 - 2.0 * a1 - 0.25 * a3 * a3 * a3) / R; + if (deltaD >= 0.0) { + D = Math.sqrt(deltaD); + if (deltaE >= 0.0) { + E = Math.sqrt(deltaE); + roots = new double[4]; + roots[0] = -0.25 * a3 + 0.5 * R + 0.5 * D; + roots[1] = -0.25 * a3 + 0.5 * R - 0.5 * D; + roots[2] = -0.25 * a3 - 0.5 * R + 0.5 * E; + roots[3] = -0.25 * a3 - 0.5 * R - 0.5 * E; + } + else { + roots = new double[2]; + roots[0] = -0.25 * a3 + 0.5 * R + 0.5 * D; + roots[1] = -0.25 * a3 + 0.5 * R - 0.5 * D; + } + } + else { + if (deltaE >= 0.0) { + E = Math.sqrt(deltaE); + roots = new double[2]; + roots[0] = -0.25 * a3 - 0.5 * R + 0.5 * E; + roots[1] = -0.25 * a3 - 0.5 * R - 0.5 * E; + } + else { + roots = new double[0]; + } + } + } + } + } + return roots; + } + + /** + * Divides a polynomial by a known root. + */ + public static double[] divPolyByRoot(double[] coeffs, double root) { + int nx = coeffs.length; + double[] out = new double[nx - 1]; + double rem = coeffs[nx - 1]; + for (int i = nx - 2; i >= 0; i--) { + out[i] = rem; + rem = coeffs[i] + rem * root; + } + return out; + } + + // divide by (x - (a + bi))(x - (a - bi)) = x^2 - a^2 x + a^2 + b^2 + /** + * Divides a polynomial by a pair of known conjugate roots, i.e., (x - (a + + * bi))(x - (a - bi)). + */ + public static double[] divPolyByConjRoots(double[] coeffs, double a, double b) { + double t1 = 2.0 * a; + double t2 = a * a + b * b; + int n = coeffs.length - 2; + double[] out = new double[n]; + out[n - 1] = coeffs[n + 1]; + out[n - 2] = coeffs[n] + t1 * out[n - 1]; + for (int i = n - 1; i >= 2; i--) { + out[i - 2] = coeffs[i] + t1 * out[i - 1] - t2 * out[i]; + } + return out; + } + + /** + * Evaluates a polynomial in x0. f(x) = a[0] + a[1]*x + a[2]*x^2 + ... + */ + public static double evalPoly(double[] a, double x0) { + int n = a.length; + double f = a[n - 1]; + for (int i = n - 2; i >= 0; i--) { + f = f * x0 + a[i]; + } + return f; + } + + /** + * Evaluates a polynomial and its first derivative in x0. f(x) = a[0] + + * a[1]*x + a[2]*x^2 + ... + * + * @return A length two array containing f(x0) and f'(x0), respectively. + */ + public static double[] evalPolyD(double[] a, double x0) { + int n = a.length; + double[] f = new double[2]; + f[0] = a[n - 1]; + f[1] = 0.0; + for (int i = n - 2; i >= 0; i--) { + f[1] = f[1] * x0 + f[0]; + f[0] = f[0] * x0 + a[i]; + } + return f; + } + + // Laguerre's method, adapted from 'Numerical Recipes' for real + // coefficients, complex roots + + /** + * Laguerre's root finding method for real-valued polynomials. f(x) = a[0] + + * a[1]*x + a[2]*x^2 + ... The returned root can be complex. + * + * @return An array containing the real and imaginary part of the root a + + * i*b, i.e., {a,b}. + */ + public static double[] laguerre(double[] a, double x0) { + // public static double[] laguerre(double[] a, double x0, int[] + // converged) { + + int N = a.length - 1; // degree of the polynomial + double[] x = complex(x0, 0.0); // a (complex) root + double[] f, df, d2f; + double[] G, G2, H, sq, Gplus, Gminus, dx; + double[] delta; + double absx, error, abs_plus, abs_minus; + final double[] fracl = { 0.0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 1.0 }; // fractions + // used + // to + // break + // limit + // cycles + int MT = 10; + // int maxiter = MT*fracl.length; + int maxiter = 30; + double tol = 1.0e-15; + int[] converged = new int[1]; + converged[0] = -2; + + for (int iter = 1; iter <= maxiter; iter++) { + + f = complex(a[N], 0.0); + df = complex(0.0, 0.0); + d2f = complex(0.0, 0.0); + absx = cabs(x); + error = cabs(f); + for (int k = N - 1; k >= 0; k--) { + d2f = cadd(cmul(d2f, x), df); + df = cadd(cmul(df, x), f); + f = cadd(cmul(f, x), complex(a[k], 0.0)); + error = cabs(f) + absx * error; + } + if (cabs(f) <= error * tol) { // x is a root + converged[0] = 2; + break; + } + G = cdiv(df, f); + G2 = cmul(G, G); + H = csub(G2, cdiv(d2f, f)); + delta = rcmul(N - 1, csub(rcmul(N, H), G2)); + sq = csqrt(delta); + Gplus = cadd(G, sq); + Gminus = csub(G, sq); + abs_plus = cabs(Gplus); + abs_minus = cabs(Gminus); + if (abs_minus > abs_plus) { + Gplus = Gminus; + abs_plus = abs_minus; + } // Gplus is largest absolute denominator + if (abs_plus > 0.0) { + dx = cdiv(complex(N, 0.0), Gplus); + } + else { // G = 0, H = 0, freak case + dx = rcmul(1 + absx, complex(Math.cos(iter), Math.sin(iter))); + dx = complex(1.0, 0.0); + } + /* + * if (cabs(dx) < tol) { // converged //IJ.write("test"); break; } + */ + if (iter % MT != 0) { + x = csub(x, dx); + } + else { // fractional step to break limit cycles + x = csub(x, rcmul(fracl[iter / MT], dx)); + } + } + return x; + } + + private static double[] complex(double a, double b) { + double[] c = { a, b }; + return c; + } + + private static double[] cadd(double[] c1, double[] c2) { + double[] c = { c1[0] + c2[0], c1[1] + c2[1] }; + return c; + } + + private static double[] csub(double[] c1, double[] c2) { + double[] c = { c1[0] - c2[0], c1[1] - c2[1] }; + return c; + } + + private static double cabs(double[] c) { + return Math.sqrt(c[0] * c[0] + c[1] * c[1]); + } + + private static double[] rcmul(double a, double[] c) { + double[] s = { a * c[0], a * c[1] }; + return s; + } + + private static double[] cmul(double[] c1, double[] c2) { + double[] c = { c1[0] * c2[0] - c1[1] * c2[1], c1[0] * c2[1] + c2[0] * c1[1] }; + return c; + } + + private static double[] cdiv(double[] c1, double[] c2) { + double d = c2[0] * c2[0] + c2[1] * c2[1]; + double[] c = { (c1[0] * c2[0] + c1[1] * c2[1]) / d, (c2[0] * c1[1] - c1[0] * c2[1]) / d }; + return c; + } + + private static double[] csqrt(double[] c) { + double t = cabs(c); + double d = Math.sqrt(2); + double[] s = { Math.sqrt(t + c[0]) / d, csign(c[1]) * Math.sqrt(t - c[0]) / d }; + return s; + } + + private static double csign(double x) { + if (x >= 0.0) { + return 1.0; + } + else { + return -1.0; + } + } + + /** + * Computes the mean. + */ + public static double mean(double[] input) { + return sum(input) / input.length; + } + + /** + * Computes the mean. + */ + public static double mean(double[][] input) { + return sum(input) / (input.length * input[0].length); + } + + /** + * Computes the sum. + */ + public static double sum(double[] input) { + int nxy = input.length; + double s = 0.0; + for (int k = 0; k < nxy; k++) { + s += input[k]; + } + return s; + } + + /** + * Computes the sum. + */ + public static double sum(double[][] input) { + int nx = input.length; + int ny = input[0].length; + double s = 0.0; + for (int x = 0; x < nx; x++) { + for (int y = 0; y < ny; y++) { + s += input[x][y]; + } + } + return s; + } + + /** + * Adds the two input images. + */ + public static double[] add(double[] a, double[] b) { + int nxy = a.length; + double[] out = new double[nxy]; + for (int k = 0; k < nxy; k++) { + out[k] = a[k] + b[k]; + } + return out; + } + + /** + * Adds the two input images. + */ + public static double[][] add(double[][] a, double[][] b) { + int nx = a.length; + int ny = a[0].length; + double[][] out = new double[nx][ny]; + for (int x = 0; x < nx; x++) { + for (int y = 0; y < ny; y++) { + out[x][y] = a[x][y] + b[x][y]; + } + } + return out; + } + + /** + * Subtracts the two input images. + */ + public static double[] subtract(double[] a, double[] b) { + int nxy = a.length; + double[] out = new double[nxy]; + for (int k = 0; k < nxy; k++) { + out[k] = a[k] - b[k]; + } + return out; + } + + /** + * Subtracts the two input images. + */ + public static double[][] subtract(double[][] a, double[][] b) { + int nx = a.length; + int ny = a[0].length; + double[][] out = new double[nx][ny]; + for (int x = 0; x < nx; x++) { + for (int y = 0; y < ny; y++) { + out[x][y] = a[x][y] - b[x][y]; + } + } + return out; + } + + /** + * Multiplies the two input images. + */ + public static double[] mutiply(double[] a, double[] b) { + int nxy = a.length; + double[] out = new double[nxy]; + for (int k = 0; k < nxy; k++) { + out[k] = a[k] * b[k]; + } + return out; + } + + /** + * Multiplies the two input images. + */ + public static double[][] multiply(double[][] a, double[][] b) { + int nx = a.length; + int ny = a[0].length; + double[][] out = new double[nx][ny]; + for (int x = 0; x < nx; x++) { + for (int y = 0; y < ny; y++) { + out[x][y] = a[x][y] * b[x][y]; + } + } + return out; + } + + /* + * public static double newton(double[] coeffs, double x1, double x2) { + * + * if (Math.signum(SteerableUtilities.evalPoly(coeffs, + * x1)*SteerableUtilities.evalPoly(coeffs, x2)) != -1.0) { + * //IJ.write("error newton"+(x1*x2)); } + * + * double root = (x1+x2)/2.0; int maxIter = 40; double dx; double[] f; + * double acc = 1e-30; + * + * for (int i=0;i<maxIter;i++) { f = evalPolyD(coeffs, root); dx = + * f[0]/f[1]; root -= dx; + * + * //if ((x1-root)*(root-x2) < 0.0) { //IJ.write("Newton out of bounds"); // + * root = 111.13; //} + * + * if (Math.abs(dx) < acc) { break; } } return root; } + */ + +} diff --git a/src/bilib/src/ijtools/IJtools.java b/src/bilib/src/ijtools/IJtools.java new file mode 100644 index 0000000000000000000000000000000000000000..610c8c01cd66beab2039a8771f000682f7907cd6 --- /dev/null +++ b/src/bilib/src/ijtools/IJtools.java @@ -0,0 +1,847 @@ +package ijtools; + +import ij.*; +import ij.process.*; + +/** + * Utility class for displaying, loading and performing basic arithmetic + * operations on images. Where applicable, arrays are in lexicographical order. + * + * @author Francois Aguet + * @version 1.0 + */ +public class IJtools { + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, double[] pixels, int nx, int ny) { + (new ImagePlus(name, new FloatProcessor(nx, ny, pixels))).show(); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, float[] pixels, int nx, int ny) { + (new ImagePlus(name, new FloatProcessor(nx, ny, pixels, null))).show(); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, int[] pixels, int nx, int ny) { + (new ImagePlus(name, new FloatProcessor(nx, ny, pixels))).show(); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, short[] pixels, int nx, int ny) { + (new ImagePlus(name, new ShortProcessor(nx, ny, pixels, null))).show(); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, byte[] pixels, int nx, int ny) { + (new ImagePlus(name, new ByteProcessor(nx, ny, pixels, null))).show(); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void showRGB(String name, int[] pixels, int nx, int ny) { + (new ImagePlus(name, new ColorProcessor(nx, ny, pixels))).show(); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, double[][] input) { + int nx = input.length; + int ny = input[0].length; + double[] pixels = new double[nx * ny]; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < nx; x++) { + pixels[x + y * nx] = input[x][y]; + } + } + show(name, pixels, nx, ny); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, float[][] input) { + int nx = input.length; + int ny = input[0].length; + float[] pixels = new float[nx * ny]; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < nx; x++) { + pixels[x + y * nx] = input[x][y]; + } + } + show(name, pixels, nx, ny); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, int[][] input) { + int nx = input.length; + int ny = input[0].length; + int[] pixels = new int[nx * ny]; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < nx; x++) { + pixels[x + y * nx] = input[x][y]; + } + } + show(name, pixels, nx, ny); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, short[][] input) { + int nx = input.length; + int ny = input[0].length; + short[] pixels = new short[nx * ny]; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < nx; x++) { + pixels[x + y * nx] = input[x][y]; + } + } + show(name, pixels, nx, ny); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void show(String name, byte[][] input) { + int nx = input.length; + int ny = input[0].length; + byte[] pixels = new byte[nx * ny]; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < nx; x++) { + pixels[x + y * nx] = input[x][y]; + } + } + show(name, pixels, nx, ny); + } + + /** + * Displays the image in a new window in in ImageJ. + */ + public static void showRGB(String name, int[][] input) { + int nx = input.length; + int ny = input[0].length; + int[] pixels = new int[nx * ny]; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < nx; x++) { + pixels[x + y * nx] = input[x][y]; + } + } + showRGB(name, pixels, nx, ny); + } + + /** + * Displays the stack in a new window in in ImageJ. + */ + public static void showStack(String name, double[] input, int nx, int ny, int nz) { + ImageStack istack = new ImageStack(nx, ny); + for (int z = 0; z < nz; z++) { + double[] pixels = new double[nx * ny]; + for (int i = 0; i < nx * ny; i++) { + pixels[i] = input[i + z * nx * ny]; + } + istack.addSlice("", new FloatProcessor(nx, ny, pixels)); + } + (new ImagePlus(name, istack)).show(); + } + + /** + * Displays the stack in a new window in in ImageJ. + */ + public static void showStack(String name, float[] input, int nx, int ny, int nz) { + ImageStack istack = new ImageStack(nx, ny); + for (int z = 0; z < nz; z++) { + float[] pixels = new float[nx * ny]; + for (int i = 0; i < nx * ny; i++) { + pixels[i] = input[i + z * nx * ny]; + } + istack.addSlice("", pixels); + } + (new ImagePlus(name, istack)).show(); + } + + /** + * Displays the stack in a new window in in ImageJ. + */ + public static void showStack(String name, int[] input, int nx, int ny, int nz) { + ImageStack istack = new ImageStack(nx, ny); + int[] pixels = new int[nx * ny]; + for (int z = 0; z < nz; z++) { + for (int i = 0; i < nx * ny; i++) { + pixels[i] = input[i + z * nx * ny]; + } + istack.addSlice("", new FloatProcessor(nx, ny, pixels)); + } + (new ImagePlus(name, istack)).show(); + } + + /** + * Displays the stack in a new window in in ImageJ. + */ + public static void showStack(String name, short[] input, int nx, int ny, int nz) { + ImageStack istack = new ImageStack(nx, ny); + for (int z = 0; z < nz; z++) { + short[] pixels = new short[nx * ny]; + for (int i = 0; i < nx * ny; i++) { + pixels[i] = input[i + z * nx * ny]; + } + istack.addSlice("", pixels); + } + (new ImagePlus(name, istack)).show(); + } + + /** + * Displays the stack in a new window in in ImageJ. + */ + public static void showStack(String name, byte[] input, int nx, int ny, int nz) { + ImageStack istack = new ImageStack(nx, ny); + for (int z = 0; z < nz; z++) { + byte[] pixels = new byte[nx * ny]; + for (int i = 0; i < nx * ny; i++) { + pixels[i] = input[i + z * nx * ny]; + } + istack.addSlice("", pixels); + } + (new ImagePlus(name, istack)).show(); + } + + /** + * Displays the stack in a new window in in ImageJ. + */ + public static void showStackRGB(String name, int[] input, int nx, int ny, int nz) { + ImageStack istack = new ImageStack(nx, ny); + int[] pixels = new int[nx * ny]; + for (int z = 0; z < nz; z++) { + for (int i = 0; i < nx * ny; i++) { + pixels[i] = input[i + z * nx * ny]; + } + istack.addSlice("", new ColorProcessor(nx, ny, pixels)); + } + (new ImagePlus(name, istack)).show(); + } + + /** + * Displays the stack in a new window in in ImageJ. Input structure is + * [z][xy]. + */ + public static void showStack(String name, double[][] input, int nx, int ny) { + int nz = input.length; + ImageStack istack = new ImageStack(nx, ny); + double max = -Double.MAX_VALUE; + double min = Double.MAX_VALUE; + double t; + for (int z = 0; z < nz; z++) { + double[] pixels = new double[nx * ny]; + for (int i = 0; i < nx * ny; i++) { + t = input[z][i]; + if (t > max) { + max = t; + } + if (t < min) { + min = t; + } + } + istack.addSlice("", pixels); + } + ImagePlus imp = new ImagePlus(name, istack); + imp.getProcessor().setMinAndMax(min, max); + imp.show(); + } + + /** + * Displays the stack in a new window in in ImageJ. Input structure is + * [z][xy]. + */ + public static void showStack(String name, float[][] input, int nx, int ny) { + int nz = input.length; + ImageStack istack = new ImageStack(nx, ny); + float max = -Float.MAX_VALUE; + float min = Float.MAX_VALUE; + float t; + for (int z = 0; z < nz; z++) { + for (int i = 0; i < nx * ny; i++) { + t = input[z][i]; + if (t > max) { + max = t; + } + if (t < min) { + min = t; + } + } + istack.addSlice("", input[z]); + } + ImagePlus imp = new ImagePlus(name, istack); + imp.getProcessor().setMinAndMax(min, max); + imp.show(); + } + + /** + * Displays the stack in a new window in in ImageJ. Input structure is + * [z][xy]. + */ + public static void showStack(String name, int[][] input, int nx, int ny) { + int nz = input.length; + ImageStack istack = new ImageStack(nx, ny); + int max = -Integer.MAX_VALUE; + int min = Integer.MAX_VALUE; + int t; + int[] pixels = new int[nx * ny]; + for (int z = 0; z < nz; z++) { + for (int i = 0; i < nx * ny; i++) { + t = input[z][i]; + if (t > max) { + max = t; + } + if (t < min) { + min = t; + } + } + istack.addSlice("", new FloatProcessor(nx, ny, pixels)); + } + ImagePlus imp = new ImagePlus(name, istack); + imp.getProcessor().setMinAndMax(min, max); + imp.show(); + } + + /** + * Displays the stack in a new window in in ImageJ. Input structure is + * [z][xy]. + */ + public static void showStack(String name, short[][] input, int nx, int ny) { + int nz = input.length; + ImageStack istack = new ImageStack(nx, ny); + short max = -Short.MAX_VALUE; + short min = Short.MAX_VALUE; + short t; + for (int z = 0; z < nz; z++) { + short[] pixels = new short[nx * ny]; + for (int i = 0; i < nx * ny; i++) { + t = input[z][i]; + if (t > max) { + max = t; + } + if (t < min) { + min = t; + } + } + istack.addSlice("", pixels); + } + ImagePlus imp = new ImagePlus(name, istack); + imp.getProcessor().setMinAndMax(min, max); + imp.show(); + } + + /** + * Displays the stack in a new window in in ImageJ. Input structure is + * [z][xy]. + */ + public static void showStack(String name, byte[][] input, int nx, int ny) { + int nz = input.length; + ImageStack istack = new ImageStack(nx, ny); + byte max = -Byte.MAX_VALUE; + byte min = Byte.MAX_VALUE; + byte t; + for (int z = 0; z < nz; z++) { + byte[] pixels = new byte[nx * ny]; + for (int i = 0; i < nx * ny; i++) { + t = input[z][i]; + if (t > max) { + max = t; + } + if (t < min) { + min = t; + } + } + istack.addSlice("", pixels); + } + ImagePlus imp = new ImagePlus(name, istack); + imp.getProcessor().setMinAndMax(min, max); + imp.show(); + } + + /** + * Displays the stack in a new window in in ImageJ. Input structure is + * [z][xy]. + */ + public static void showStackRGB(String name, int[][] input, int nx, int ny) { + int nz = input.length; + ImageStack istack = new ImageStack(nx, ny); + for (int z = 0; z < nz; z++) { + istack.addSlice("", new ColorProcessor(nx, ny, input[z])); + } + (new ImagePlus(name, istack)).show(); + } + + /** + * Loads the contents of an ImageProcessor into a double[] array. + */ + public static void loadImage(ImageProcessor ip, double[] pixels) { + if (ip == null) { + throw new ArrayStoreException("ImageProcessor == null."); + } + int nk = ip.getWidth() * ip.getHeight(); + if (nk != pixels.length) { + throw new IndexOutOfBoundsException("Array sizes do not match."); + } + if (ip.getPixels() instanceof byte[]) { + byte[] bsrc = (byte[]) ip.getPixels(); + for (int k = 0; k < nk; k++) { + pixels[k] = (double) (bsrc[k] & 0xFF); + } + } + else if (ip.getPixels() instanceof short[]) { + short[] ssrc = (short[]) ip.getPixels(); + for (int k = 0; k < nk; k++) { + pixels[k] = (double) (ssrc[k] & 0xFFFF); + } + } + else if (ip.getPixels() instanceof float[]) { + float[] fsrc = (float[]) ip.getPixels(); + for (int k = 0; k < nk; k++) { + pixels[k] = (double) fsrc[k]; + } + } + else { + throw new ArrayStoreException("Unexpected image type."); + } + } + + /** + * Loads the contents of an ImageProcessor into a float[] array. + */ + public static void loadImage(ImageProcessor ip, float[] pixels) { + if (ip == null) { + throw new ArrayStoreException("ImageProcessor == null."); + } + int nk = ip.getWidth() * ip.getHeight(); + if (nk != pixels.length) { + throw new IndexOutOfBoundsException("Array sizes do not match"); + } + if (ip.getPixels() instanceof byte[]) { + byte[] bsrc = (byte[]) ip.getPixels(); + for (int k = 0; k < nk; k++) { + pixels[k] = (float) (bsrc[k] & 0xFF); + } + } + else if (ip.getPixels() instanceof short[]) { + short[] ssrc = (short[]) ip.getPixels(); + for (int k = 0; k < nk; k++) { + pixels[k] = (float) (ssrc[k] & 0xFFFF); + } + } + else if (ip.getPixels() instanceof float[]) { + float[] fsrc = (float[]) ip.getPixels(); + for (int k = 0; k < nk; k++) { + pixels[k] = fsrc[k]; + } + } + else { + throw new ArrayStoreException("Unexpected image type."); + } + } + + /** + * Loads the contents of an ImageProcessor into a double[][] array. + */ + public static void loadImage(ImageProcessor ip, double[][] pixels) { + if (ip == null) { + throw new ArrayStoreException("ImageProcessor == null."); + } + int nx = ip.getWidth(); + int ny = ip.getHeight(); + if (nx != pixels.length || ny != pixels[0].length) { + throw new IndexOutOfBoundsException("Array sizes do not match."); + } + if (ip.getPixels() instanceof byte[]) { + byte[] bsrc = (byte[]) ip.getPixels(); + for (int y = 0; y < ny; y++) + for (int x = 0; x < nx; x++) + pixels[x][y] = (double) (bsrc[x + y * nx] & 0xFF); + } + else if (ip.getPixels() instanceof short[]) { + short[] ssrc = (short[]) ip.getPixels(); + for (int y = 0; y < ny; y++) + for (int x = 0; x < nx; x++) + pixels[x][y] = (double) (ssrc[x + y * nx] & 0xFFFF); + } + else if (ip.getPixels() instanceof float[]) { + float[] fsrc = (float[]) ip.getPixels(); + for (int y = 0; y < ny; y++) + for (int x = 0; x < nx; x++) + pixels[x][y] = (double) fsrc[x + y * nx]; + } + else { + throw new ArrayStoreException("Unexpected image type."); + } + } + + /** + * Loads the contents of an ImageProcessor into a float[][] array. + */ + public static void loadImage(ImageProcessor ip, float[][] pixels) { + if (ip == null) { + throw new ArrayStoreException("ImageProcessor == null."); + } + int nx = ip.getWidth(); + int ny = ip.getHeight(); + if (nx != pixels.length || ny != pixels[0].length) { + throw new IndexOutOfBoundsException("Array sizes do not match."); + } + if (ip.getPixels() instanceof byte[]) { + byte[] bsrc = (byte[]) ip.getPixels(); + for (int y = 0; y < ny; y++) + for (int x = 0; x < nx; x++) + pixels[x][y] = (float) (bsrc[x + y * nx] & 0xFF); + } + else if (ip.getPixels() instanceof short[]) { + short[] ssrc = (short[]) ip.getPixels(); + for (int y = 0; y < ny; y++) + for (int x = 0; x < nx; x++) + pixels[x][y] = (float) (ssrc[x + y * nx] & 0xFFFF); + } + else if (ip.getPixels() instanceof float[]) { + float[] fsrc = (float[]) ip.getPixels(); + for (int y = 0; y < ny; y++) + for (int x = 0; x < nx; x++) + pixels[x][y] = fsrc[x + y * nx]; + } + else { + throw new ArrayStoreException("Unexpected image type."); + } + } + + /** + * Loads the three RGB channels of an ImageProcessor into individual float[] + * arrays. + */ + public static void loadImageRGB(ImageProcessor ip, float[] rChannel, float[] gChannel, float[] bChannel) { + if (ip == null) { + throw new ArrayStoreException("ImageProcessor == null."); + } + int nk = ip.getWidth() * ip.getHeight(); + if (nk != rChannel.length || nk != gChannel.length || nk != bChannel.length) { + throw new IndexOutOfBoundsException("Array sizes do not match"); + } + if (ip.getPixels() instanceof int[]) { + int[] isrc = (int[]) ip.getPixels(); + for (int k = 0; k < nk; k++) { + rChannel[k] = (float) ((isrc[k] >> 16) & 0x0000FF); + gChannel[k] = (float) ((isrc[k] >> 8) & 0x0000FF); + bChannel[k] = (float) ((isrc[k]) & 0x0000FF); + } + } + else { + throw new ArrayStoreException("Unexpected image type"); + } + } + + /** + * Loads the contents of an ImageStack into a double[] array. + */ + public static void loadStack(ImageStack istack, double[] pixels) { + if (istack == null) { + throw new ArrayStoreException("ImageStack == null."); + } + int nx = istack.getWidth(); + int ny = istack.getHeight(); + int nz = istack.getSize(); + int offz = 0; + int nxy = nx * ny; + if (istack.getPixels(1) instanceof byte[]) { + byte[] bsrc; + for (int z = 0; z < nz; z++) { + bsrc = (byte[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[i + offz] = (double) (bsrc[i] & 0xFF); + } + offz += nxy; + } + } + else if (istack.getPixels(1) instanceof short[]) { + short[] ssrc; + for (int z = 0; z < nz; z++) { + ssrc = (short[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[i + offz] = (double) (ssrc[i] & 0xFFFF); + } + offz += nxy; + } + } + else if (istack.getPixels(1) instanceof float[]) { + float[] fsrc; + for (int z = 0; z < nz; z++) { + fsrc = (float[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[i + offz] = (double) fsrc[i]; + } + offz += nxy; + } + } + else { + throw new ArrayStoreException("Unexpected image type."); + } + } + + /** + * Loads the contents of an ImageStack into a float[] array. + */ + public static void loadStack(ImageStack istack, float[] pixels) { + if (istack == null) { + throw new ArrayStoreException("ImageStack == null."); + } + int nx = istack.getWidth(); + int ny = istack.getHeight(); + int nz = istack.getSize(); + int offz = 0; + int nxy = nx * ny; + if (istack.getPixels(1) instanceof byte[]) { + byte[] bsrc; + for (int z = 0; z < nz; z++) { + bsrc = (byte[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[i + offz] = (float) (bsrc[i] & 0xFF); + } + offz += nxy; + } + } + else if (istack.getPixels(1) instanceof short[]) { + short[] ssrc; + for (int z = 0; z < nz; z++) { + ssrc = (short[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[i + offz] = (float) (ssrc[i] & 0xFFFF); + } + offz += nxy; + } + } + else if (istack.getPixels(1) instanceof float[]) { + float[] fsrc; + for (int z = 0; z < nz; z++) { + fsrc = (float[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[i + offz] = fsrc[i]; + } + offz += nxy; + } + } + else { + throw new ArrayStoreException("Unexpected image type."); + } + } + + /** + * Loads the contents of an ImageStack into a double[][] array. Input + * structure is [z][xy]. + */ + public static void loadStack(ImageStack istack, double[][] pixels) { + if (istack == null) + throw new ArrayStoreException("ImageStack == null."); + + int nz = pixels.length; + int nxy = pixels[0].length; + + if (istack.getPixels(1) instanceof float[]) { + float[] fsrc; + for (int z = 0; z < nz; z++) { + fsrc = (float[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[z][i] = (double) fsrc[i]; + } + } + } + else if (istack.getPixels(1) instanceof short[]) { + short[] ssrc; + for (int z = 0; z < nz; z++) { + ssrc = (short[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[z][i] = (double) (ssrc[i] & 0xFFFF); + } + } + } + else if (istack.getPixels(1) instanceof byte[]) { + byte[] bsrc; + for (int z = 0; z < nz; z++) { + bsrc = (byte[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[z][i] = (double) (bsrc[i] & 0xFF); + } + } + } + else { + throw new ArrayStoreException("Unexpected image type."); + } + } + + /** + * Loads the contents of an ImageStack into a float[][] array. Input + * structure is [z][xy]. + */ + public static void loadStack(ImageStack istack, float[][] pixels) { + if (istack == null) + throw new ArrayStoreException("ImageStack == null."); + + int nz = pixels.length; + int nxy = pixels[0].length; + + if (istack.getPixels(1) instanceof float[]) { + float[] fsrc; + for (int z = 0; z < nz; z++) { + fsrc = (float[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[z][i] = fsrc[i]; + } + } + } + else if (istack.getPixels(1) instanceof short[]) { + short[] ssrc; + for (int z = 0; z < nz; z++) { + ssrc = (short[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[z][i] = (float) (ssrc[i] & 0xFFFF); + } + } + } + else if (istack.getPixels(1) instanceof byte[]) { + byte[] bsrc; + for (int z = 0; z < nz; z++) { + bsrc = (byte[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[z][i] = (float) (bsrc[i] & 0xFF); + } + } + } + else { + throw new ArrayStoreException("Unexpected image type."); + } + } + + /** + * Loads the contents of a RGB ImageStack into a int[][] array. Input + * structure is [z][xy]. + */ + public static void loadStackRGB(ImageStack istack, int[][] pixels) { + if (istack == null) { + throw new ArrayStoreException("ImageStack == null."); + } + int nz = pixels.length; + int nxy = pixels[0].length; + + if (istack.getPixels(1) instanceof int[]) { + int[] isrc; + for (int z = 0; z < nz; z++) { + isrc = (int[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[z][i] = isrc[i]; + } + } + } + else { + throw new ArrayStoreException("Input stack must be RGB."); + } + } + + /** + * Loads the contents of a RGB ImageStack into a int[] array. + */ + public static void loadStackRGB(ImageStack istack, int[] pixels) { + if (istack == null) { + throw new ArrayStoreException("ImageStack == null."); + } + int nx = istack.getWidth(); + int ny = istack.getHeight(); + int nz = istack.getSize(); + int offz = 0; + int nxy = nx * ny; + if (istack.getPixels(1) instanceof int[]) { + int[] isrc; + for (int z = 0; z < nz; z++) { + isrc = (int[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + pixels[i + offz] = isrc[i]; + } + offz += nxy; + } + } + else { + throw new ArrayStoreException("Input stack must be RGB."); + } + } + + /** + * Converts and RGB ImageProcessor to grayscale and loads the result into a + * float[][] array. Conversion: (R*R + G*G + B*B)/(R+G+B). + */ + public static void loadAndConvertRGBStack(ImageStack istack, float[][] pixels) { + if (istack == null) { + throw new ArrayStoreException("ImageStack == null."); + } + int nz = pixels.length; + int nxy = pixels[0].length; + float R, G, B; + if (istack.getPixels(1) instanceof int[]) { + int[] isrc; + for (int z = 0; z < nz; z++) { + isrc = (int[]) istack.getPixels(z + 1); + for (int i = 0; i < nxy; i++) { + R = (float) (isrc[i] >> 16 & 0x000000FF); + G = (float) (isrc[i] >> 8 & 0x000000FF); + B = (float) (isrc[i] & 0x000000FF); + pixels[z][i] = (R * R + G * G + B * B) / (R + G + B); + } + } + } + else { + throw new ArrayStoreException("Unexpected image type."); + } + } + + /* + * public static double[][] kMeans(double[][] input, int K) { + * + * int nx = input.length; int ny = input[0].length; int N = nx*ny; double[] + * r = new double[K]; double[] t = new double[K+1]; t[0] = + * -Double.MAX_VALUE; t[K] = Double.MAX_VALUE; int x, y, k; int[] count = + * new int[K]; for (int i=0;i<10;i++) { // change + * + * for (k=0;k<K;k++) { count[k] = 0; } + * + * for (k=0;k<K;k++) { for (x=0;x<nx;x++) { for (y=0;y<ny;y++) { if + * (input[x][y] < t[k+1]) { count[k]++; } } } } + * + * for (k=1;k<K;k++) { t[k] = (r[k]+r[k-1])/2.0; } + * + * } + * + * return input; } + */ + + /* + * public static double[] histogram(double[][] input, int nBins) { + * + * int nx = input.length; int ny = input[0].length; double[] hist = new + * double[nBins]; for (int i=0;i<nBins;i++) { hist[i] = 0; } int index; + * double min = Double.MAX_VALUE; double max = -Double.MAX_VALUE; double p; + * + * for (int x=0;x<nx;x++) { for (int y=0;y<ny;y++) { p = input[x][y]; if (p + * < min) { min = p; } if (p > max) { max = p; } } } for (int x=0;x<nx;x++) + * { for (int y=0;y<ny;y++) { p = input[x][y] - min; index = + * (int)Math.round((p-p%nBins)/nBins); hist[index]++; } } return hist; } + */ + + // public static double region + +} diff --git a/src/bilib/src/ijtools/Interpolator.java b/src/bilib/src/ijtools/Interpolator.java new file mode 100644 index 0000000000000000000000000000000000000000..284786eec55e27b2703b9eba3a4344a0615bfde9 --- /dev/null +++ b/src/bilib/src/ijtools/Interpolator.java @@ -0,0 +1,324 @@ +package ijtools; + +import java.lang.*; +import ij.*; + +/** + * Class for image interpolation with B-splines. Currently supported methods: + * linear, quadratic, cubic. Where applicable, mirror boundary conditions are + * used. + * + * @author Francois Aguet + * @version 1.0 + */ +public class Interpolator { + + private double[] input; + private double[] c; + private int nx, ny; + private String mode; + private double a, c0; + + /** + * @param input + * 1-D array storing the image. + * @param nx + * Width of the image. + * @param ny + * Height of the image. + * @param mode + * Interpolation mode. Options: "linear", "quadratic", "cubic". + */ + public Interpolator(double[] input, int nx, int ny, String mode) { + this.input = input; + this.nx = nx; + this.ny = ny; + this.mode = mode; + if (mode.equals("linear")) { + c = input; + } + else if (mode.equals("quadratic")) { + c0 = 8.0; + a = -3.0 + 2.0 * Math.sqrt(2.0); + computeCoefficients(); + } + else if (mode.equals("cubic")) { + c0 = 6.0; + a = -2.0 + Math.sqrt(3.0); + computeCoefficients(); + } + + // test reconstruction + /* + * double[][] s2 = new double[ntheta][nr]; for (int y=0;y<nr;y++) { for + * (int x=0;x<ntheta;x++) { s2[x][y] = interpolatedValue(x+1, y+1); } } + * IJtools.show(s2, "reconstruction"); + */ + } + + /** + * Return the value interpolated at (x,y). + */ + public double getValue(double x, double y) { + int xi = (int) x; + int yi = (int) y; + int x0, x1, y0, y1; + + if (mode.equals("linear")) { + double dx = x - xi; + double dy = y - yi; + if (x < 0) { + dx = -dx; + x1 = mirror(xi - 1, nx); + } + else { + x1 = mirror(xi + 1, nx); + } + if (y < 0) { + dy = -dy; + y1 = mirror(yi - 1, ny); + } + else { + y1 = mirror(yi + 1, ny); + } + x0 = mirror(xi, nx); + y0 = mirror(yi, ny); + return (1.0 - dy) * (dx * input[x1 + y0 * nx] + (1.0 - dx) * input[x0 + y0 * nx]) + dy * (dx * input[x1 + y1 * nx] + (1.0 - dx) * input[x0 + y1 * nx]); + } + else { + double dx = x - xi; + double dy = y - yi; + double[] wx, wy; + int x2, x3, y2, y3; + + if (x < 0) { + xi = xi - 1; + dx = 1.0 + dx; + } + if (y < 0) { + yi = yi - 1; + dy = 1.0 + dy; + } + + if (mode.equals("quadratic")) { + wx = getQuadraticSpline(dx); + wy = getQuadraticSpline(dy); + } + else { // if (mode.equals("cubic")) { + wx = getCubicSpline(dx); + wy = getCubicSpline(dy); + } + + x0 = xi - 1; + x1 = xi; + x2 = xi + 1; + x3 = xi + 2; + x0 = mirror(x0, nx); + x1 = mirror(x1, nx); + x2 = mirror(x2, nx); + x3 = mirror(x3, nx); + + y0 = yi - 1; + y1 = yi; + y2 = yi + 1; + y3 = yi + 2; + y0 = mirror(y0, ny); + y1 = mirror(y1, ny); + y2 = mirror(y2, ny); + y3 = mirror(y3, ny); + y0 *= nx; + y1 *= nx; + y2 *= nx; + y3 *= nx; + + double v = wx[0] * (wy[0] * c[x0 + y0] + wy[1] * c[x0 + y1] + wy[2] * c[x0 + y2] + wy[3] * c[x0 + y3]) + wx[1] + * (wy[0] * c[x1 + y0] + wy[1] * c[x1 + y1] + wy[2] * c[x1 + y2] + wy[3] * c[x1 + y3]) + wx[2] + * (wy[0] * c[x2 + y0] + wy[1] * c[x2 + y1] + wy[2] * c[x2 + y2] + wy[3] * c[x2 + y3]) + wx[3] + * (wy[0] * c[x3 + y0] + wy[1] * c[x3 + y1] + wy[2] * c[x3 + y2] + wy[3] * c[x3 + y3]); + return v; + } + + } + + private int mirror(int x, int nx) { + if (x >= 0 && x < nx) { + return x; + } + else if (x < 0) { + return -x; + } + else { + return 2 * nx - 2 - x; + } + } + + // public double[] interpolate (double[][] coordinates) {}; + + /* + * public static double interpolateLinear(double[] image, int[] dims, double + * x, double y, int z) { + * + * int nx = dims[0]; int ny = dims[1]; int i = (int)x; int j = (int)y; + * double dx = x - (double)(i); double dy = y - (double)(j); + * + * if (x < 0) { dx = -dx; i = 0; } if (i >= nx-1) { dx = 1-dx; i--; i = + * nx-2; } if (y < 0) { dy = -dy; j = 0; } if (j >= ny-1) { dy = 1-dy; j--; + * j = ny-2;} + * + * int idx1 = i+nx*(j+z*ny); int idx2 = idx1+nx; double v00 = image[idx1]; + * double v10 = image[idx1+1]; double v01 = image[idx2]; double v11 = + * image[idx2+1]; + * + * return dx*((v11-v10)*dy + v10) - (dx-1.0)*((v01-v00)*dy + v00); } + */ + + private void computeCoefficients() { + // Horizontal + double[] cp = getCausalInitHorizontal(input, a); + int i; + for (int y = 0; y < ny; y++) { + for (int x = 1; x < nx; x++) { // causal + i = x + y * nx; + cp[i] = input[i] + a * cp[i - 1]; + } + } + c = getAntiCausalInitHorizontal(cp, a); // cn + for (int y = 0; y < ny; y++) { + for (int x = nx - 2; x >= 0; x--) { // anticausal + i = x + y * nx; + c[i] = a * (c[i + 1] - cp[i]); + } + } + // Vertical + cp = getCausalInitVertical(c, a); + for (int x = 0; x < nx; x++) { + for (int y = 1; y < ny; y++) { + i = x + y * nx; + cp[i] = c[i] + a * cp[i - nx]; + } + } + c = getAntiCausalInitVertical(cp, a); + for (int x = 0; x < nx; x++) { + for (int y = ny - 2; y >= 0; y--) { + i = x + y * nx; + c[i] = a * (c[i + nx] - cp[i]); + } + } + // constant + double c02 = c0 * c0; + for (i = 0; i < ny * ny; i++) { + c[i] = c02 * c[i]; + } + } + + /** + * Computes the quadratic spline basis function at a position t. + * + * @param t + * argument between 0 and 1. + * @return 4 sampled values of the cubic B-spline (B3[t+1], B3[t], B3[t-1], + * B3[t-2]). + */ + private static double[] getQuadraticSpline(double t) { + if (t < 0.0 || t > 1.0) { + throw new ArrayStoreException("Argument t for quadratic B-spline outside of expected range [0, 1]: " + t); + } + double v[] = new double[4]; + if (t <= 0.5) { + v[0] = (t - 0.5) * (t - 0.5) / 2.0; + v[1] = 0.75 - t * t; + v[2] = 1.0 - v[1] - v[0]; // (t+0.5)*(t+0.5)/2.0; + v[3] = 0.0; + } + else { + v[0] = 0.0; + v[1] = (t - 1.5) * (t - 1.5) / 2.0; + v[3] = (t - 0.5) * (t - 0.5) / 2.0; + v[2] = 1.0 - v[3] - v[1]; + } + return v; + } + + /** + * Computes the cubic spline basis function at a position t. + * + * @param t + * argument between 0 and 1. + * @return 4 sampled values of the cubic B-spline (B3[t+1], B3[t], B3[t-1], + * B3[t-2]). + */ + private static double[] getCubicSpline(double t) { + if (t < 0.0 || t > 1.0) { + throw new ArrayStoreException("Argument t for cubic B-spline outside of expected range [0, 1]: " + t); + } + double v[] = new double[4]; + double t1 = 1.0 - t; + double t2 = t * t; + v[0] = (t1 * t1 * t1) / 6.0; + v[1] = (2.0 / 3.0) + 0.5 * t2 * (t - 2); + v[3] = (t2 * t) / 6.0; + v[2] = 1.0 - v[3] - v[1] - v[0]; + return v; + } + + private double[] getAntiCausalInitVertical(double[] s, double a) { + double[] cn = new double[nx * ny]; + int idx = (ny - 1) * nx; + double d = a * a - 1.0; + for (int x = 0; x < nx; x++) { + cn[x + idx] = a * (s[x + idx] + a * s[x + idx - nx]) / d; + } + return cn; + } + + private double[] getAntiCausalInitHorizontal(double[] s, double a) { + double[] cn = new double[nx * ny]; + double d = a * a - 1.0; + for (int y = 0; y < ny; y++) { + cn[nx - 1 + y * nx] = a * (s[nx - 1 + y * nx] + a * s[nx - 2 + y * nx]) / d; + } + return cn; + } + + // Exact method + private double[] getCausalInitVertical(double[] s, double z) { + double[] cp = new double[nx * ny]; + double zd, sum, den, za; + for (int x = 0; x < nx; x++) { + zd = Math.pow(z, ny - 1); + sum = s[x] + s[x + (ny - 1) * nx] * zd; + den = zd * zd; + zd = den / z; + za = z; + for (int y = 1; y < ny - 1; y++) { + sum += s[x + y * nx] * (za + zd); + za *= z; + zd /= z; + } + sum /= (1 - den); + cp[x] = sum; + } + return cp; + } + + private double[] getCausalInitHorizontal(double[] s, double z) { + double[] cp = new double[nx * ny]; + double zd, sum, den, za; + for (int y = 0; y < ny; y++) { + zd = Math.pow(z, nx - 1); + sum = s[y * nx] + s[nx - 1 + y * nx] * zd; + den = zd * zd; + zd = den / z; + za = z; + for (int x = 1; x < nx - 1; x++) { + sum += s[x + y * nx] * (za + zd); + za *= z; + zd /= z; + } + sum /= (1 - den); + cp[y * nx] = sum; + } + return cp; + } + +} diff --git a/src/bilib/src/ijtools/SplineConvolver.java b/src/bilib/src/ijtools/SplineConvolver.java new file mode 100644 index 0000000000000000000000000000000000000000..d0ed39423d071aeddf72aca620746a0f41780c45 --- /dev/null +++ b/src/bilib/src/ijtools/SplineConvolver.java @@ -0,0 +1,437 @@ +package ijtools; + +//package ijtools; +import ij.IJ; + +/** + * Convolution routines for spline kernels of arbitrary integer orders and + * scales. + * + * @author Francois Aguet + * @version 1.0 + */ +public class SplineConvolver { + + public static double[][] convolve(double[][] input, int n, int scale) { + + int nx = input.length; + int ny = input[0].length; + + double[][] output;// = new double[nx][ny]; + double[][] reference;// = new double[nx][ny]; + + double[] splineKernelFine = splineSamples(n, scale); + double[] splineKernelCoarse = splineSamples(n, 1); + // IJtools.show("spline", splineKernelFine, splineKernelFine.length, 1); + + long start1 = System.currentTimeMillis(); + reference = Convolver2D.convolveEvenX(input, splineKernelFine); + reference = Convolver2D.convolveEvenY(reference, splineKernelFine); + long end1 = System.currentTimeMillis(); + IJtools.show("Reference", reference); + + long start2 = System.currentTimeMillis(); + if (n % 2 == 1) { // odd n + output = Convolver2D.convolveEvenX(input, splineKernelCoarse); + output = Convolver2D.convolveEvenY(output, splineKernelCoarse); + for (int k = 1; k <= (n + 1) / 2; k++) { + output = movingSum(output, scale); + output = movingSumSansFrontieres(output, scale); + } + } + else { // even n + if (scale % 2 == 1) { // odd scale + output = Convolver2D.convolveEvenX(input, splineKernelCoarse); + output = Convolver2D.convolveEvenY(output, splineKernelCoarse); + for (int k = 0; k <= n; k++) { + output = movingSumOdd(output, scale); + } + } + else { // even scale + output = movingSum(input, scale); + output = movingSumSansFrontieres(output, scale); + for (int k = 2; k <= n / 2; k++) { + output = movingSum(output, scale); + output = movingSumSansFrontieres(output, scale); + } + output = movingSum(output, scale); + + splineKernelCoarse = splineSamplesHalfStep(n); + for (int k = 0; k < splineKernelCoarse.length; k++) { + IJ.write("" + splineKernelCoarse[k]); + } + output = convEvenKernelX(output, splineKernelCoarse); + output = convEvenKernelY(output, splineKernelCoarse); + output = crop(output, (scale + splineKernelCoarse.length) / 2 - 1); + } + } + double norm = Math.pow(scale, n + 1); + for (int x = 0; x < nx; x++) { + for (int y = 0; y < ny; y++) { + output[x][y] /= (norm * norm); + } + } + long end2 = System.currentTimeMillis(); + IJ.write("ref time: " + (end1 - start1)); + IJ.write("sum time: " + (end2 - start2)); + + IJtools.show("Moving sums", output); + + return output; + + } + + private static double[][] movingSum(double[][] input, int length) { + int nx = input.length; + int ny = input[0].length; + double[][] temp = new double[nx + length - 1][ny]; + double[][] output = new double[nx + length - 1][ny + length - 1]; + int x, y; + + for (y = 0; y < ny; y++) { + temp[0][y] = input[0][y]; + for (x = 1; x < length; x++) { + temp[0][y] += input[x][y]; + } + for (x = 1; x < length; x++) { // left border: mirror + temp[x][y] = temp[x - 1][y] - input[length - x][y] + input[x][y]; // remove + // 0-(x-length) + } + for (x = length; x < nx; x++) { + temp[x][y] = temp[x - 1][y] - input[x - length][y] + input[x][y]; + } + for (x = nx; x < nx + length - 1; x++) { // right border: mirror + temp[x][y] = temp[x - 1][y] - input[x - length][y] + input[2 * nx - x - 2][y]; // (ns-1) + // - + // (x + // - + // (ns-1)) + } + } + for (x = 0; x < nx + length - 1; x++) { + output[x][0] = temp[x][0]; + for (y = 1; y < length; y++) { + output[x][0] += temp[x][y]; + } + for (y = 1; y < length; y++) { // left border: mirror + output[x][y] = output[x][y - 1] - temp[x][length - y] + temp[x][y]; + } + for (y = length; y < ny; y++) { + output[x][y] = output[x][y - 1] - temp[x][y - length] + temp[x][y]; + } + for (y = ny; y < ny + length - 1; y++) { // right border: mirror + output[x][y] = output[x][y - 1] - temp[x][y - length] + temp[x][2 * ny - y - 2]; + } + } + return output; + } + + private static double[][] movingSumSansFrontieres(double[][] input, int length) { + int nx = input.length; + int ny = input[0].length; + double[][] temp = new double[nx - length + 1][ny]; + double[][] output = new double[nx - length + 1][ny - length + 1]; + int x, y; + + for (y = 0; y < ny; y++) { + temp[0][y] = input[0][y]; + for (x = 1; x < length; x++) { + temp[0][y] += input[x][y]; + } + for (x = 1; x < nx - length + 1; x++) { + temp[x][y] = temp[x - 1][y] - input[x - 1][y] + input[x + length - 1][y]; + } + } + for (x = 0; x < nx - length + 1; x++) { // ///// + 1 ?? + output[x][0] = temp[x][0]; + for (y = 1; y < length; y++) { + output[x][0] += temp[x][y]; + } + for (y = 1; y < ny - length + 1; y++) { + output[x][y] = output[x][y - 1] - temp[x][y - 1] + temp[x][y + length - 1]; + } + } + return output; + } + + private static double[][] movingSumOdd(double[][] input, int length) { + int nx = input.length; + int ny = input[0].length; + double[][] temp = new double[nx][ny]; + double[][] output = new double[nx][ny]; + int c = (length - 1) / 2; + int x, y; + for (y = 0; y < ny; y++) { + temp[0][y] = input[0][y]; + for (x = 1; x <= c; x++) { + temp[0][y] += 2.0 * input[x][y]; + } + for (x = 1; x <= c; x++) { // left border + temp[x][y] = temp[x - 1][y] - input[1 + c - x][y] + input[x + c][y]; + } + for (x = c + 1; x < nx - c; x++) { + temp[x][y] = temp[x - 1][y] - input[x - c - 1][y] + input[x + c][y]; + } + for (x = nx - c; x < nx; x++) { // right border + temp[x][y] = temp[x - 1][y] - input[x - c - 1][y] + input[2 * nx - 2 - x - c][y]; + } + } + for (x = 0; x < nx; x++) { + output[x][0] = temp[x][0]; + for (y = 1; y <= c; y++) { + output[x][0] += 2.0 * temp[x][y]; + } + for (y = 1; y <= c; y++) { // top border + output[x][y] = output[x][y - 1] - temp[x][1 + c - y] + temp[x][y + c]; + } + for (y = c + 1; y < ny - c; y++) { + output[x][y] = output[x][y - 1] - temp[x][y - c - 1] + temp[x][y + c]; + } + for (y = ny - c; y < ny; y++) { // bottom border + output[x][y] = output[x][y - 1] - temp[x][y - c - 1] + temp[x][2 * ny - 2 - y - c]; + } + } + return output; + } + + private static double[][] convEvenKernelX(double[][] input, double[] kernel) { + int nx = input.length; + int ny = input[0].length; + int w = kernel.length; + double[][] output = new double[nx + w - 1][ny]; + int x, y, k; + + for (y = 0; y < ny; y++) { + for (x = 0; x <= w - 2; x++) { // left border + output[x][y] = 0.0; + for (k = 0; k <= w - x - 2; k++) { // (w-1) - (x+1) + output[x][y] += kernel[k] * input[w - x - 1 - k][y]; // 0 - + // (0 + // - + // (x-w+1+k)) + } + for (k = w - x - 1; k < w; k++) { + output[x][y] += kernel[k] * input[x - w + 1 + k][y]; + } + } + for (x = w - 1; x < nx; x++) { + output[x][y] = 0.0; + for (k = 0; k < w; k++) { + output[x][y] += kernel[k] * input[x - w + 1 + k][y]; + } + } + for (x = nx; x <= nx + w - 2; x++) { // right border + output[x][y] = 0.0; + for (k = 0; k <= nx - 2 - x + w; k++) { + output[x][y] += kernel[k] * input[x - w + 1 + k][y]; + } + for (k = nx - x - 1 + w; k < w; k++) { + output[x][y] += kernel[k] * input[2 * nx - 3 - x + w - k][y]; + } + } + } + return output; + } + + private static double[][] convEvenKernelY(double[][] input, double[] kernel) { + int nx = input.length; + int ny = input[0].length; + int w = kernel.length; + double[][] output = new double[nx][ny + w - 1]; + int x, y, k; + + for (x = 0; x < nx; x++) { + for (y = 0; y <= w - 2; y++) { // top border + output[x][y] = 0.0; + for (k = 0; k <= w - y - 2; k++) { // outside of signal -> + // mirror: + output[x][y] += kernel[k] * input[x][w - y - 1 - k]; + } + for (k = w - y - 1; k < w; k++) { + output[x][y] += kernel[k] * input[x][y - w + 1 + k]; + } + } + for (y = w - 1; y < ny; y++) { + output[x][y] = 0.0; + for (k = 0; k < w; k++) { + output[x][y] += kernel[k] * input[x][y - w + 1 + k]; + } + } + for (y = ny; y <= ny + w - 2; y++) { // bottom border + output[x][y] = 0.0; + for (k = 0; k <= ny - 2 - y + w; k++) { + output[x][y] += kernel[k] * input[x][y - w + 1 + k]; + } + for (k = ny - 1 - y + w; k < w; k++) { + output[x][y] += kernel[k] * input[x][2 * ny - 3 - y + w - k]; + } + } + } + return output; + } + + private static double[][] crop(double[][] input, int t) { + int nx = input.length - 2 * t; + int ny = input[0].length - 2 * t; + double[][] output = new double[nx][ny]; + for (int y = 0; y < ny; y++) { + for (int x = 0; x < nx; x++) { + output[x][y] = input[x + t][y + t]; + } + } + return output; + } + + /* + * private static double[] mavg(double[] signal, int scale) { int ns = + * signal.length; double[] out = new double[ns+scale-1]; out[0] = + * sum(signal, 0, scale-1); for (int i=1;i<scale;i++) { out[i] = out[i-1] - + * signal[scale-i+1] + signal[i]; } for (int i=scale;i<ns;i++) { out[i] = + * out[i-1] - signal[i-scale] + signal[i]; } for (int + * i=ns;i<=ns+scale-2;i++) { out[i] = out[i-1] - signal[i-scale] + + * signal[2*ns-i]; } return out; } + */ + + private static double[] mavg_odd(double[] signal, int scale) { + int ns = signal.length; + int c = (scale - 1) / 2; + double[] out = new double[ns]; + out[0] = signal[0] + 2.0 * sum(signal, 1, c); + for (int i = 1; i <= c; i++) { + out[i] = out[i - 1] - signal[2 - i + c] + signal[i + c]; + } + for (int i = c + 1; i < ns - c; i++) { + out[i] = out[i - 1] - signal[i - c - 1] + signal[i + c]; + } + for (int i = ns - c; i < ns; i++) { + out[i] = out[i - 1] - signal[i - c - 1] + signal[2 * ns - c - i]; + } + return out; + } + + private static double[] convEvenKernel(double[] signal, double[] kernel) { + int ns = signal.length; + int w = kernel.length; + double[] out = new double[ns + w - 1]; + for (int i = 0; i <= w - 2; i++) { + out[i] = 0.0; + for (int k = 0; k <= w - i - 1; k++) { + out[i] += kernel[k] * signal[2 - i + w - k]; + } + for (int k = w - i; k < w; k++) { + out[i] += kernel[k] * signal[i - w + k]; + } + } + for (int i = w - 1; i < ns; i++) { + out[i] = 0.0; + for (int k = 0; k < w; k++) { + out[i] += kernel[k] * signal[i - w + k]; + } + } + for (int i = ns; i <= ns + w - 2; i++) { + for (int k = 0; k < ns - i + w; k++) { + out[i] += kernel[k] * signal[i - w + k]; + } + for (int k = ns - i + w; k < w; k++) { + out[i] += kernel[k] * signal[ns - 1 - w + k]; + } + } + return out; + } + + private static double[] mavg_nob(double[] signal, int scale) { + int ns = signal.length; + double[] out = new double[ns - scale + 1]; + out[0] = sum(signal, 0, scale - 1); + for (int i = 1; i <= ns - scale; i++) { + out[i] = out[i - 1] + signal[i + scale - 1] - signal[i - 1]; + } + return out; + } + + private static double sum(double[] s, int a, int b) { + double t = 0; + for (int i = a; i <= b; i++) { + t += s[i]; + } + return t; + } + + /** + * returns the samples of a degree n, scale s B-spline samples returned for + * [0 b+1/2] + */ + private static double[] splineSamples(int n, int s) { + + double b = ((double) n + 1.0) / 2.0; + double normalization = (double) (s * fact(n)); + int nx = (int) (b * s); // +1 unnecessary, =0 + if (nx != b * s) { + nx++; + } + double[] samples = new double[nx]; + double ksign; + double x, klimit; + int[] coeffs = binomialCoefficients(n + 1); + for (int i = 0; i < nx; i++) { + x = (double) i / (double) s; + klimit = x + b; + samples[i] = Math.pow(x + b, n); + ksign = 1.0; + for (int k = 1; k <= klimit; k++) { + ksign *= -1.0; + samples[i] += (double) coeffs[k] * ksign * Math.pow(x - k + b, n); + } + samples[i] /= normalization; + } + return samples; + } + + /** + * returns the samples of a degree n at half-integer positions samples + * returned for [-(b+1)/2 (b+1)/2] + */ + private static double[] splineSamplesHalfStep(int n) { + double b = ((double) n + 1.0) / 2.0; + double normalization = (double) fact(n); + double[] samples = new double[n]; + double ksign; + double x, klimit; + int[] coeffs = binomialCoefficients(n + 1); + for (int i = 0; i < n; i++) { + x = (double) i - ((double) n - 1.0) / 2.0; + klimit = x + b; + ksign = 1.0; + samples[i] = Math.pow(x + b, n); + for (int k = 1; k <= klimit; k++) { + ksign *= -1.0; + samples[i] += (double) coeffs[k] * ksign * Math.pow(x - k + b, n); + } + samples[i] /= normalization; + } + return samples; + } + + private static int[] binomialCoefficients(int n) { + int[] coeffs = new int[n + 1]; + for (int k = 0; k <= n; k++) { + coeffs[k] = (int) (fact(n) / (fact(k) * fact(n - k))); + } + return coeffs; + } + + public static long fact(int n) { + + if (n <= 1) { + return 1; + } + else { + long k = n; + for (int i = n - 1; i > 1; i--) { + k *= i; + } + return k; + } + } + +} diff --git a/src/bilib/src/imageware.zip b/src/bilib/src/imageware.zip new file mode 100644 index 0000000000000000000000000000000000000000..4685044fa0b9ca7d6a7683c0a320929b0051f837 Binary files /dev/null and b/src/bilib/src/imageware.zip differ diff --git a/src/bilib/src/imageware/Access.java b/src/bilib/src/imageware/Access.java new file mode 100644 index 0000000000000000000000000000000000000000..d345d9b0a660f91ce52736dde3781979df5be5ec --- /dev/null +++ b/src/bilib/src/imageware/Access.java @@ -0,0 +1,256 @@ +package imageware; + +/** + * Class Access. + * + * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de + * Lausanne, Lausanne, Switzerland + */ + +public interface Access extends Buffer { + + // getPixel section + public double getPixel(int x, int y, int z); + + public double getPixel(int x, int y, int z, byte boundaryConditions); + + public double getInterpolatedPixel(double x, double y, double z); + + public double getInterpolatedPixel(double x, double y, double z, byte boundaryConditions); + + // putPixel section + public void putPixel(int x, int y, int z, double value); + + // getBounded section + + public void getBoundedX(int x, int y, int z, byte[] buffer); + + public void getBoundedY(int x, int y, int z, byte[] buffer); + + public void getBoundedZ(int x, int y, int z, byte[] buffer); + + public void getBoundedXY(int x, int y, int z, byte[][] buffer); + + public void getBoundedXZ(int x, int y, int z, byte[][] buffer); + + public void getBoundedYZ(int x, int y, int z, byte[][] buffer); + + public void getBoundedXYZ(int x, int y, int z, byte[][][] buffer); + + public void getBoundedX(int x, int y, int z, short[] buffer); + + public void getBoundedY(int x, int y, int z, short[] buffer); + + public void getBoundedZ(int x, int y, int z, short[] buffer); + + public void getBoundedXY(int x, int y, int z, short[][] buffer); + + public void getBoundedXZ(int x, int y, int z, short[][] buffer); + + public void getBoundedYZ(int x, int y, int z, short[][] buffer); + + public void getBoundedXYZ(int x, int y, int z, short[][][] buffer); + + public void getBoundedX(int x, int y, int z, float[] buffer); + + public void getBoundedY(int x, int y, int z, float[] buffer); + + public void getBoundedZ(int x, int y, int z, float[] buffer); + + public void getBoundedXY(int x, int y, int z, float[][] buffer); + + public void getBoundedXZ(int x, int y, int z, float[][] buffer); + + public void getBoundedYZ(int x, int y, int z, float[][] buffer); + + public void getBoundedXYZ(int x, int y, int z, float[][][] buffer); + + public void getBoundedX(int x, int y, int z, double[] buffer); + + public void getBoundedY(int x, int y, int z, double[] buffer); + + public void getBoundedZ(int x, int y, int z, double[] buffer); + + public void getBoundedXY(int x, int y, int z, double[][] buffer); + + public void getBoundedXZ(int x, int y, int z, double[][] buffer); + + public void getBoundedYZ(int x, int y, int z, double[][] buffer); + + public void getBoundedXYZ(int x, int y, int z, double[][][] buffer); + + // getBlock with boundary conditions section + + public void getBlockX(int x, int y, int z, byte[] buffer, byte boundaryConditions); + + public void getBlockY(int x, int y, int z, byte[] buffer, byte boundaryConditions); + + public void getBlockZ(int x, int y, int z, byte[] buffer, byte boundaryConditions); + + public void getBlockXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions); + + public void getBlockXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions); + + public void getBlockYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions); + + public void getBlockXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions); + + public void getBlockX(int x, int y, int z, short[] buffer, byte boundaryConditions); + + public void getBlockY(int x, int y, int z, short[] buffer, byte boundaryConditions); + + public void getBlockZ(int x, int y, int z, short[] buffer, byte boundaryConditions); + + public void getBlockXY(int x, int y, int z, short[][] buffer, byte boundaryConditions); + + public void getBlockXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions); + + public void getBlockYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions); + + public void getBlockXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions); + + public void getBlockX(int x, int y, int z, float[] buffer, byte boundaryConditions); + + public void getBlockY(int x, int y, int z, float[] buffer, byte boundaryConditions); + + public void getBlockZ(int x, int y, int z, float[] buffer, byte boundaryConditions); + + public void getBlockXY(int x, int y, int z, float[][] buffer, byte boundaryConditions); + + public void getBlockXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions); + + public void getBlockYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions); + + public void getBlockXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions); + + public void getBlockX(int x, int y, int z, double[] buffer, byte boundaryConditions); + + public void getBlockY(int x, int y, int z, double[] buffer, byte boundaryConditions); + + public void getBlockZ(int x, int y, int z, double[] buffer, byte boundaryConditions); + + public void getBlockXY(int x, int y, int z, double[][] buffer, byte boundaryConditions); + + public void getBlockXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions); + + public void getBlockYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions); + + public void getBlockXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions); + + // getNeighborhood with boundary conditions section + + public void getNeighborhoodX(int x, int y, int z, byte[] buffer, byte boundaryConditions); + + public void getNeighborhoodY(int x, int y, int z, byte[] buffer, byte boundaryConditions); + + public void getNeighborhoodZ(int x, int y, int z, byte[] buffer, byte boundaryConditions); + + public void getNeighborhoodXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions); + + public void getNeighborhoodXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions); + + public void getNeighborhoodYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions); + + public void getNeighborhoodXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions); + + public void getNeighborhoodX(int x, int y, int z, short[] buffer, byte boundaryConditions); + + public void getNeighborhoodY(int x, int y, int z, short[] buffer, byte boundaryConditions); + + public void getNeighborhoodZ(int x, int y, int z, short[] buffer, byte boundaryConditions); + + public void getNeighborhoodXY(int x, int y, int z, short[][] buffer, byte boundaryConditions); + + public void getNeighborhoodXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions); + + public void getNeighborhoodYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions); + + public void getNeighborhoodXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions); + + public void getNeighborhoodX(int x, int y, int z, float[] buffer, byte boundaryConditions); + + public void getNeighborhoodY(int x, int y, int z, float[] buffer, byte boundaryConditions); + + public void getNeighborhoodZ(int x, int y, int z, float[] buffer, byte boundaryConditions); + + public void getNeighborhoodXY(int x, int y, int z, float[][] buffer, byte boundaryConditions); + + public void getNeighborhoodXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions); + + public void getNeighborhoodYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions); + + public void getNeighborhoodXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions); + + public void getNeighborhoodX(int x, int y, int z, double[] buffer, byte boundaryConditions); + + public void getNeighborhoodY(int x, int y, int z, double[] buffer, byte boundaryConditions); + + public void getNeighborhoodZ(int x, int y, int z, double[] buffer, byte boundaryConditions); + + public void getNeighborhoodXY(int x, int y, int z, double[][] buffer, byte boundaryConditions); + + public void getNeighborhoodXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions); + + public void getNeighborhoodYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions); + + public void getNeighborhoodXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions); + + // putBounded section + + public void putBoundedX(int x, int y, int z, byte[] buffer); + + public void putBoundedY(int x, int y, int z, byte[] buffer); + + public void putBoundedZ(int x, int y, int z, byte[] buffer); + + public void putBoundedXY(int x, int y, int z, byte[][] buffer); + + public void putBoundedXZ(int x, int y, int z, byte[][] buffer); + + public void putBoundedYZ(int x, int y, int z, byte[][] buffer); + + public void putBoundedXYZ(int x, int y, int z, byte[][][] buffer); + + public void putBoundedX(int x, int y, int z, short[] buffer); + + public void putBoundedY(int x, int y, int z, short[] buffer); + + public void putBoundedZ(int x, int y, int z, short[] buffer); + + public void putBoundedXY(int x, int y, int z, short[][] buffer); + + public void putBoundedXZ(int x, int y, int z, short[][] buffer); + + public void putBoundedYZ(int x, int y, int z, short[][] buffer); + + public void putBoundedXYZ(int x, int y, int z, short[][][] buffer); + + public void putBoundedX(int x, int y, int z, float[] buffer); + + public void putBoundedY(int x, int y, int z, float[] buffer); + + public void putBoundedZ(int x, int y, int z, float[] buffer); + + public void putBoundedXY(int x, int y, int z, float[][] buffer); + + public void putBoundedXZ(int x, int y, int z, float[][] buffer); + + public void putBoundedYZ(int x, int y, int z, float[][] buffer); + + public void putBoundedXYZ(int x, int y, int z, float[][][] buffer); + + public void putBoundedX(int x, int y, int z, double[] buffer); + + public void putBoundedY(int x, int y, int z, double[] buffer); + + public void putBoundedZ(int x, int y, int z, double[] buffer); + + public void putBoundedXY(int x, int y, int z, double[][] buffer); + + public void putBoundedXZ(int x, int y, int z, double[][] buffer); + + public void putBoundedYZ(int x, int y, int z, double[][] buffer); + + public void putBoundedXYZ(int x, int y, int z, double[][][] buffer); + +} diff --git a/src/bilib/src/imageware/Buffer.java b/src/bilib/src/imageware/Buffer.java new file mode 100644 index 0000000000000000000000000000000000000000..29206a3ca2ccd7a4599b5b3991881584431fb483 --- /dev/null +++ b/src/bilib/src/imageware/Buffer.java @@ -0,0 +1,188 @@ +package imageware; + +/** + * Class Buffer. + * + * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de + * Lausanne, Lausanne, Switzerland + */ + +public interface Buffer { + public int getType(); + + public String getTypeToString(); + + public int getDimension(); + + public int[] getSize(); + + public int getSizeX(); + + public int getSizeY(); + + public int getSizeZ(); + + public int getWidth(); + + public int getHeight(); + + public int getDepth(); + + public int getTotalSize(); + + public boolean isSameSize(ImageWare imageware); + + // get section + public void getX(int x, int y, int z, ImageWare buffer); + + public void getY(int x, int y, int z, ImageWare buffer); + + public void getZ(int x, int y, int z, ImageWare buffer); + + public void getXY(int x, int y, int z, ImageWare buffer); + + public void getXZ(int x, int y, int z, ImageWare buffer); + + public void getYZ(int x, int y, int z, ImageWare buffer); + + public void getXYZ(int x, int y, int z, ImageWare buffer); + + public void getX(int x, int y, int z, byte[] buffer); + + public void getY(int x, int y, int z, byte[] buffer); + + public void getZ(int x, int y, int z, byte[] buffer); + + public void getXY(int x, int y, int z, byte[][] buffer); + + public void getXZ(int x, int y, int z, byte[][] buffer); + + public void getYZ(int x, int y, int z, byte[][] buffer); + + public void getXYZ(int x, int y, int z, byte[][][] buffer); + + public void getX(int x, int y, int z, short[] buffer); + + public void getY(int x, int y, int z, short[] buffer); + + public void getZ(int x, int y, int z, short[] buffer); + + public void getXY(int x, int y, int z, short[][] buffer); + + public void getXZ(int x, int y, int z, short[][] buffer); + + public void getYZ(int x, int y, int z, short[][] buffer); + + public void getXYZ(int x, int y, int z, short[][][] buffer); + + public void getX(int x, int y, int z, float[] buffer); + + public void getY(int x, int y, int z, float[] buffer); + + public void getZ(int x, int y, int z, float[] buffer); + + public void getXY(int x, int y, int z, float[][] buffer); + + public void getXZ(int x, int y, int z, float[][] buffer); + + public void getYZ(int x, int y, int z, float[][] buffer); + + public void getXYZ(int x, int y, int z, float[][][] buffer); + + public void getX(int x, int y, int z, double[] buffer); + + public void getY(int x, int y, int z, double[] buffer); + + public void getZ(int x, int y, int z, double[] buffer); + + public void getXY(int x, int y, int z, double[][] buffer); + + public void getXZ(int x, int y, int z, double[][] buffer); + + public void getYZ(int x, int y, int z, double[][] buffer); + + public void getXYZ(int x, int y, int z, double[][][] buffer); + + // put section + public void putX(int x, int y, int z, ImageWare buffer); + + public void putY(int x, int y, int z, ImageWare buffer); + + public void putZ(int x, int y, int z, ImageWare buffer); + + public void putXY(int x, int y, int z, ImageWare buffer); + + public void putXZ(int x, int y, int z, ImageWare buffer); + + public void putYZ(int x, int y, int z, ImageWare buffer); + + public void putXYZ(int x, int y, int z, ImageWare buffer); + + public void putX(int x, int y, int z, byte[] buffer); + + public void putY(int x, int y, int z, byte[] buffer); + + public void putZ(int x, int y, int z, byte[] buffer); + + public void putXY(int x, int y, int z, byte[][] buffer); + + public void putXZ(int x, int y, int z, byte[][] buffer); + + public void putYZ(int x, int y, int z, byte[][] buffer); + + public void putXYZ(int x, int y, int z, byte[][][] buffer); + + public void putX(int x, int y, int z, short[] buffer); + + public void putY(int x, int y, int z, short[] buffer); + + public void putZ(int x, int y, int z, short[] buffer); + + public void putXY(int x, int y, int z, short[][] buffer); + + public void putXZ(int x, int y, int z, short[][] buffer); + + public void putYZ(int x, int y, int z, short[][] buffer); + + public void putXYZ(int x, int y, int z, short[][][] buffer); + + public void putX(int x, int y, int z, float[] buffer); + + public void putY(int x, int y, int z, float[] buffer); + + public void putZ(int x, int y, int z, float[] buffer); + + public void putXY(int x, int y, int z, float[][] buffer); + + public void putXZ(int x, int y, int z, float[][] buffer); + + public void putYZ(int x, int y, int z, float[][] buffer); + + public void putXYZ(int x, int y, int z, float[][][] buffer); + + public void putX(int x, int y, int z, double[] buffer); + + public void putY(int x, int y, int z, double[] buffer); + + public void putZ(int x, int y, int z, double[] buffer); + + public void putXY(int x, int y, int z, double[][] buffer); + + public void putXZ(int x, int y, int z, double[][] buffer); + + public void putYZ(int x, int y, int z, double[][] buffer); + + public void putXYZ(int x, int y, int z, double[][][] buffer); + + // get Slice in a specific type for a fast and direct access + public Object[] getVolume(); + + public byte[] getSliceByte(int z); + + public short[] getSliceShort(int z); + + public float[] getSliceFloat(int z); + + public double[] getSliceDouble(int z); + +} diff --git a/src/bilib/src/imageware/Builder.java b/src/bilib/src/imageware/Builder.java new file mode 100644 index 0000000000000000000000000000000000000000..6bf68a3ab4ffbdc4554514370daadea982b64a56 --- /dev/null +++ b/src/bilib/src/imageware/Builder.java @@ -0,0 +1,732 @@ +package imageware; + +import ij.ImagePlus; +import ij.ImageStack; +import ij.WindowManager; +import ij.process.ByteProcessor; +import ij.process.FloatProcessor; +import ij.process.ImageProcessor; +import ij.process.ShortProcessor; + +import java.awt.Image; + +/** + * Class Builder. + * + * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de + * Lausanne, Lausanne, Switzerland + */ + +public class Builder { + + /** + * Wrap a imageware of from the focused image of ImageJ. + */ + public static ImageWare wrapOnFocus() { + ImagePlus imp = WindowManager.getCurrentImage(); + return wrap(imp.getStack()); + } + + /** + * Wrap a imageware around a ImagePlus object. + * + * @param imp + * an ImagePlus object to wrap + */ + public static ImageWare wrap(ImagePlus imp) { + return wrap(imp.getStack()); + } + + /** + * Wrap a imageware around a ImageStack object. + * + * @param stack + * an ImageStack object to wrap + */ + public static ImageWare wrap(ImageStack stack) { + if (stack == null) + throw_null(); + ImageProcessor ip = stack.getProcessor(1); + if (ip instanceof ByteProcessor) { + return new ByteSet(stack, ImageWare.WRAP); + } + else if (ip instanceof ShortProcessor) { + return new ShortSet(stack, ImageWare.WRAP); + } + else if (ip instanceof FloatProcessor) { + return new FloatSet(stack, ImageWare.WRAP); + } + else { + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to wrap this ImageStack object.\n" + + "Support only the 8-bit, 16-bit and 32-bits type.\n" + "-------------------------------------------------------\n"); + } + } + + /** + * Create an empty imageware of a specified type. + * + * @param nx + * size in X axis + * @param ny + * size in Y axis + * @param nz + * size in Z axis + * @param type + * type of the imageware + */ + public static ImageWare create(int nx, int ny, int nz, int type) { + switch (type) { + case ImageWare.BYTE: + return new ByteSet(nx, ny, nz); + case ImageWare.SHORT: + return new ShortSet(nx, ny, nz); + case ImageWare.FLOAT: + return new FloatSet(nx, ny, nz); + case ImageWare.DOUBLE: + return new DoubleSet(nx, ny, nz); + default: + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + ".\n" + + "-------------------------------------------------------\n"); + } + } + + /** + * Create a imageware of from an Java AWT Image. + * + * @param image + * an Java AWT Image object + */ + public static ImageWare create(Image image) { + if (image == null) + throw_null(); + return new ByteSet(image, ImageWare.CREATE); + } + + /** + * Create a imageware of from the focussed image of ImageJ. + */ + public static ImageWare createOnFocus() { + return create(WindowManager.getCurrentImage()); + } + + /** + * Create a imageware of from an ImageStack. + * + * @param stack + * an ImageStack object + */ + public static ImageWare create(ImageStack stack) { + if (stack == null) + throw_null(); + ImageWare wrapped = wrap(stack); + return wrapped.duplicate(); + } + + /** + * Create a imageware of from an ImagePlus. + * + * @param imp + * an ImagePlus object + */ + public static ImageWare create(ImagePlus imp) { + if (imp == null) + throw_null(); + ImageWare wrapped = wrap(imp); + return wrapped.duplicate(); + } + + /** + * Create an array of 3 datasets from an ImagePlus. + * + * @param imp + * an ImagePlus object + */ + public static ImageWare[] createColors(ImagePlus imp) { + if (imp == null) + throw_null(); + return createColors(imp.getStack()); + } + + /** + * Create an array of 3 imageware from an ImageStack. + * + * @param stack + * an ImageStack object + */ + public static ImageWare[] createColors(ImageStack stack) { + if (stack == null) + throw_null(); + ImageWare color[] = new ImageWare[3]; + color[0] = new ByteSet(stack, ImageWare.RED); + color[1] = new ByteSet(stack, ImageWare.GREEN); + color[2] = new ByteSet(stack, ImageWare.BLUE); + return color; + } + + /** + * Create a imageware of a specific channel if the ImagePlus is a color + * image. + * + * @param imp + * an ImagePlus object + */ + public static ImageWare createColorChannel(ImagePlus imp, byte channel) { + if (imp == null) + throw_null(); + return createColorChannel(imp.getStack(), channel); + } + + /** + * Create a imageware of a specific channel if the ImageStack is a color + * image. + * + * @param stack + * an ImageStack object + */ + public static ImageWare createColorChannel(ImageStack stack, byte channel) { + if (stack == null) + throw_null(); + return new ByteSet(stack, channel); + } + + /** + * Create a imageware of from an array. + * + * @param object + * byte 1D array + */ + public static ImageWare create(byte[] object) { + if (object == null) + throw_null(); + return new ByteSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * short 1D array + */ + public static ImageWare create(short[] object) { + if (object == null) + throw_null(); + return new ShortSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * float 1D array + */ + public static ImageWare create(float[] object) { + if (object == null) + throw_null(); + return new FloatSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * double 1D array + */ + public static ImageWare create(double[] object) { + if (object == null) + throw_null(); + return new DoubleSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * byte 2D array + */ + public static ImageWare create(byte[][] object) { + if (object == null) + throw_null(); + return new ByteSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * short 2D array + */ + public static ImageWare create(short[][] object) { + if (object == null) + throw_null(); + return new ByteSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * float 2D array + */ + public static ImageWare create(float[][] object) { + if (object == null) + throw_null(); + return new FloatSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * double 2D array + */ + public static ImageWare create(double[][] object) { + if (object == null) + throw_null(); + return new DoubleSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * byte 3D array + */ + public static ImageWare create(byte[][][] object) { + if (object == null) + throw_null(); + return new ByteSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * short 3D array + */ + public static ImageWare create(short[][][] object) { + if (object == null) + throw_null(); + return new ShortSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * float 3D array + */ + public static ImageWare create(float[][][] object) { + if (object == null) + throw_null(); + return new FloatSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of from an array. + * + * @param object + * double 3D array + */ + public static ImageWare create(double[][][] object) { + if (object == null) + throw_null(); + return new DoubleSet(object, ImageWare.CREATE); + } + + /** + * Create a imageware of a specified type from an Java AWT Image object. + * + * @param image + * an Java AWT Image object + * @param type + * type of the imageware + */ + public static ImageWare create(Image image, int type) { + if (image == null) + throw_null(); + switch (type) { + case ImageWare.BYTE: + return new ByteSet(image, ImageWare.CREATE); + case ImageWare.SHORT: + return new ShortSet(image, ImageWare.CREATE); + case ImageWare.FLOAT: + return new FloatSet(image, ImageWare.CREATE); + case ImageWare.DOUBLE: + return new DoubleSet(image, ImageWare.CREATE); + default: + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + ".\n" + + "-------------------------------------------------------\n"); + } + } + + /** + * Create a imageware of from the focused image of ImageJ. + * + * @param type + * type of the imageware + */ + public static ImageWare createOnFocus(int type) { + return create(WindowManager.getCurrentImage(), type); + } + + /** + * Create a imageware of a specified type from an ImagePlus object. + * + * @param imp + * an ImagePlus object + * @param type + * type of the imageware + */ + public static ImageWare create(ImagePlus imp, int type) { + if (imp == null) + throw_null(); + switch (type) { + case ImageWare.BYTE: + return new ByteSet(imp.getStack(), ImageWare.CREATE); + case ImageWare.SHORT: + return new ShortSet(imp.getStack(), ImageWare.CREATE); + case ImageWare.FLOAT: + return new FloatSet(imp.getStack(), ImageWare.CREATE); + case ImageWare.DOUBLE: + return new DoubleSet(imp.getStack(), ImageWare.CREATE); + default: + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + ".\n" + + "-------------------------------------------------------\n"); + } + } + + /** + * Create a imageware of a specified type from an ImageStack object. + * + * @param object + * an ImageStack object + * @param type + * type of the imageware + */ + public static ImageWare create(ImageStack object, int type) { + if (object == null) + throw_null(); + ImageWare wrapped = wrap(object); + return wrapped.convert(type); + } + + /** + * Create an array of 3 datasets from an ImagePlus. + * + * @param imp + * an ImagePlus object + * @param type + * type of the imageware + */ + public static ImageWare[] createColor(ImagePlus imp, int type) { + if (imp == null) + throw_null(); + return createColor(imp.getStack(), type); + } + + /** + * Create an array of 3 imageware from an ColorProcessor. + * + * @param stack + * an ColorProcessor object + * @param type + * type of the imageware + */ + public static ImageWare[] createColor(ImageStack stack, int type) { + if (stack == null) + throw_null(); + ImageWare color[] = new ImageWare[3]; + switch (type) { + case ImageWare.BYTE: + color[0] = new ByteSet(stack, ImageWare.RED); + color[1] = new ByteSet(stack, ImageWare.GREEN); + color[2] = new ByteSet(stack, ImageWare.BLUE); + break; + case ImageWare.SHORT: + color[0] = new ShortSet(stack, ImageWare.RED); + color[1] = new ShortSet(stack, ImageWare.GREEN); + color[2] = new ShortSet(stack, ImageWare.BLUE); + break; + case ImageWare.FLOAT: + color[0] = new FloatSet(stack, ImageWare.RED); + color[1] = new FloatSet(stack, ImageWare.GREEN); + color[2] = new FloatSet(stack, ImageWare.BLUE); + break; + case ImageWare.DOUBLE: + color[0] = new DoubleSet(stack, ImageWare.RED); + color[1] = new DoubleSet(stack, ImageWare.GREEN); + color[2] = new DoubleSet(stack, ImageWare.BLUE); + break; + default: + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + ".\n" + + "-------------------------------------------------------\n"); + } + return color; + } + + /** + * Create a imageware of a specific channel if the ImagePlus is a color + * image. + * + * @param imp + * an ImagePlus object + */ + public static ImageWare createColorChannel(ImagePlus imp, byte channel, int type) { + if (imp == null) + throw_null(); + return createColorChannel(imp.getStack(), channel, type); + } + + /** + * Create a imageware of a specific channel if the ImageStack is a color + * image. + * + * @param stack + * an ImageStack object + */ + public static ImageWare createColorChannel(ImageStack stack, byte channel, int type) { + if (stack == null) + throw_null(); + ImageWare out = null; + switch (type) { + case ImageWare.BYTE: + out = new ByteSet(stack, channel); + break; + case ImageWare.SHORT: + out = new ShortSet(stack, channel); + break; + case ImageWare.FLOAT: + out = new FloatSet(stack, channel); + break; + case ImageWare.DOUBLE: + out = new DoubleSet(stack, channel); + break; + default: + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + ".\n" + + "-------------------------------------------------------\n"); + } + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * byte 1D array + * @param type + * type of the imageware + */ + public static ImageWare create(byte[] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, 1, 1, type); + out.putX(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * short 1D array + * @param type + * type of the imageware + */ + public static ImageWare create(short[] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, 1, 1, type); + out.putX(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * float 1D array + * @param type + * type of the imageware + */ + public static ImageWare create(float[] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, 1, 1, type); + out.putX(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * double 1D array + * @param type + * type of the imageware + */ + public static ImageWare create(double[] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, 1, 1, type); + out.putX(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * byte 2D array + * @param type + * type of the imageware + */ + public static ImageWare create(byte[][] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, object[0].length, 1, type); + out.putXY(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * short 2D array + * @param type + * type of the imageware + */ + public static ImageWare create(short[][] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, object[0].length, 1, type); + out.putXY(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * float 2D array + * @param type + * type of the imageware + */ + public static ImageWare create(float[][] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, object[0].length, 1, type); + out.putXY(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * double 2D array + * @param type + * type of the imageware + */ + public static ImageWare create(double[][] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, object[0].length, 1, type); + out.putXY(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * byte 3D array + * @param type + * type of the imageware + */ + public static ImageWare create(byte[][][] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, object[0].length, object[0][0].length, type); + out.putXYZ(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * short 3D array + * @param type + * type of the imageware + */ + public static ImageWare create(short[][][] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, object[0].length, object[0][0].length, type); + out.putXYZ(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * float 3D array + * @param type + * type of the imageware + */ + public static ImageWare create(float[][][] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, object[0].length, object[0][0].length, type); + out.putXYZ(0, 0, 0, object); + return out; + } + + /** + * Create a imageware of a specified type from an array. + * + * @param object + * double 3D array + * @param type + * type of the imageware + */ + public static ImageWare create(double[][][] object, int type) { + if (object == null) + throw_null(); + ImageWare out = createType(object.length, object[0].length, object[0][0].length, type); + out.putXYZ(0, 0, 0, object); + return out; + } + + /** + */ + private static ImageWare createType(int nx, int ny, int nz, int type) { + ImageWare out = null; + switch (type) { + case ImageWare.BYTE: + out = new ByteSet(nx, ny, nz); + break; + case ImageWare.SHORT: + out = new ShortSet(nx, ny, nz); + break; + case ImageWare.FLOAT: + out = new FloatSet(nx, ny, nz); + break; + case ImageWare.DOUBLE: + out = new DoubleSet(nx, ny, nz); + break; + default: + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create this object.\n" + + "-------------------------------------------------------\n"); + } + return out; + } + + private static void throw_null() { + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to wrap the ImagePlus.\n" + + "The object parameter is null.\n" + "-------------------------------------------------------\n"); + } + +} diff --git a/src/bilib/src/imageware/ByteAccess.java b/src/bilib/src/imageware/ByteAccess.java new file mode 100644 index 0000000000000000000000000000000000000000..888b0d0c76b5f52539853ef60512220825a5162a --- /dev/null +++ b/src/bilib/src/imageware/ByteAccess.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class ByteAccess. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class ByteAccess extends ByteBuffer implements Access { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected ByteAccess(int nx, int ny, int nz) { super(nx, ny, nz); } protected ByteAccess(Image image, int mode) { super(image, mode); } protected ByteAccess(ImageStack stack, int mode) { super(stack, mode); } protected ByteAccess(ImageStack stack, byte chan) { super(stack, chan); } protected ByteAccess(byte[] array, int mode) { super(array, mode); } protected ByteAccess(byte[][] array, int mode) { super(array, mode); } protected ByteAccess(byte[][][] array, int mode) { super(array, mode); } protected ByteAccess(short[] array, int mode) { super(array, mode); } protected ByteAccess(short[][] array, int mode) { super(array, mode); } protected ByteAccess(short[][][] array, int mode) { super(array, mode); } protected ByteAccess(float[] array, int mode) { super(array, mode); } protected ByteAccess(float[][] array, int mode) { super(array, mode); } protected ByteAccess(float[][][] array, int mode) { super(array, mode); } protected ByteAccess(double[] array, int mode) { super(array, mode); } protected ByteAccess(double[][] array, int mode) { super(array, mode); } protected ByteAccess(double[][][] array, int mode) { super(array, mode); } // ------------------------------------------------------------------ // // getPixel section // // ------------------------------------------------------------------ /** * Get a pixel at specific position without specific boundary conditions * * If the positions is outside of this imageware, the method return 0.0. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a pixel value */ public double getPixel(int x, int y, int z) { if (x >= nx) return 0.0; if (y >= ny) return 0.0; if (z >= nz) return 0.0; if (x < 0) return 0.0; if (y < 0) return 0.0; if (z < 0) return 0.0; return ((byte[]) data[z])[x + y * nx] & 0xFF; } /** * Get a pixel at specific position with specific boundary conditions * * If the positions is outside of this imageware, the method apply the * boundary conditions to return a value. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a pixel value */ public double getPixel(int x, int y, int z, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to put a pixel \n" + "at the position (" + x + "," + y + "," + z + ".\n" + "-------------------------------------------------------\n"); } int xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } return ((byte[]) data[zp])[xp + yp * nx] & 0xFF; } /** * Get a interpolated pixel value at specific position without specific * boundary conditions. * * If the positions is not on the pixel grid, the method return a * interpolated value of the pixel (linear interpolation). If the positions * is outside of this imageware, the method return 0.0. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a interpolated value */ public double getInterpolatedPixel(double x, double y, double z) { if (x > nx - 1) return 0.0; if (y > ny - 1) return 0.0; if (z > nz - 1) return 0.0; if (x < 0) return 0.0; if (y < 0) return 0.0; if (z < 0) return 0.0; double output = 0.0; /* * int i = (x >= 0.0 ? ((int)x) : ((int)x - 1)); int j = (y >= 0.0 ? * ((int)y) : ((int)y - 1)); int k = (z >= 0.0 ? ((int)z) : ((int)z - * 1)); */ int i = (x >= 0.0 ? ((int) x) : ((int) x - 1)); int j = (y >= 0.0 ? ((int) y) : ((int) y - 1)); int k = (z >= 0.0 ? ((int) z) : ((int) z - 1)); boolean fi = (i == nx - 1); boolean fj = (j == ny - 1); boolean fk = (k == nz - 1); int index = i + j * nx; switch (getDimension()) { case 1: double v1_0 = (double) (((byte[]) data[k])[index] & 0xFF); double v1_1 = (fi ? v1_0 : (double) (((byte[]) data[k])[index + 1] & 0xFF)); double dx1 = x - (double) i; return v1_1 * dx1 - v1_0 * (dx1 - 1.0); case 2: double v2_00 = (double) (((byte[]) data[k])[index] & 0xFF); double v2_10 = (fi ? v2_00 : (double) (((byte[]) data[k])[index + 1] & 0xFF)); double v2_01 = (fj ? v2_00 : (double) (((byte[]) data[k])[index + nx] & 0xFF)); double v2_11 = (fi ? (fj ? v2_00 : v2_01) : (double) (((byte[]) data[k])[index + 1 + nx] & 0xFF)); double dx2 = x - (double) i; double dy2 = y - (double) j; return (dx2 * (v2_11 * dy2 - v2_10 * (dy2 - 1.0)) - (dx2 - 1.0) * (v2_01 * dy2 - v2_00 * (dy2 - 1.0))); case 3: double v3_000 = (double) (((byte[]) data[k])[index] & 0xFF); double v3_100 = (fi ? v3_000 : (double) (((byte[]) data[k])[index + 1] & 0xFF)); double v3_010 = (fj ? v3_000 : (double) (((byte[]) data[k])[index + nx] & 0xFF)); double v3_110 = (fi ? (fj ? v3_000 : v3_010) : (double) (((byte[]) data[k])[index + 1 + nx] & 0xFF)); double v3_001 = (fk ? v3_000 : (double) (((byte[]) data[k + 1])[index] & 0xFF)); double v3_011 = (fk ? (fj ? v3_000 : v3_010) : (double) (((byte[]) data[k + 1])[index + 1] & 0xFF)); double v3_101 = (fk ? (fi ? v3_000 : v3_100) : (double) (((byte[]) data[k + 1])[index + nx] & 0xFF)); double v3_111 = (fk ? (fj ? (fi ? v3_000 : v3_100) : v3_110) : (double) (((byte[]) data[k + 1])[index + 1 + nx] & 0xFF)); double dx3 = x - (double) i; double dy3 = y - (double) j; double dz3 = z - (double) k; double z1 = (dx3 * (v3_110 * dy3 - v3_100 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_010 * dy3 - v3_000 * (dy3 - 1.0))); double z2 = (dx3 * (v3_111 * dy3 - v3_101 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_011 * dy3 - v3_001 * (dy3 - 1.0))); return z2 * dz3 - z1 * (dz3 - 1.0); } return output; } /** * Get a interpolated pixel value at specific position with specific * boundary conditions. * * If the positions is not on the pixel grid, the method return a * interpolated value of the pixel (linear interpolation). If the positions * is outside of this imageware, the method apply the boundary conditions to * return a value. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @param boundaryConditions * MIRROR or PERIODIC boundary conditions * @return a interpolated value */ public double getInterpolatedPixel(double x, double y, double z, byte boundaryConditions) { double output = 0.0; int i = (x >= 0.0 ? ((int) x) : ((int) x - 1)); int j = (y >= 0.0 ? ((int) y) : ((int) y - 1)); int k = (z >= 0.0 ? ((int) z) : ((int) z - 1)); switch (getDimension()) { case 1: double v1_0 = getPixel(i, j, k, boundaryConditions); double v1_1 = getPixel(i + 1, j, k, boundaryConditions); double dx1 = x - (double) i; return v1_1 * dx1 - v1_0 * (dx1 - 1.0); case 2: double v2_00 = getPixel(i, j, k, boundaryConditions); double v2_10 = getPixel(i + 1, j, k, boundaryConditions); double v2_01 = getPixel(i, j + 1, k, boundaryConditions); double v2_11 = getPixel(i + 1, j + 1, k, boundaryConditions); double dx2 = x - (double) i; double dy2 = y - (double) j; return (dx2 * (v2_11 * dy2 - v2_10 * (dy2 - 1.0)) - (dx2 - 1.0) * (v2_01 * dy2 - v2_00 * (dy2 - 1.0))); case 3: double v3_000 = getPixel(i, j, k, boundaryConditions); double v3_100 = getPixel(i + 1, j, k, boundaryConditions); double v3_010 = getPixel(i, j + 1, k, boundaryConditions); double v3_110 = getPixel(i + 1, j + 1, k, boundaryConditions); double v3_001 = getPixel(i, j, k + 1, boundaryConditions); double v3_011 = getPixel(i + 1, j, k + 1, boundaryConditions); double v3_101 = getPixel(i, j + 1, k + 1, boundaryConditions); double v3_111 = getPixel(i + 1, j + 1, k + 1, boundaryConditions); double dx3 = x - (double) i; double dy3 = y - (double) j; double dz3 = z - (double) k; double z1 = (dx3 * (v3_110 * dy3 - v3_100 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_010 * dy3 - v3_000 * (dy3 - 1.0))); double z2 = (dx3 * (v3_111 * dy3 - v3_101 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_011 * dy3 - v3_001 * (dy3 - 1.0))); return z2 * dz3 - z1 * (dz3 - 1.0); } return output; } // ------------------------------------------------------------------ // // putPixel section // // ------------------------------------------------------------------ /** * Put a pixel at specific position * * If the positions is outside of this imageware, the method does nothing. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis */ public void putPixel(int x, int y, int z, double value) { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; if (x < 0) return; if (y < 0) return; if (z < 0) return; ((byte[]) data[z])[x + y * nx] = (byte) value; } // ------------------------------------------------------------------ // // getBounded section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (tmp[offset] & 0xFF); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (short) (tmp[offset] & 0xFF); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (float) (tmp[offset] & 0xFF); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (double) (tmp[offset] & 0xFF); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (tmp[offset] & 0xFF); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (short) (tmp[offset] & 0xFF); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (float) (tmp[offset] & 0xFF); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (double) (tmp[offset] & 0xFF); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (((byte[]) data[k])[offset] & 0xFF); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (short) (((byte[]) data[k])[offset] & 0xFF); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (float) (((byte[]) data[k])[offset] & 0xFF); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (double) (((byte[]) data[k])[offset] & 0xFF); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); byte[] tmp = (byte[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (tmp[offset] & 0xFF); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); byte[] tmp = (byte[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (tmp[offset] & 0xFF); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); byte[] tmp = (byte[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (tmp[offset] & 0xFF); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); byte[] tmp = (byte[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (tmp[offset] & 0xFF); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (((byte[]) data[z])[offset] & 0xFF); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (((byte[]) data[z])[offset] & 0xFF); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (((byte[]) data[z])[offset] & 0xFF); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (((byte[]) data[z])[offset] & 0xFF); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (((byte[]) data[z])[offset] & 0xFF); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (((byte[]) data[z])[offset] & 0xFF); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (((byte[]) data[z])[offset] & 0xFF); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (((byte[]) data[z])[offset] & 0xFF); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, byte[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { byte[] tmp = (byte[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (byte) (tmp[offset] & 0xFF); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, short[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { byte[] tmp = (byte[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (short) (tmp[offset] & 0xFF); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, float[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { byte[] tmp = (byte[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (float) (tmp[offset] & 0xFF); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, double[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { byte[] tmp = (byte[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (double) (tmp[offset] & 0xFF); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } // ------------------------------------------------------------------ // // getBlock section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; byte[] tmp = (byte[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (byte) (tmp[xp + yp] & 0xFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; byte[] tmp = (byte[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (short) (tmp[xp + yp] & 0xFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; byte[] tmp = (byte[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (float) (tmp[xp + yp] & 0xFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; byte[] tmp = (byte[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (double) (tmp[xp + yp] & 0xFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } byte[] tmp = (byte[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (byte) (tmp[xp + yp * nx] & 0xFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } byte[] tmp = (byte[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (short) (tmp[xp + yp * nx] & 0xFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } byte[] tmp = (byte[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (float) (tmp[xp + yp * nx] & 0xFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } byte[] tmp = (byte[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (double) (tmp[xp + yp * nx] & 0xFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (byte) (((byte[]) data[zp])[xyp] & 0xFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (short) (((byte[]) data[zp])[xyp] & 0xFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (float) (((byte[]) data[zp])[xyp] & 0xFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (double) (((byte[]) data[zp])[xyp] & 0xFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = (byte[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (tmp[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = (byte[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (tmp[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = (byte[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (tmp[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = (byte[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (tmp[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (((byte[]) data[zp])[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (((byte[]) data[zp])[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (((byte[]) data[zp])[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (((byte[]) data[zp])[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (byte) (((byte[]) data[zp])[xp + yp * nx] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (short) (((byte[]) data[zp])[xp + yp * nx] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (float) (((byte[]) data[zp])[xp + yp * nx] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (double) (((byte[]) data[zp])[xp + yp * nx] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = (byte[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (byte) (tmp[xp + yp] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = (byte[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (short) (tmp[xp + yp] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = (byte[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (float) (tmp[xp + yp] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = (byte[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (double) (tmp[xp + yp] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } // ------------------------------------------------------------------ // // getBlock section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; byte[] tmp = ((byte[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (byte) (tmp[xp + yp] & 0xFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; byte[] tmp = ((byte[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (short) (tmp[xp + yp] & 0xFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; byte[] tmp = ((byte[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (float) (tmp[xp + yp] & 0xFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; byte[] tmp = ((byte[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (double) (tmp[xp + yp] & 0xFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; byte[] tmp = ((byte[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (byte) (tmp[xp + yp * nx] & 0xFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; byte[] tmp = ((byte[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (short) (tmp[xp + yp * nx] & 0xFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; byte[] tmp = ((byte[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (float) (tmp[xp + yp * nx] & 0xFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; byte[] tmp = ((byte[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (double) (tmp[xp + yp * nx] & 0xFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (byte) (((byte[]) data[zp])[xyp] & 0xFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (short) (((byte[]) data[zp])[xyp] & 0xFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (float) (((byte[]) data[zp])[xyp] & 0xFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (double) (((byte[]) data[zp])[xyp] & 0xFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; byte[] tmp = ((byte[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (tmp[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; byte[] tmp = ((byte[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (tmp[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; byte[] tmp = ((byte[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (tmp[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; byte[] tmp = ((byte[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (tmp[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (((byte[]) data[zp])[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (((byte[]) data[zp])[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (((byte[]) data[zp])[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (((byte[]) data[zp])[xp + yp] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (byte) (((byte[]) data[zp])[xp + yp * nx] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (short) (((byte[]) data[zp])[xp + yp * nx] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (float) (((byte[]) data[zp])[xp + yp * nx] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (double) (((byte[]) data[zp])[xp + yp * nx] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = ((byte[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (byte) (tmp[xp + yp] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = ((byte[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (short) (tmp[xp + yp] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = ((byte[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (float) (tmp[xp + yp] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } byte[] tmp = ((byte[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (double) (tmp[xp + yp] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } // ------------------------------------------------------------------ // // putBounded section // // ------------------------------------------------------------------ /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i] & 0xFF); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i] & 0xFFFF); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i] & 0xFF); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); byte[] tmp = (byte[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i] & 0xFF); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i] & 0xFFFF); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i]); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i]); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); byte[] tmp = (byte[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i][j] & 0xFF); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); byte[] tmp = (byte[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i][j] & 0xFFFF); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); byte[] tmp = (byte[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i][j]); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); byte[] tmp = (byte[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i][j]); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i][j] & 0xFF); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i][j] & 0xFFFF); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i][j]); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i][j]); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i][j] & 0xFF); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i][j] & 0xFFFF); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i][j]); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((byte[]) data[k])[offset] = (byte) (buffer[i][j]); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, byte[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { byte[] tmp = (byte[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i][j][k] & 0xFF); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, short[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { byte[] tmp = (byte[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i][j][k] & 0xFFFF); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, float[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { byte[] tmp = (byte[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i][j][k]); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, double[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { byte[] tmp = (byte[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (byte) (buffer[i][j][k]); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/ByteBuffer.java b/src/bilib/src/imageware/ByteBuffer.java new file mode 100644 index 0000000000000000000000000000000000000000..e9d7a5eaf6eabe18abf115e2b5c49f23024d563b --- /dev/null +++ b/src/bilib/src/imageware/ByteBuffer.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import ij.process.ByteProcessor; import ij.process.ColorProcessor; import ij.process.FloatProcessor; import ij.process.ImageProcessor; import ij.process.ShortProcessor; import java.awt.Image; import java.awt.image.ImageObserver; import java.awt.image.PixelGrabber; /** * Class ByteBuffer. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class ByteBuffer implements Buffer { protected Object[] data = null; protected int nx = 0; protected int ny = 0; protected int nz = 0; protected int nxy = 0; /** * Constructor of a empty 3D byte buffer. * * @param nx * size of the 3D buffer in the X axis * @param ny * size of the 3D buffer in the Y axis * @param nz * size of the 3D buffer in the Z axis */ protected ByteBuffer(int nx, int ny, int nz) { this.nx = nx; this.ny = ny; this.nz = nz; if (nx <= 0 || ny <= 0 || nz <= 0) throw_constructor(nx, ny, nz); allocate(); } /** * Constructor of a byte buffer from a object Image of Java. * * @param image * source to build a new imageware */ protected ByteBuffer(Image image, int mode) { if (image == null) { throw_constructor(); } ImageObserver observer = null; this.nx = image.getWidth(observer); this.ny = image.getHeight(observer); this.nz = 1; this.nxy = nx * ny; byte[] pixels = new byte[nxy]; PixelGrabber pg = new PixelGrabber(image, 0, 0, nx, ny, false); try { pg.grabPixels(); pixels = (byte[]) (pg.getPixels()); } catch (Exception e) { throw_constructor(); } allocate(); for (int k = 0; k < nxy; k++) ((byte[]) data[0])[k] = (byte) (pixels[k] & 0xFF); } /** * Constructor of a byte buffer from a ImageStack. * * New data are allocated if the mode is CREATE, the imageware use the data * of ImageJ if the mode is WRAP. * * @param stack * source to build a new imageware * @param mode * WRAP or CREATE */ protected ByteBuffer(ImageStack stack, int mode) { if (stack == null) { throw_constructor(); } this.nx = stack.getWidth(); this.ny = stack.getHeight(); this.nz = stack.getSize(); this.nxy = nx * ny; switch (mode) { case ImageWare.WRAP: this.data = stack.getImageArray(); break; case ImageWare.CREATE: allocate(); ImageProcessor ip = stack.getProcessor(1); if (ip instanceof ByteProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { byte[] slice = (byte[]) vol[z]; for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] = (byte) (slice[k] & 0xFF); } } } else if (ip instanceof ShortProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { short[] slice = (short[]) vol[z]; for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] = (byte) (slice[k] & 0xFFFF); } } } else if (ip instanceof FloatProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { float[] slice = (float[]) vol[z]; for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] = (byte) slice[k]; } } } else if (ip instanceof ColorProcessor) { double r, g, b; int c; ColorProcessor cp; int[] pixels; for (int z = 0; z < nz; z++) { cp = (ColorProcessor) stack.getProcessor(z + 1); pixels = (int[]) cp.getPixels(); for (int k = 0; k < nxy; k++) { c = pixels[k]; r = (double) ((c & 0xFF0000) >> 16); g = (double) ((c & 0xFF00) >> 8); b = (double) ((c & 0xFF)); ((byte[]) data[z])[k] = (byte) ((r + g + b) / 3.0); } } } else { throw_constructor(); } break; default: throw_constructor(); break; } } /** * Constructor of a byte buffer from a specific color channel of ImageStack. * * New data are always allocated. If it is a gray image the imageware is * created and fill up with data of the source ImageStack. If it is a color * image only the selected channel is used to create this imageware. * * @param stack * source to build a new imageware * @param channel * RED, GREEN or BLUE */ protected ByteBuffer(ImageStack stack, byte channel) { if (stack == null) { throw_constructor(); } this.nx = stack.getWidth(); this.ny = stack.getHeight(); this.nz = stack.getSize(); this.nxy = nx * ny; allocate(); ImageProcessor ip = stack.getProcessor(1); if (ip instanceof ByteProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { byte[] slice = (byte[]) vol[z]; for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] = (byte) (slice[k] & 0xFF); } } } else if (ip instanceof ShortProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { short[] slice = (short[]) vol[z]; for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] = (byte) (slice[k] & 0xFFFF); } } } else if (ip instanceof FloatProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { float[] slice = (float[]) vol[z]; for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] = (byte) slice[k]; } } } else if (ip instanceof ColorProcessor) { ColorProcessor cp; int[] pixels; for (int z = 0; z < nz; z++) { cp = (ColorProcessor) stack.getProcessor(z + 1); pixels = (int[]) cp.getPixels(); switch (channel) { case ImageWare.RED: for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] = (byte) ((pixels[k] & 0xFF0000) >> 16); } break; case ImageWare.GREEN: for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] = (byte) ((pixels[k] & 0xFF00) >> 8); } break; case ImageWare.BLUE: for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] = (byte) (pixels[k] & 0xFF); } break; default: throw_constructor(); } } } else { throw_constructor(); } } /** * Constructor of a byte buffer from a byte array. * * @param array * source to build this new imageware */ protected ByteBuffer(byte[] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = 1; this.nz = 1; allocate(); putX(0, 0, 0, array); } /** * Constructor of a byte buffer from a byte array. * * @param array * source to build this new imageware */ protected ByteBuffer(byte[][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = 1; allocate(); putXY(0, 0, 0, array); } /** * Constructor of a byte buffer from a byte array. * * @param array * source to build this new imageware */ protected ByteBuffer(byte[][][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = array[0][0].length; allocate(); putXYZ(0, 0, 0, array); } /** * Constructor of a byte buffer from a short array. * * @param array * source to build this new imageware */ protected ByteBuffer(short[] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = 1; this.nz = 1; allocate(); putX(0, 0, 0, array); } /** * Constructor of a byte buffer from a short array. * * @param array * source to build this new imageware */ protected ByteBuffer(short[][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = 1; allocate(); putXY(0, 0, 0, array); } /** * Constructor of a byte buffer from a short array. * * @param array * source to build this new imageware */ protected ByteBuffer(short[][][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = array[0][0].length; allocate(); putXYZ(0, 0, 0, array); } /** * Constructor of a byte buffer from a float array. * * @param array * source to build this new imageware */ protected ByteBuffer(float[] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = 1; this.nz = 1; allocate(); putX(0, 0, 0, array); } /** * Constructor of a byte buffer from a float array. * * @param array * source to build this new imageware */ protected ByteBuffer(float[][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = 1; allocate(); putXY(0, 0, 0, array); } /** * Constructor of a byte buffer from a float array. * * @param array * source to build this new imageware */ protected ByteBuffer(float[][][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = array[0][0].length; allocate(); putXYZ(0, 0, 0, array); } /** * Constructor of a byte buffer from a double array. * * @param array * source to build this new imageware */ protected ByteBuffer(double[] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = 1; this.nz = 1; allocate(); putX(0, 0, 0, array); } /** * Constructor of a byte buffer from a double array. * * @param array * source to build this new imageware */ protected ByteBuffer(double[][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = 1; allocate(); putXY(0, 0, 0, array); } /** * Constructor of a byte buffer from a double array. * * @param array * source to build this new imageware */ protected ByteBuffer(double[][][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = array[0][0].length; allocate(); putXYZ(0, 0, 0, array); } /** * Return the type of this imageware. * * @return the type of this imageware */ public int getType() { return ImageWare.BYTE; } /** * Return the type of this imageware in a string format. * * @return the type of this imageware translated in a string format */ public String getTypeToString() { return "Byte"; } /** * Return the number of dimension of this imageware (1, 2 or 3). * * @return the number of dimension of this imageware */ public int getDimension() { int dims = 0; dims += (nx > 1 ? 1 : 0); dims += (ny > 1 ? 1 : 0); dims += (nz > 1 ? 1 : 0); return dims; } /** * Return the size of the imageware int[0] : x, int[1] : y, int[2] : z. * * @return an array given the size of the imageware */ public int[] getSize() { int[] size = { nx, ny, nz }; return size; } /** * Return the size in the X axis. * * @return the size in the X axis */ public int getSizeX() { return nx; } /** * Return the size in the Y axis. * * @return the size in the Y axis */ public int getSizeY() { return ny; } /** * Return the size in the Z axis. * * @return the size in the Z axis */ public int getSizeZ() { return nz; } /** * Return the size in the X axis. * * @return the size in the X axis */ public int getWidth() { return nx; } /** * Return the size in the Y axis. * * @return the size in the Y axis */ public int getHeight() { return ny; } /** * Return the size in the Z axis. * * @return the size in the Z axis */ public int getDepth() { return nz; } /** * Return the number of pixels in the imageware. * * @return number of pixels in the imageware */ public int getTotalSize() { return nxy * nz; } /** * Return true is this imageware has the same size the imageware given as * parameter. * * @param imageware * imageware to be compared * @return true if the imageware of the same size than this imageware */ public boolean isSameSize(ImageWare imageware) { if (nx != imageware.getSizeX()) return false; if (ny != imageware.getSizeY()) return false; if (nz != imageware.getSizeZ()) return false; return true; } // ------------------------------------------------------------------ // // put Section // // ------------------------------------------------------------------ /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putX(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); double buf[] = new double[bnx]; buffer.getX(0, 0, 0, buf); putX(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putY(int x, int y, int z, ImageWare buffer) { int bny = buffer.getSizeY(); double buf[] = new double[bny]; buffer.getY(0, 0, 0, buf); putY(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putZ(int x, int y, int z, ImageWare buffer) { int bnz = buffer.getSizeZ(); double buf[] = new double[bnz]; buffer.getZ(0, 0, 0, buf); putZ(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putXY(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bny = buffer.getSizeY(); double buf[][] = new double[bnx][bny]; buffer.getXY(0, 0, 0, buf); putXY(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putXZ(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bnz = buffer.getSizeZ(); double buf[][] = new double[bnx][bnz]; buffer.getXZ(0, 0, 0, buf); putXZ(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putYZ(int x, int y, int z, ImageWare buffer) { int bny = buffer.getSizeY(); int bnz = buffer.getSizeZ(); double buf[][] = new double[bny][bnz]; buffer.getYZ(0, 0, 0, buf); putYZ(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putXYZ(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bny = buffer.getSizeY(); int bnz = buffer.getSizeZ(); double buf[][][] = new double[bnx][bny][bnz]; buffer.getXYZ(0, 0, 0, buf); putXYZ(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putX(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; System.arraycopy(buffer, 0, tmp, offset, leni); } catch (Exception e) { throw_put("X", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putX(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (byte) (buffer[i] & 0xFFFF); offset++; } } catch (Exception e) { throw_put("X", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putX(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (byte) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putX(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (byte) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putY(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (byte) (buffer[i] & 0xFF); offset += nx; } } catch (Exception e) { throw_put("Y", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putY(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (byte) (buffer[i] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_put("Y", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putY(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (byte) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putY(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (byte) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * bybytete 1D array to put into the imageware */ public void putZ(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { ((byte[]) data[z])[offset] = (byte) (buffer[i] & 0xFF); z++; } } catch (Exception e) { throw_put("Z", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byshortte 1D array to put into the imageware */ public void putZ(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { ((byte[]) data[z])[offset] = (byte) (buffer[i] & 0xFFFF); z++; } } catch (Exception e) { throw_put("Z", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byfloatte 1D array to put into the imageware */ public void putZ(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { ((byte[]) data[z])[offset] = (byte) (buffer[i]); z++; } } catch (Exception e) { throw_put("Z", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * bydoublete 1D array to put into the imageware */ public void putZ(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { ((byte[]) data[z])[offset] = (byte) (buffer[i]); z++; } } catch (Exception e) { throw_put("Z", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putXY(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (byte) (buffer[i][j] & 0xFF); } } } catch (Exception e) { throw_put("XY", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putXY(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (byte) (buffer[i][j] & 0xFFFF); } } } catch (Exception e) { throw_put("XY", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putXY(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (byte) (buffer[i][j]); } } } catch (Exception e) { throw_put("XY", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putXY(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (byte) (buffer[i][j]); } } } catch (Exception e) { throw_put("XY", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putXZ(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + j * nx; for (int i = 0; i < leni; i++, offset++) { ((byte[]) data[z])[offset] = (byte) (buffer[i][j] & 0xFF); } } } catch (Exception e) { throw_put("YZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putXZ(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + j * nx; for (int i = 0; i < leni; i++, offset++) { ((byte[]) data[z])[offset] = (byte) (buffer[i][j] & 0xFFFF); } } } catch (Exception e) { throw_put("YZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putXZ(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + j * nx; for (int i = 0; i < leni; i++, offset++) { ((byte[]) data[z])[offset] = (byte) (buffer[i][j]); } } } catch (Exception e) { throw_put("YZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putXZ(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + j * nx; for (int i = 0; i < leni; i++, offset++) { ((byte[]) data[z])[offset] = (byte) (buffer[i][j]); } } } catch (Exception e) { throw_put("YZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putYZ(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) for (int i = 0; i < leni; i++, offset += nx) { ((byte[]) data[z])[offset] = (byte) (buffer[i][j] & 0xFF); } } catch (Exception e) { throw_put("XZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putYZ(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) for (int i = 0; i < leni; i++, offset += nx) { ((byte[]) data[z])[offset] = (byte) (buffer[i][j] & 0xFFFF); } } catch (Exception e) { throw_put("XZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putYZ(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) for (int i = 0; i < leni; i++, offset += nx) { ((byte[]) data[z])[offset] = (byte) (buffer[i][j]); } } catch (Exception e) { throw_put("XZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putYZ(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) for (int i = 0; i < leni; i++, offset += nx) { ((byte[]) data[z])[offset] = (byte) (buffer[i][j]); } } catch (Exception e) { throw_put("XZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to put into the imageware */ public void putXYZ(int x, int y, int z, byte[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (byte) (buffer[i][j][k] & 0xFF); } } } } catch (Exception e) { throw_put("XYZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to put into the imageware */ public void putXYZ(int x, int y, int z, short[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (byte) (buffer[i][j][k] & 0xFFFF); } } } } catch (Exception e) { throw_put("XYZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to put into the imageware */ public void putXYZ(int x, int y, int z, float[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (byte) (buffer[i][j][k]); } } } } catch (Exception e) { throw_put("XYZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to put into the imageware */ public void putXYZ(int x, int y, int z, double[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (byte) (buffer[i][j][k]); } } } } catch (Exception e) { throw_put("XYZ", "No check", buffer, x, y, z); } } // ------------------------------------------------------------------ // // get Section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getX(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); double buf[] = new double[bnx]; getX(x, y, z, buf); buffer.putX(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getY(int x, int y, int z, ImageWare buffer) { int bny = buffer.getSizeY(); double buf[] = new double[bny]; getY(x, y, z, buf); buffer.putY(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getZ(int x, int y, int z, ImageWare buffer) { int bnz = buffer.getSizeZ(); double buf[] = new double[bnz]; getZ(x, y, z, buf); buffer.putZ(0, 0, 0, buf); } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getXY(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bny = buffer.getSizeY(); double buf[][] = new double[bnx][bny]; getXY(x, y, z, buf); buffer.putXY(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getXZ(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bnz = buffer.getSizeZ(); double buf[][] = new double[bnx][bnz]; getXZ(x, y, z, buf); buffer.putXZ(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the datase */ public void getYZ(int x, int y, int z, ImageWare buffer) { int bny = buffer.getSizeY(); int bnz = buffer.getSizeZ(); double buf[][] = new double[bny][bnz]; getYZ(x, y, z, buf); buffer.putYZ(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getXYZ(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bny = buffer.getSizeY(); int bnz = buffer.getSizeZ(); double buf[][][] = new double[bnx][bny][bnz]; getXYZ(x, y, z, buf); buffer.putXYZ(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware */ public void getX(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; System.arraycopy(tmp, offset, buffer, 0, leni); } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware */ public void getX(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (short) (tmp[offset] & 0xFF); offset++; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware */ public void getX(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (float) (tmp[offset] & 0xFF); offset++; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware */ public void getX(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (double) (tmp[offset] & 0xFF); offset++; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware */ public void getY(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (byte) (tmp[offset] & 0xFF); offset += nx; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware */ public void getY(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (short) (tmp[offset] & 0xFF); offset += nx; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware */ public void getY(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (float) (tmp[offset] & 0xFF); offset += nx; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware */ public void getY(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; byte[] tmp = (byte[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (double) (tmp[offset] & 0xFF); offset += nx; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware */ public void getZ(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { buffer[i] = (byte) (((byte[]) data[z])[offset] & 0xFF); z++; } } catch (Exception e) { throw_get("Y", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware */ public void getZ(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { buffer[i] = (short) (((byte[]) data[z])[offset] & 0xFF); z++; } } catch (Exception e) { throw_get("Y", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware */ public void getZ(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { buffer[i] = (float) (((byte[]) data[z])[offset] & 0xFF); z++; } } catch (Exception e) { throw_get("Y", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware */ public void getZ(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { buffer[i] = (double) (((byte[]) data[z])[offset] & 0xFF); z++; } } catch (Exception e) { throw_get("Y", "No check", buffer, x, y, z); } } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware */ public void getXY(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (byte) (tmp[offset] & 0xFF); } } } catch (Exception e) { throw_get("XY", "No check", buffer, x, y, z); } } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware */ public void getXY(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (short) (tmp[offset] & 0xFF); } } } catch (Exception e) { throw_get("XY", "No check", buffer, x, y, z); } } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware */ public void getXY(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (float) (tmp[offset] & 0xFF); } } } catch (Exception e) { throw_get("XY", "No check", buffer, x, y, z); } } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware */ public void getXY(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (double) (tmp[offset] & 0xFF); } } } catch (Exception e) { throw_get("XY", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware */ public void getXZ(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + y * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (byte) (((byte[]) data[z])[offset] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware */ public void getXZ(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + y * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (short) (((byte[]) data[z])[offset] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware */ public void getXZ(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + y * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (float) (((byte[]) data[z])[offset] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware */ public void getXZ(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + y * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (double) (((byte[]) data[z])[offset] & 0xFF); } } } catch (Exception e) { throw_get("XZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the datase */ public void getYZ(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { for (int i = 0; i < leni; i++, offset += nx) { buffer[i][j] = (byte) (((byte[]) data[z])[offset] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the datase */ public void getYZ(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { for (int i = 0; i < leni; i++, offset += nx) { buffer[i][j] = (short) (((byte[]) data[z])[offset] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the datase */ public void getYZ(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { for (int i = 0; i < leni; i++, offset += nx) { buffer[i][j] = (float) (((byte[]) data[z])[offset] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the datase */ public void getYZ(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { for (int i = 0; i < leni; i++, offset += nx) { buffer[i][j] = (double) (((byte[]) data[z])[offset] & 0xFF); } } } catch (Exception e) { throw_get("YZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware */ public void getXYZ(int x, int y, int z, byte[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j][k] = (byte) (tmp[offset] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware */ public void getXYZ(int x, int y, int z, short[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j][k] = (short) (tmp[offset] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware */ public void getXYZ(int x, int y, int z, float[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j][k] = (float) (tmp[offset] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware */ public void getXYZ(int x, int y, int z, double[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { byte[] tmp = (byte[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j][k] = (double) (tmp[offset] & 0xFF); } } } } catch (Exception e) { throw_get("XYZ", "No check", buffer, x, y, z); } } // ------------------------------------------------------------------ // // Private Section // // ------------------------------------------------------------------ /** * Prepare a complete error message from the errors coming the constructors. */ protected void throw_constructor() { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a byte imageware.\n" + "-------------------------------------------------------\n"); } /** * Prepare a complete error message from the errors coming the constructors. */ protected void throw_constructor(int nx, int ny, int nz) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a byte imageware " + nx + "," + ny + "," + nz + "].\n" + "-------------------------------------------------------\n"); } /** * Prepare a complete error message from the errors coming the get routines. */ protected void throw_get(String direction, String border, Object buffer, int x, int y, int z) { int leni = 0; int lenj = 0; int lenk = 0; String type = " unknown type"; if (buffer instanceof byte[]) { leni = ((byte[]) buffer).length; type = " 1D byte"; } else if (buffer instanceof short[]) { leni = ((short[]) buffer).length; type = " 1D short"; } else if (buffer instanceof float[]) { leni = ((float[]) buffer).length; type = " 1D float"; } else if (buffer instanceof double[]) { leni = ((double[]) buffer).length; type = " 1D double"; } else if (buffer instanceof byte[][]) { leni = ((byte[][]) buffer).length; lenj = ((byte[][]) buffer)[0].length; type = " 2D byte"; } else if (buffer instanceof short[][]) { leni = ((short[][]) buffer).length; lenj = ((short[][]) buffer)[0].length; type = " 2D short"; } else if (buffer instanceof float[][]) { leni = ((float[][]) buffer).length; lenj = ((float[][]) buffer)[0].length; type = " 2D float"; } else if (buffer instanceof double[][]) { leni = ((double[][]) buffer).length; lenj = ((double[][]) buffer)[0].length; type = " 2D double"; } else if (buffer instanceof byte[][][]) { leni = ((byte[][][]) buffer).length; lenj = ((byte[][][]) buffer)[0].length; lenk = ((byte[][][]) buffer)[0][0].length; type = " 3D byte"; } else if (buffer instanceof short[][][]) { leni = ((short[][][]) buffer).length; lenj = ((short[][][]) buffer)[0].length; lenk = ((short[][][]) buffer)[0][0].length; type = " 3D short"; } else if (buffer instanceof float[][][]) { leni = ((float[][][]) buffer).length; lenj = ((float[][][]) buffer)[0].length; lenk = ((float[][][]) buffer)[0][0].length; type = " 3D float"; } else if (buffer instanceof double[][][]) { leni = ((double[][][]) buffer).length; lenj = ((double[][][]) buffer)[0].length; lenk = ((double[][][]) buffer)[0][0].length; type = " 3D double"; } throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get a" + type + " buffer [" + (leni == 0 ? "" : ("" + leni)) + (lenj == 0 ? "" : ("," + lenj)) + (lenk == 0 ? "" : ("," + lenk)) + "] \n" + "from the byte imageware [" + nx + "," + ny + "," + nz + "]\n" + "at the position (" + x + "," + y + "," + z + ") in direction " + direction + "\n" + "using " + border + ".\n" + "-------------------------------------------------------\n"); } /** * Prepare a complete error message from the errors coming the put routines. */ protected void throw_put(String direction, String border, Object buffer, int x, int y, int z) { int leni = 0; int lenj = 0; int lenk = 0; String type = " unknown type"; if (buffer instanceof byte[]) { leni = ((byte[]) buffer).length; type = " 1D byte"; } else if (buffer instanceof short[]) { leni = ((short[]) buffer).length; type = " 1D short"; } else if (buffer instanceof float[]) { leni = ((float[]) buffer).length; type = " 1D float"; } else if (buffer instanceof double[]) { leni = ((double[]) buffer).length; type = " 1D double"; } else if (buffer instanceof byte[][]) { leni = ((byte[][]) buffer).length; lenj = ((byte[][]) buffer)[0].length; type = " 2D byte"; } else if (buffer instanceof short[][]) { leni = ((short[][]) buffer).length; lenj = ((short[][]) buffer)[0].length; type = " 2D short"; } else if (buffer instanceof float[][]) { leni = ((float[][]) buffer).length; lenj = ((float[][]) buffer)[0].length; type = " 2D float"; } else if (buffer instanceof double[][]) { leni = ((double[][]) buffer).length; lenj = ((double[][]) buffer)[0].length; type = " 2D double"; } else if (buffer instanceof byte[][][]) { leni = ((byte[][][]) buffer).length; lenj = ((byte[][][]) buffer)[0].length; lenk = ((byte[][][]) buffer)[0][0].length; type = " 3D byte"; } else if (buffer instanceof short[][][]) { leni = ((short[][][]) buffer).length; lenj = ((short[][][]) buffer)[0].length; lenk = ((short[][][]) buffer)[0][0].length; type = " 3D short"; } else if (buffer instanceof float[][][]) { leni = ((float[][][]) buffer).length; lenj = ((float[][][]) buffer)[0].length; lenk = ((float[][][]) buffer)[0][0].length; type = " 3D float"; } else if (buffer instanceof double[][][]) { leni = ((double[][][]) buffer).length; lenj = ((double[][][]) buffer)[0].length; lenk = ((double[][][]) buffer)[0][0].length; type = " 3D double"; } throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to put a" + type + " buffer [" + (leni == 0 ? "" : ("" + leni)) + (lenj == 0 ? "" : ("," + lenj)) + (lenk == 0 ? "" : ("," + lenk)) + "] \n" + "into the byte imageware [" + nx + "," + ny + "," + nz + "]\n" + "at the position (" + x + "," + y + "," + z + ") in direction " + direction + "\n" + "using " + border + ".\n" + "-------------------------------------------------------\n"); } // ------------------------------------------------------------------ // // Get slice fast and direct access Section // // ------------------------------------------------------------------ /** * Get a reference of the whole volume data. * * @return a reference of the data of this imageware */ public Object[] getVolume() { return data; } /** * Get a specific slice, fast and direct access, but only for byte * imageware. * * @param z * number of the requested slice * @return a reference of the data of one slice of this imageware */ public byte[] getSliceByte(int z) { return (byte[]) data[z]; } /** * Get a specific slice, fast and direct access, but only for short * imageware. * * @param z * number of the requested slice * @return a reference of the data of one slice of this imageware */ public short[] getSliceShort(int z) { return null; } /** * Get a specific slice, fast and direct access, but only for float * imageware. * * @param z * number of the requested slice * @return a reference of the data of one slice of this imageware */ public float[] getSliceFloat(int z) { return null; } /** * Get a specific slice, fast and direct access, but only for double * imageware. * * @param z * number of the requested slice * @return a reference of the data of one slice of this imageware */ public double[] getSliceDouble(int z) { return null; } /** * Allocate a buffer of size [nx,ny,nz]. */ private void allocate() { try { this.data = new Object[nz]; this.nxy = nx * ny; for (int z = 0; z < nz; z++) this.data[z] = new byte[nxy]; } catch (Exception e) { throw_constructor(nx, ny, nz); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/BytePointwise.java b/src/bilib/src/imageware/BytePointwise.java new file mode 100644 index 0000000000000000000000000000000000000000..2b75f0484801585c31c3a8e907fe89e7ac2ef2da --- /dev/null +++ b/src/bilib/src/imageware/BytePointwise.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import ij.process.ByteProcessor; import java.awt.Image; import java.util.Random; /** * Class BytePointwise. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class BytePointwise extends ByteAccess implements Pointwise { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected BytePointwise(int nx, int ny, int nz) { super(nx, ny, nz); } protected BytePointwise(Image image, int mode) { super(image, mode); } protected BytePointwise(ImageStack stack, int mode) { super(stack, mode); } protected BytePointwise(ImageStack stack, byte chan) { super(stack, chan); } protected BytePointwise(byte[] array, int mode) { super(array, mode); } protected BytePointwise(byte[][] array, int mode) { super(array, mode); } protected BytePointwise(byte[][][] array, int mode) { super(array, mode); } protected BytePointwise(short[] array, int mode) { super(array, mode); } protected BytePointwise(short[][] array, int mode) { super(array, mode); } protected BytePointwise(short[][][] array, int mode) { super(array, mode); } protected BytePointwise(float[] array, int mode) { super(array, mode); } protected BytePointwise(float[][] array, int mode) { super(array, mode); } protected BytePointwise(float[][][] array, int mode) { super(array, mode); } protected BytePointwise(double[] array, int mode) { super(array, mode); } protected BytePointwise(double[][] array, int mode) { super(array, mode); } protected BytePointwise(double[][][] array, int mode) { super(array, mode); } /** * Fill this imageware with a constant value. * * @param value * the constant value */ public void fillConstant(double value) { byte typedValue = (byte) value; byte[] slice = null; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) slice[k] = typedValue; } } /** * Fill this imageware with ramp. */ public void fillRamp() { int off = 0; byte[] slice = null; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) slice[k] = (byte) (off + k); off += nxy; } } /** * Generate a gaussian noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void fillGaussianNoise(double amplitude) { Random rnd = new Random(); byte[] slice = null; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) ((rnd.nextGaussian()) * amplitude); } } } /** * Generate a uniform noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void fillUniformNoise(double amplitude) { Random rnd = new Random(); byte[] slice = null; amplitude *= 2.0; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) ((rnd.nextDouble() - 0.5) * amplitude); } } } /** * Generate a salt and pepper noise. * * @param amplitudeSalt * amplitude of the salt noise * @param amplitudePepper * amplitude of the pepper noise * @param percentageSalt * percentage of the salt noise * @param percentagePepper * percentage of the pepper noise */ public void fillSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper) { Random rnd = new Random(); int index, z; if (percentageSalt > 0) { double nbSalt = nxy * nz / percentageSalt; for (int k = 0; k < nbSalt; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((byte[]) data[z])[index] = (byte) (rnd.nextDouble() * amplitudeSalt); } } if (percentagePepper > 0) { double nbPepper = nxy * nz / percentagePepper; for (int k = 0; k < nbPepper; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((byte[]) data[z])[index] = (byte) (-rnd.nextDouble() * amplitudeSalt); } } } /** * Build an ImageStack of ImageJ. */ public ImageStack buildImageStack() { ImageStack imagestack = new ImageStack(nx, ny); for (int z = 0; z < nz; z++) { ByteProcessor ip = new ByteProcessor(nx, ny); byte pix[] = (byte[]) ip.getPixels(); for (int k = 0; k < nxy; k++) pix[k] = (byte) (((byte[]) data[z])[k]); imagestack.addSlice("" + z, ip); } return imagestack; } /** * Invert the pixel intensity. */ public void invert() { double max = -Double.MAX_VALUE; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFF) > max) max = slice[k] & 0xFF; } } for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) (max - ((double) (slice[k] & 0xFF))); } } } /** * Negate the pixel intensity. */ public void negate() { byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) (-((double) (slice[k] & 0xFF))); } } } /** * Clip the pixel intensity into [0..255]. */ public void clip() { clip(0.0, 255.0); } /** * Clip the pixel intensity into [minLevel..maxLevel]. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void clip(double minLevel, double maxLevel) { byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; byte value; byte min = (byte) minLevel; byte max = (byte) maxLevel; for (int k = 0; k < nxy; k++) { value = (byte) (slice[k] & 0xFF); if (value < min) slice[k] = min; if (value > max) slice[k] = max; } } } /** * Rescale the pixel intensity into [0..255]. */ public void rescale() { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFF) > maxImage) maxImage = slice[k] & 0xFF; if ((slice[k] & 0xFF) < minImage) minImage = slice[k] & 0xFF; } } double a; if (minImage - maxImage == 0) { a = 1.0; minImage = 128.0; } else { a = 255.0 / (maxImage - minImage); } for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) (a * (((double) (slice[k] & 0xFF)) - minImage)); } } } /** * Rescale the pixel intensity into [minLevel..maxLevel]. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void rescale(double minLevel, double maxLevel) { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFF) > maxImage) maxImage = slice[k] & 0xFF; if ((slice[k] & 0xFF) < minImage) minImage = slice[k] & 0xFF; } } double a; if (minImage - maxImage == 0) { a = 1.0; minImage = (maxLevel - minLevel) / 2.0; } else { a = (maxLevel - minLevel) / (maxImage - minImage); } for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) (a * (((double) (slice[k] & 0xFF)) - minImage) + minLevel); } } } /** * Rescale the pixel intensity with a linear curve passing through * (maxLevel-minLevel)/2 at the 0 input intensity. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void rescaleCenter(double minLevel, double maxLevel) { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFF) > maxImage) maxImage = slice[k] & 0xFF; if ((slice[k] & 0xFF) < minImage) minImage = slice[k] & 0xFF; } } double center = (maxLevel + minLevel) / 2.0; double a; if (minImage - maxImage == 0) { a = 1.0; minImage = (maxLevel - minLevel) / 2.0; } else { if (Math.abs(maxImage) > Math.abs(minImage)) a = (maxLevel - center) / Math.abs(maxImage); else a = (center - minLevel) / Math.abs(minImage); } for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) (a * (((double) (slice[k] & 0xFF)) - minImage) + center); } } } /** * Compute the absolute value of this imageware. */ public void abs() { } /** * Compute the log of this imageware. */ public void log() { byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) Math.log(slice[k]); } } } /** * Compute the exponential of this imageware. */ public void exp() { byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) Math.exp(slice[k]); } } } /** * Compute the square root of this imageware. */ public void sqrt() { byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) Math.sqrt(slice[k]); } } } /** * Compute the square of this imageware. */ public void sqr() { byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] *= slice[k]; } } } /** * Compute the power of a of this imageware. * * @param a * exponent */ public void pow(double a) { byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (byte) Math.pow(slice[k], a); } } } /** * Add a constant value to this imageware. */ public void add(double constant) { byte cst = (byte) constant; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += cst; } } } /** * Multiply a constant value to this imageware. * * @param constant * the constant value */ public void multiply(double constant) { byte cst = (byte) constant; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] *= cst; } } } /** * Subtract a constant value to this imageware. * * @param constant * the constant value */ public void subtract(double constant) { byte cst = (byte) constant; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] -= cst; } } } /** * Divide by a constant value to this imageware. * * @param constant * the constant value */ public void divide(double constant) { if (constant == 0.0) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to divide because the constant is 0.\n" + "-------------------------------------------------------\n"); byte cst = (byte) constant; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] /= cst; } } } /** * Threshold a imageware in two levels 0 and 255. * * All the pixels values strictly greater than 'thresholdValue' and are set * to 0. The remaining values are set to 255. * * @param thresholdValue * double value given the threshold */ public void threshold(double thresholdValue) { threshold(thresholdValue, 0.0, 255.0); } /** * Threshold a imageware in two levels minLevel and maxLevel. * * All the pixels values strictly greater than 'thresholdValue' and are set * to maxLevel. The remaining values are set to minLevel. * * @param thresholdValue * double value given the threshold * @param minLevel * double value given the minimum level * @param maxLevel * double value given the maximum level */ public void threshold(double thresholdValue, double minLevel, double maxLevel) { byte low = (byte) (minLevel); byte high = (byte) (maxLevel); byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = ((double) (slice[k] & 0xFF) > thresholdValue ? high : low); } } } /** * Apply a soft thresholding. * * All the pixels values strictly greater than '-thresholdValue' and stricty * lower than 'thresholdValue' set to 0. The remaining positive values are * reduced by 'thresholdvalue'; the remaining negative values are augmented * by 'thresholdValue'. * * @param thresholdValue * double value given the threshold */ public void thresholdSoft(double thresholdValue) { byte zero = (byte) (0.0); double pixel; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { pixel = (double) (slice[k] & 0xFF); slice[k] = (pixel <= -thresholdValue ? (byte) (pixel + thresholdValue) : (pixel > thresholdValue ? (byte) (pixel - thresholdValue) : zero)); } } } /** * Apply a hard thresholding. * * All the pixels values strictly greater than '-thresholdValue' and stricty * lower than 'thresholdValue' are set to 0. The remaining values are * unchanged. * * @param thresholdValue * double value given the threshold */ public void thresholdHard(double thresholdValue) { byte zero = (byte) (0.0); double pixel; byte[] slice; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { pixel = (double) (slice[k] & 0xFF); if (pixel > -thresholdValue && pixel < thresholdValue) slice[k] = zero; } } } /** * Add a gaussian noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void addGaussianNoise(double amplitude) { Random rnd = new Random(); byte[] slice = null; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += (byte) ((rnd.nextGaussian()) * amplitude); } } } /** * Add a uniform noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void addUniformNoise(double amplitude) { Random rnd = new Random(); byte[] slice = null; amplitude *= 2.0; for (int z = 0; z < nz; z++) { slice = (byte[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += (byte) ((rnd.nextDouble() - 0.5) * amplitude); } } } /** * Add a salt and pepper noise. * * @param amplitudeSalt * amplitude of the salt noise * @param amplitudePepper * amplitude of the pepper noise * @param percentageSalt * percentage of the salt noise * @param percentagePepper * percentage of the pepper noise */ public void addSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper) { Random rnd = new Random(); int index, z; if (percentageSalt > 0) { double nbSalt = nxy * nz / percentageSalt; for (int k = 0; k < nbSalt; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((byte[]) data[z])[index] += (byte) (rnd.nextDouble() * amplitudeSalt); } } if (percentagePepper > 0) { double nbPepper = nxy * nz / percentagePepper; for (int k = 0; k < nbPepper; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((byte[]) data[z])[index] -= (byte) (rnd.nextDouble() * amplitudeSalt); } } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/ByteProcess.java b/src/bilib/src/imageware/ByteProcess.java new file mode 100644 index 0000000000000000000000000000000000000000..8156fbac956b9f324c3f975d44468a6c76e6d62c --- /dev/null +++ b/src/bilib/src/imageware/ByteProcess.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class ByteProcess. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class ByteProcess extends BytePointwise implements Process { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected ByteProcess(int nx, int ny, int nz) { super(nx, ny, nz); } protected ByteProcess(Image image, int mode) { super(image, mode); } protected ByteProcess(ImageStack stack, int mode) { super(stack, mode); } protected ByteProcess(ImageStack stack, byte chan) { super(stack, chan); } protected ByteProcess(byte[] array, int mode) { super(array, mode); } protected ByteProcess(byte[][] array, int mode) { super(array, mode); } protected ByteProcess(byte[][][] array, int mode) { super(array, mode); } protected ByteProcess(short[] array, int mode) { super(array, mode); } protected ByteProcess(short[][] array, int mode) { super(array, mode); } protected ByteProcess(short[][][] array, int mode) { super(array, mode); } protected ByteProcess(float[] array, int mode) { super(array, mode); } protected ByteProcess(float[][] array, int mode) { super(array, mode); } protected ByteProcess(float[][][] array, int mode) { super(array, mode); } protected ByteProcess(double[] array, int mode) { super(array, mode); } protected ByteProcess(double[][] array, int mode) { super(array, mode); } protected ByteProcess(double[][][] array, int mode) { super(array, mode); } /** * Apply a separable gaussian smoothing over the image with the same * strengthness in all directions. To have a smmothing effect the * strengthness should be strictly greater than 0 and the size in the * considered directions should be greater strictly than 1. * * @param sigma * Strengthness of the smoothing */ public void smoothGaussian(double sigma) { smoothGaussian(sigma, sigma, sigma); } /** * Apply a separablegaussian smoothing over the image with an independant * strengthness in the different directions. To have a smmothing effect the * strengthness should be strictly greater than 0 and the size in the * considered directions should be greater strictly than 1. * * @param sigmaX * Strengthness of the smoothing in X axis * @param sigmaY * Strengthness of the smoothing in X axis * @param sigmaZ * Strengthness of the smoothing in X axis */ public void smoothGaussian(double sigmaX, double sigmaY, double sigmaZ) { int n = 3; double N = (double) n; double poles[] = new double[n]; if (nx > 1 && sigmaX > 0.0) { double s2 = sigmaX * sigmaX; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[nx]; for (int z = 0; z < nz; z++) { for (int y = 0; y < ny; y++) { getX(0, y, z, line); putX(0, y, z, Convolver.convolveIIR(line, poles)); } } } if (ny > 1 && sigmaY > 0.0) { double s2 = sigmaY * sigmaY; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[ny]; for (int x = 0; x < nx; x++) { for (int z = 0; z < nz; z++) { getY(x, 0, z, line); putY(x, 0, z, Convolver.convolveIIR(line, poles)); } } } if (nz > 1 && sigmaZ > 0.0) { double s2 = sigmaZ * sigmaZ; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[nz]; for (int y = 0; y < ny; y++) { for (int x = 0; x < nx; x++) { getZ(x, y, 0, line); putZ(x, y, 0, Convolver.convolveIIR(line, poles)); } } } } /** * Get the maximum of this imageware and a imageware. * * @param imageware * imageware to max */ public void max(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get the maximum because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { if (((byte[]) data[z])[k] < (byte) tmp[k]) ((byte[]) data[z])[k] = (byte) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { if (((byte[]) data[z])[k] < (byte) tmp[k]) ((byte[]) data[z])[k] = (byte) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { if (((byte[]) data[z])[k] < (byte) tmp[k]) ((byte[]) data[z])[k] = (byte) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { if (((byte[]) data[z])[k] < (byte) tmp[k]) ((byte[]) data[z])[k] = (byte) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Get the minimum of this imageware and a imageware. * * @param imageware * imageware to min */ public void min(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get the minimum because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { if (((byte[]) data[z])[k] > (byte) tmp[k]) ((byte[]) data[z])[k] = (byte) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { if (((byte[]) data[z])[k] > (byte) tmp[k]) ((byte[]) data[z])[k] = (byte) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { if (((byte[]) data[z])[k] > (byte) tmp[k]) ((byte[]) data[z])[k] = (byte) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { if (((byte[]) data[z])[k] > (byte) tmp[k]) ((byte[]) data[z])[k] = (byte) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Add a imageware to the current imageware. * * @param imageware * imageware to add */ public void add(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to add because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] += (byte) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] += (byte) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] += (byte) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] += (byte) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Multiply a imageware to the current imageware. * * @param imageware * imageware to multiply */ public void multiply(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to multiply because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] *= (byte) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] *= (byte) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] *= (byte) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] *= (byte) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Subtract a imageware to the current imageware. * * @param imageware * imageware to subtract */ public void subtract(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to subtract because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] -= (byte) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] -= (byte) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] -= (byte) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] -= (byte) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Divide a imageware to the current imageware. * * @param imageware * imageware to divide */ public void divide(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to divide because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] /= (byte) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] /= (byte) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] /= (byte) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((byte[]) data[z])[k] /= (byte) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/ByteSet.java b/src/bilib/src/imageware/ByteSet.java new file mode 100644 index 0000000000000000000000000000000000000000..d354ff419105232460d2a68981a2b0b844c53847 --- /dev/null +++ b/src/bilib/src/imageware/ByteSet.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class ByteSet. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class ByteSet extends ByteProcess implements ImageWare { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected ByteSet(int nx, int ny, int nz) { super(nx, ny, nz); } protected ByteSet(Image image, int mode) { super(image, mode); } protected ByteSet(ImageStack stack, int mode) { super(stack, mode); } protected ByteSet(ImageStack stack, byte chan) { super(stack, chan); } protected ByteSet(byte[] array, int mode) { super(array, mode); } protected ByteSet(byte[][] array, int mode) { super(array, mode); } protected ByteSet(byte[][][] array, int mode) { super(array, mode); } protected ByteSet(short[] array, int mode) { super(array, mode); } protected ByteSet(short[][] array, int mode) { super(array, mode); } protected ByteSet(short[][][] array, int mode) { super(array, mode); } protected ByteSet(float[] array, int mode) { super(array, mode); } protected ByteSet(float[][] array, int mode) { super(array, mode); } protected ByteSet(float[][][] array, int mode) { super(array, mode); } protected ByteSet(double[] array, int mode) { super(array, mode); } protected ByteSet(double[][] array, int mode) { super(array, mode); } protected ByteSet(double[][][] array, int mode) { super(array, mode); } /** * Duplicate the imageware. * * Create a new imageware with the same size, same type and same data than * the calling one. * * @return a duplicated version of this imageware */ public ImageWare duplicate() { ImageWare out = new ByteSet(nx, ny, nz); byte[] outdata; for (int z = 0; z < nz; z++) { outdata = (byte[]) (((ByteSet) out).data[z]); System.arraycopy(data[z], 0, outdata, 0, nxy); } return out; } /** * Replicate the imageware. * * Create a new imageware with the same size, same type than the calling * one. The data are not copied. * * @return a replicated version of this imageware */ public ImageWare replicate() { return new ByteSet(nx, ny, nz); } /** * Replicate the imageware. * * Create a new imageware with the same size and a specified type than the * calling one. The data are not copied. * * @param type * requested type * @return a replicated version of this imageware */ public ImageWare replicate(int type) { switch (type) { case ImageWare.BYTE: return new ByteSet(nx, ny, nz); case ImageWare.SHORT: return new ShortSet(nx, ny, nz); case ImageWare.FLOAT: return new FloatSet(nx, ny, nz); case ImageWare.DOUBLE: return new DoubleSet(nx, ny, nz); default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + "].\n" + "-------------------------------------------------------\n"); } } /** * Copy all the data of source in the current imageware. The source should * have the same size and same type than the calling one. * * @param source * a source imageware */ public void copy(ImageWare source) { if (nx != source.getSizeX()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + nx + " != " + source.getSizeX() + ").\n" + "-------------------------------------------------------\n"); if (ny != source.getSizeY()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + ny + " != " + source.getSizeY() + ").\n" + "-------------------------------------------------------\n"); if (nz != source.getSizeZ()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + nz + " != " + source.getSizeZ() + ").\n" + "-------------------------------------------------------\n"); if (getType() != source.getType()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same type (" + getType() + " != " + source.getType() + ").\n" + "-------------------------------------------------------\n"); byte[] src; for (int z = 0; z < nz; z++) { src = (byte[]) (((ByteSet) source).data[z]); System.arraycopy(src, 0, data[z], 0, nxy); } } /** * convert the imageware in a specified type. * * Create a new imageware with the same size and converted data than the * calling one. * * @param type * indicates the type of the output * @return a converted version of this imageware */ public ImageWare convert(int type) { if (type == ImageWare.BYTE) return duplicate(); ImageWare out = null; switch (type) { case ImageWare.BYTE: { byte[] slice; out = new ByteSet(nx, ny, nz); byte[] outslice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); outslice = ((byte[]) ((ByteSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (byte) (slice[k] & 0xFF); } } } break; case ImageWare.SHORT: { byte[] slice; out = new ShortSet(nx, ny, nz); short[] outslice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); outslice = ((short[]) ((ShortSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (short) (slice[k] & 0xFF); } } } break; case ImageWare.FLOAT: { byte[] slice; out = new FloatSet(nx, ny, nz); float[] outslice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); outslice = ((float[]) ((FloatSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (float) (slice[k] & 0xFF); } } } break; case ImageWare.DOUBLE: { byte[] slice; out = new DoubleSet(nx, ny, nz); double[] outslice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); outslice = ((double[]) ((DoubleSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (double) (slice[k] & 0xFF); } } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + "].\n" + "-------------------------------------------------------\n"); } return out; } /** * Print information of this ImageWare object. */ public void printInfo() { System.out.println("ImageWare object information"); System.out.println("Dimension: " + getDimension()); System.out.println("Size: [" + nx + ", " + ny + ", " + nz + "]"); System.out.println("TotalSize: " + getTotalSize()); System.out.println("Type: " + getTypeToString()); System.out.println("Maximun: " + getMaximum()); System.out.println("Minimun: " + getMinimum()); System.out.println("Mean: " + getMean()); System.out.println("Norm1: " + getNorm1()); System.out.println("Norm2: " + getNorm2()); System.out.println("Total: " + getTotal()); System.out.println(""); } /** * Show this ImageWare object. */ public void show() { String title = getTypeToString(); switch (getDimension()) { case 1: title += " line"; break; case 2: title += " image"; break; case 3: title += " volume"; break; } Display.show(title, this); // ImagePlus imp = new ImagePlus(title, buildImageStack()); // imp.show(); } /** * Show the data in ImagePlus object with a specify title. * * @param title * a string given the title of the window */ public void show(String title) { Display.show(title, this); // ImagePlus imp = new ImagePlus(title, buildImageStack()); // imp.show(); } /** * Return the minimum value of this imageware. * * @return the min value of this imageware */ public double getMinimum() { double min = Double.MAX_VALUE; byte[] slice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); for (int k = 0; k < nxy; k++) if ((slice[k] & 0xFF) < min) min = slice[k] & 0xFF; } return min; } /** * Return the maximum value of this imageware. * * @return the max value of this imageware */ public double getMaximum() { double max = -Double.MAX_VALUE; byte[] slice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); for (int k = 0; k < nxy; k++) if ((slice[k] & 0xFF) > max) max = slice[k] & 0xFF; } return max; } /** * Return the mean value of this imageware. * * @return the mean value of this imageware */ public double getMean() { return getTotal() / (nz * nxy); } /** * Return the norm value of order 1. * * @return the norm value of this imageware in L1 sense */ public double getNorm1() { double norm = 0.0; double value = 0; byte[] slice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); for (int k = 0; k < nxy; k++) { value = (double) (slice[k] & 0xFF); norm += (value > 0.0 ? value : -value); } } return norm; } /** * Return the norm value of order 2. * * @return the norm value of this imageware in L2 sense */ public double getNorm2() { double norm = 0.0; byte[] slice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); for (int k = 0; k < nxy; k++) norm += (slice[k] & 0xFF) * (slice[k] & 0xFF); } return norm; } /** * Return the sum of all pixel in this imageware. * * @return the total sum of all pixel in this imageware */ public double getTotal() { double total = 0.0; byte[] slice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); for (int k = 0; k < nxy; k++) total += slice[k] & 0xFF; } return total; } /** * Return the the minumum [0] and the maximum [1] value of this imageware. * Faster routine than call one getMinimum() and then one getMaximum(). * * @return an array of two values, the min and the max values of the images */ public double[] getMinMax() { double max = -Double.MAX_VALUE; double min = Double.MAX_VALUE; byte[] slice; for (int z = 0; z < nz; z++) { slice = ((byte[]) data[z]); for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFF) > max) max = slice[k] & 0xFF; if ((slice[k] & 0xFF) < min) min = slice[k] & 0xFF; } } double minmax[] = { min, max }; return minmax; } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/Convolver.java b/src/bilib/src/imageware/Convolver.java new file mode 100644 index 0000000000000000000000000000000000000000..ffeffeefdbfe5ce793dca736ca3bd8098176f11b --- /dev/null +++ b/src/bilib/src/imageware/Convolver.java @@ -0,0 +1 @@ +package imageware; /** * Class Convolver. Routines to convolve a 1D signal applying mirror boundary * conditions. * * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class Convolver extends Object { private static double tolerance = 10e-6; /** * Convolution with a Finite Impulse Response (FIR) filter. * * Note: Only with the periodic boundary conditions. * * @param input * 1D input signal * @param kernel * kernel of the filter */ public static double[] convolveFIR(double[] input, double[] kernel) { int l = input.length; if (l <= 1) throw new IllegalArgumentException("convolveFIR: input signal too short"); double[] output = new double[l]; int indexq = kernel.length - 1; int indexp = 0; int n2 = 2 * (l - 1); int origin = kernel.length / 2; int m = 1 + origin - kernel.length; m -= (m < 0L) ? (n2 * ((m + 1 - n2) / n2)) : (n2 * (m / n2)); int k; for (int i = 0; i < l; i++) { int j = -kernel.length; k = m; indexq = kernel.length - 1; double Sum = 0.0; while (j < 0) { indexp = k; int kp = ((k - l) < j) ? (j) : (k - l); if (kp < 0L) { for (int n = kp; n < 0; n++) { Sum += input[indexp] * kernel[indexq]; indexq--; indexp++; } k -= kp; j -= kp; } indexp = n2 - k; int km = ((k - n2) < j) ? (j) : (k - n2); if (km < 0L) { for (int n = km; n < 0; n++) { Sum += input[indexp] * kernel[indexq]; indexq--; indexp--; } j -= km; } k = 0; } if (++m == n2) { m = 0; } output[i] = Sum; } return output; } /** * Convolve with with a Infinite Impluse Response filter (IIR) * * @param input * 1D input signal * @param poles * 1D array containing the poles of the filter */ public static double[] convolveIIR(double[] input, double poles[]) { double lambda = 1.0; int l = input.length; double[] output = new double[l]; for (int k = 0; k < poles.length; k++) { lambda = lambda * (1.0 - poles[k]) * (1.0 - 1.0 / poles[k]); } for (int n = 0; n < l; n++) { output[n] = input[n] * lambda; } for (int k = 0; k < poles.length; k++) { output[0] = getInitialCausalCoefficientMirror(output, poles[k]); for (int n = 1; n < l; n++) { output[n] = output[n] + poles[k] * output[n - 1]; } output[l - 1] = getInitialAntiCausalCoefficientMirror(output, poles[k]); for (int n = l - 2; 0 <= n; n--) { output[n] = poles[k] * (output[n + 1] - output[n]); } } return output; } /** * Convolve a 1D signal with a Infinite Impluse Response 2nd order (IIR2) * * Note: Only with the mirror (on bounds) boundary conditions. * * Purpose: Recursive implementation of a symmetric 2nd order filter with * mirror symmetry boundary conditions : * * 1 1 H[z] = --------------- * --------------- (1-b1*z-b2*z^2) * (1-b1/z-b2/z^2) * * implemented in the following form: * * a1+a2*z a1+a2/z H[z] = --------------- + --------------- - a1 * (1-b1*z+b2*z^2) (1-b1/z+b2/z^2) * * where : a1 = -(b2 + 1.0) * (1 - b1 + b2) / ((b2 - 1.0) * (1 + b1 + b2)); * a2 = - a1 * b2 * b1 / (b2 + 1.0); * * @param input * 1D input signal * @param b1 * first pole of the filter * @param b2 * second pole of the filter */ public static double[] convolveIIR2(double input[], double b1, double b2) { int l = input.length; int n2 = 2 * l; double a1 = -(b2 + 1.0) * (1 - b1 + b2) / ((b2 - 1.0) * (1 + b1 + b2)); double a2 = -a1 * b2 * b1 / (b2 + 1.0); // cBuffer stores temporary spline coefficients double cBuffer[] = new double[n2]; // sBuffer contains a copy of s[] and a time reversed version of s[] double sBuffer[] = new double[n2]; // copy signal s[] and its time reversed version to sBuffer[] for (int n = 0; n < l; n++) { sBuffer[n] = input[n]; sBuffer[n2 - n - 1] = input[n]; } // Determine the start index n0 for the causal recursion. n0 is chosen // such // that the error of cBuffer[0] and cBuffer[1] is smaller than the // specified 'Tolerance'. int n0 = 2; if ((tolerance > 0.0) && (b2 != 1.0)) { n0 = n2 - (int) Math.ceil(2.0 * Math.log(tolerance) / Math.log(b2)); } if (n0 < 2) { n0 = 2; } cBuffer[n0 - 1] = 0.0; cBuffer[n0 - 2] = 0.0; for (int n = n0; n < n2; n++) { cBuffer[n] = a1 * sBuffer[n] + a2 * sBuffer[n - 1] + b1 * cBuffer[n - 1] - b2 * cBuffer[n - 2]; } cBuffer[0] = a1 * sBuffer[0] + a2 * sBuffer[n2 - 1] + b1 * cBuffer[n2 - 1] - b2 * cBuffer[n2 - 2]; cBuffer[1] = a1 * sBuffer[1] + a2 * sBuffer[0] + b1 * cBuffer[0] - b2 * cBuffer[n2 - 1]; // compute the remaining spline coefficients cBuffer(z) = H_{+}(z) * // sBuffer(z) by // recursive filtering for (int n = 2; n < n2; n++) { cBuffer[n] = a1 * sBuffer[n] + a2 * sBuffer[n - 1] + b1 * cBuffer[n - 1] - b2 * cBuffer[n - 2]; } // add together the temporary filter outputs to obtain the final spline // coefficients double[] output = new double[l]; for (int n = 0; n < l; n++) { output[n] = cBuffer[n] + cBuffer[n2 - n - 1] - a1 * input[n]; } return output; } /** */ private static double getInitialAntiCausalCoefficientMirror(double[] c, double z) { return ((z * c[c.length - 2] + c[c.length - 1]) * z / (z * z - 1.0)); } /** */ private static double getInitialCausalCoefficientMirror(double[] c, double z) { double z1 = z, zn = Math.pow(z, c.length - 1); double sum = c[0] + zn * c[c.length - 1]; int horizon = c.length; if (0.0 < tolerance) { horizon = 2 + (int) (Math.log(tolerance) / Math.log(Math.abs(z))); horizon = (horizon < c.length) ? (horizon) : (c.length); } zn = zn * zn; for (int n = 1; (n < (horizon - 1)); n++) { zn = zn / z; sum = sum + (z1 + zn) * c[n]; z1 = z1 * z; } return (sum / (1.0 - Math.pow(z, 2 * c.length - 2))); } } // end of classe \ No newline at end of file diff --git a/src/bilib/src/imageware/Display.java b/src/bilib/src/imageware/Display.java new file mode 100644 index 0000000000000000000000000000000000000000..4a85ab450bcea8bda63e0cd3b7fec08f041184b0 --- /dev/null +++ b/src/bilib/src/imageware/Display.java @@ -0,0 +1 @@ +package imageware; import ij.ImagePlus; import ij.ImageStack; import ij.gui.ImageCanvas; import ij.gui.ImageWindow; import ij.process.ColorProcessor; import javax.swing.SwingUtilities; /** * Class Display. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class Display { /** * Class Show. Display an imageware in the swing thread. */ static class Show implements Runnable { private String title; private ImageStack stack; public Show(String title, ImageStack stack) { this.title = title; this.stack = stack; } public void run() { (new ImagePlus(title, stack)).show(); } } /** * Class ShowZoom. Display an imageware in the swing thread. */ static class ShowZoom implements Runnable { private String title; private ImageStack stack; private double magnification; public ShowZoom(String title, ImageStack stack, double magnification) { this.title = title; this.stack = stack; } public void run() { ImagePlus imp = new ImagePlus(title, stack); imp.show(); ImageWindow win = imp.getWindow(); ImageCanvas canvas = win.getCanvas(); canvas.setMagnification(magnification); canvas.setDrawingSize((int) Math.ceil(stack.getWidth() * magnification), (int) Math.ceil(stack.getHeight() * magnification)); win.pack(); imp.updateAndRepaintWindow(); } } /** * Shows a imageware with a specifc title. * * @param title * a specific title * @param ds * the imageware to be shown */ static public void show(String title, ImageWare ds) { ImageStack stack = ds.buildImageStack(); SwingUtilities.invokeLater(new Show(title, stack)); } /** * Shows color image composed by three datasets with a specific title. * * @param title * a specific title * @param red * the imageware to be shown in the red channel * @param green * the imageware to be shown in the green channel * @param blue * the imageware to be shown in the blue channel */ static public void showColor(String title, ImageWare red, ImageWare green, ImageWare blue) { ImageStack stack = buildColor(red, green, blue); (new ImagePlus(title, stack)).show(); } /** * Shows a imageware with a specific title and with a specific * magnification. * * @param title * a specific title * @param ds * the imageware to be shown * @param magnification * zoom factor */ static public void show(String title, ImageWare ds, double magnification) { ImageStack stack = ds.buildImageStack(); SwingUtilities.invokeLater(new ShowZoom(title, stack, magnification)); } /** * Shows color image composed by three datasets with a specifc title and * with a specific magnification. * * @param title * a specific title * @param red * the imageware to be shown in the red channel * @param green * the imageware to be shown in the green channel * @param blue * the imageware to be shown in the blue channel * @param magnification * zoom factor */ static public void showColor(String title, ImageWare red, ImageWare green, ImageWare blue, double magnification) { ImageStack stack = buildColor(red, green, blue); SwingUtilities.invokeLater(new ShowZoom(title, stack, magnification)); } /** */ static private ImageStack buildColor(ImageWare red, ImageWare green, ImageWare blue) { if (!red.isSameSize(green)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a ImageStack the channel are not the same size.\n" + "[" + red.getSizeX() + "," + red.getSizeY() + "," + red.getSizeZ() + "] != " + "[" + green.getSizeX() + "," + green.getSizeY() + "," + green.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } if (!red.isSameSize(blue)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a ImageStack the channel are not the same size.\n" + "[" + red.getSizeX() + "," + red.getSizeY() + "," + red.getSizeZ() + "] != " + "[" + blue.getSizeX() + "," + blue.getSizeY() + "," + blue.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } int nx = red.getSizeX(); int ny = red.getSizeY(); int nz = red.getSizeZ(); int nxy = nx * ny; ImageStack imagestack = new ImageStack(nx, ny); ColorProcessor cp; byte[] r = new byte[nxy]; byte[] g = new byte[nxy]; byte[] b = new byte[nxy]; for (int z = 0; z < nz; z++) { cp = new ColorProcessor(nx, ny); switch (red.getType()) { case ImageWare.DOUBLE: double[] dpixred = red.getSliceDouble(z); for (int k = 0; k < nxy; k++) r[k] = (byte) (dpixred[k]); break; case ImageWare.FLOAT: float[] fpixred = red.getSliceFloat(z); for (int k = 0; k < nxy; k++) r[k] = (byte) (fpixred[k]); break; case ImageWare.SHORT: short[] spixred = red.getSliceShort(z); for (int k = 0; k < nxy; k++) r[k] = (byte) (spixred[k]); break; case ImageWare.BYTE: r = red.getSliceByte(z); break; } switch (green.getType()) { case ImageWare.DOUBLE: double[] dpixgreen = green.getSliceDouble(z); for (int k = 0; k < nxy; k++) g[k] = (byte) (dpixgreen[k]); break; case ImageWare.FLOAT: float[] fpixgreen = green.getSliceFloat(z); for (int k = 0; k < nxy; k++) g[k] = (byte) (fpixgreen[k]); break; case ImageWare.SHORT: short[] spixgreen = green.getSliceShort(z); for (int k = 0; k < nxy; k++) g[k] = (byte) (spixgreen[k]); break; case ImageWare.BYTE: g = green.getSliceByte(z); break; } switch (blue.getType()) { case ImageWare.DOUBLE: double[] dpixblue = blue.getSliceDouble(z); for (int k = 0; k < nxy; k++) b[k] = (byte) (dpixblue[k]); break; case ImageWare.FLOAT: float[] fpixblue = blue.getSliceFloat(z); for (int k = 0; k < nxy; k++) b[k] = (byte) (fpixblue[k]); break; case ImageWare.SHORT: short[] spixblue = blue.getSliceShort(z); for (int k = 0; k < nxy; k++) b[k] = (byte) (spixblue[k]); break; case ImageWare.BYTE: b = blue.getSliceByte(z); break; } cp.setRGB(r, g, b); imagestack.addSlice("" + z, cp); } return imagestack; } } \ No newline at end of file diff --git a/src/bilib/src/imageware/DoubleAccess.java b/src/bilib/src/imageware/DoubleAccess.java new file mode 100644 index 0000000000000000000000000000000000000000..0662b87291e33928acb55ab439fb11804c454232 --- /dev/null +++ b/src/bilib/src/imageware/DoubleAccess.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class DoubleAccess. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class DoubleAccess extends DoubleBuffer implements Access { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected DoubleAccess(int nx, int ny, int nz) { super(nx, ny, nz); } protected DoubleAccess(Image image, int mode) { super(image, mode); } protected DoubleAccess(ImageStack stack, int mode) { super(stack, mode); } protected DoubleAccess(ImageStack stack, byte chan) { super(stack, chan); } protected DoubleAccess(byte[] array, int mode) { super(array, mode); } protected DoubleAccess(byte[][] array, int mode) { super(array, mode); } protected DoubleAccess(byte[][][] array, int mode) { super(array, mode); } protected DoubleAccess(short[] array, int mode) { super(array, mode); } protected DoubleAccess(short[][] array, int mode) { super(array, mode); } protected DoubleAccess(short[][][] array, int mode) { super(array, mode); } protected DoubleAccess(float[] array, int mode) { super(array, mode); } protected DoubleAccess(float[][] array, int mode) { super(array, mode); } protected DoubleAccess(float[][][] array, int mode) { super(array, mode); } protected DoubleAccess(double[] array, int mode) { super(array, mode); } protected DoubleAccess(double[][] array, int mode) { super(array, mode); } protected DoubleAccess(double[][][] array, int mode) { super(array, mode); } // ------------------------------------------------------------------ // // getPixel section // // ------------------------------------------------------------------ /** * Get a pixel at specific position without specific boundary conditions * * If the positions is outside of this imageware, the method return 0.0. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a pixel value */ public double getPixel(int x, int y, int z) { if (x >= nx) return 0.0; if (y >= ny) return 0.0; if (z >= nz) return 0.0; if (x < 0) return 0.0; if (y < 0) return 0.0; if (z < 0) return 0.0; return ((double[]) data[z])[x + y * nx]; } /** * Get a pixel at specific position with specific boundary conditions * * If the positions is outside of this imageware, the method apply the * boundary conditions to return a value. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a pixel value */ public double getPixel(int x, int y, int z, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to put a pixel \n" + "at the position (" + x + "," + y + "," + z + ".\n" + "-------------------------------------------------------\n"); } int xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } return ((double[]) data[zp])[xp + yp * nx]; } /** * Get a interpolated pixel value at specific position without specific * boundary conditions. * * If the positions is not on the pixel grid, the method return a * interpolated value of the pixel (linear interpolation). If the positions * is outside of this imageware, the method return 0.0. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a interpolated value */ public double getInterpolatedPixel(double x, double y, double z) { if (x > nx - 1) return 0.0; if (y > ny - 1) return 0.0; if (z > nz - 1) return 0.0; if (x < 0) return 0.0; if (y < 0) return 0.0; if (z < 0) return 0.0; double output = 0.0; /* * int i = (x >= 0.0 ? ((int)x) : ((int)x - 1)); int j = (y >= 0.0 ? * ((int)y) : ((int)y - 1)); int k = (z >= 0.0 ? ((int)z) : ((int)z - * 1)); */ int i = (x >= 0.0 ? ((int) x) : ((int) x - 1)); int j = (y >= 0.0 ? ((int) y) : ((int) y - 1)); int k = (z >= 0.0 ? ((int) z) : ((int) z - 1)); boolean fi = (i == nx - 1); boolean fj = (j == ny - 1); boolean fk = (k == nz - 1); int index = i + j * nx; switch (getDimension()) { case 1: double v1_0 = (double) (((double[]) data[k])[index]); double v1_1 = (fi ? v1_0 : (double) (((double[]) data[k])[index + 1])); double dx1 = x - (double) i; return v1_1 * dx1 - v1_0 * (dx1 - 1.0); case 2: double v2_00 = (double) (((double[]) data[k])[index]); double v2_10 = (fi ? v2_00 : (double) (((double[]) data[k])[index + 1])); double v2_01 = (fj ? v2_00 : (double) (((double[]) data[k])[index + nx])); double v2_11 = (fi ? (fj ? v2_00 : v2_01) : (double) (((double[]) data[k])[index + 1 + nx])); double dx2 = x - (double) i; double dy2 = y - (double) j; return (dx2 * (v2_11 * dy2 - v2_10 * (dy2 - 1.0)) - (dx2 - 1.0) * (v2_01 * dy2 - v2_00 * (dy2 - 1.0))); case 3: double v3_000 = (double) (((double[]) data[k])[index]); double v3_100 = (fi ? v3_000 : (double) (((double[]) data[k])[index + 1])); double v3_010 = (fj ? v3_000 : (double) (((double[]) data[k])[index + nx])); double v3_110 = (fi ? (fj ? v3_000 : v3_010) : (double) (((double[]) data[k])[index + 1 + nx])); double v3_001 = (fk ? v3_000 : (double) (((double[]) data[k + 1])[index])); double v3_011 = (fk ? (fj ? v3_000 : v3_010) : (double) (((double[]) data[k + 1])[index + 1])); double v3_101 = (fk ? (fi ? v3_000 : v3_100) : (double) (((double[]) data[k + 1])[index + nx])); double v3_111 = (fk ? (fj ? (fi ? v3_000 : v3_100) : v3_110) : (double) (((double[]) data[k + 1])[index + 1 + nx])); double dx3 = x - (double) i; double dy3 = y - (double) j; double dz3 = z - (double) k; double z1 = (dx3 * (v3_110 * dy3 - v3_100 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_010 * dy3 - v3_000 * (dy3 - 1.0))); double z2 = (dx3 * (v3_111 * dy3 - v3_101 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_011 * dy3 - v3_001 * (dy3 - 1.0))); return z2 * dz3 - z1 * (dz3 - 1.0); } return output; } /** * Get a interpolated pixel value at specific position with specific * boundary conditions. * * If the positions is not on the pixel grid, the method return a * interpolated value of the pixel (linear interpolation). If the positions * is outside of this imageware, the method apply the boundary conditions to * return a value. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @param boundaryConditions * MIRROR or PERIODIC boundary conditions * @return a interpolated value */ public double getInterpolatedPixel(double x, double y, double z, byte boundaryConditions) { double output = 0.0; int i = (x >= 0.0 ? ((int) x) : ((int) x - 1)); int j = (y >= 0.0 ? ((int) y) : ((int) y - 1)); int k = (z >= 0.0 ? ((int) z) : ((int) z - 1)); switch (getDimension()) { case 1: double v1_0 = getPixel(i, j, k, boundaryConditions); double v1_1 = getPixel(i + 1, j, k, boundaryConditions); double dx1 = x - (double) i; return v1_1 * dx1 - v1_0 * (dx1 - 1.0); case 2: double v2_00 = getPixel(i, j, k, boundaryConditions); double v2_10 = getPixel(i + 1, j, k, boundaryConditions); double v2_01 = getPixel(i, j + 1, k, boundaryConditions); double v2_11 = getPixel(i + 1, j + 1, k, boundaryConditions); double dx2 = x - (double) i; double dy2 = y - (double) j; return (dx2 * (v2_11 * dy2 - v2_10 * (dy2 - 1.0)) - (dx2 - 1.0) * (v2_01 * dy2 - v2_00 * (dy2 - 1.0))); case 3: double v3_000 = getPixel(i, j, k, boundaryConditions); double v3_100 = getPixel(i + 1, j, k, boundaryConditions); double v3_010 = getPixel(i, j + 1, k, boundaryConditions); double v3_110 = getPixel(i + 1, j + 1, k, boundaryConditions); double v3_001 = getPixel(i, j, k + 1, boundaryConditions); double v3_011 = getPixel(i + 1, j, k + 1, boundaryConditions); double v3_101 = getPixel(i, j + 1, k + 1, boundaryConditions); double v3_111 = getPixel(i + 1, j + 1, k + 1, boundaryConditions); double dx3 = x - (double) i; double dy3 = y - (double) j; double dz3 = z - (double) k; double z1 = (dx3 * (v3_110 * dy3 - v3_100 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_010 * dy3 - v3_000 * (dy3 - 1.0))); double z2 = (dx3 * (v3_111 * dy3 - v3_101 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_011 * dy3 - v3_001 * (dy3 - 1.0))); return z2 * dz3 - z1 * (dz3 - 1.0); } return output; } // ------------------------------------------------------------------ // // putPixel section // // ------------------------------------------------------------------ /** * Put a pixel at specific position * * If the positions is outside of this imageware, the method does nothing. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis */ public void putPixel(int x, int y, int z, double value) { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; if (x < 0) return; if (y < 0) return; if (z < 0) return; ((double[]) data[z])[x + y * nx] = (double) value; } // ------------------------------------------------------------------ // // getBounded section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (short) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (float) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (double) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (short) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (float) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (double) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (((double[]) data[k])[offset]); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (short) (((double[]) data[k])[offset]); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (float) (((double[]) data[k])[offset]); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (double) (((double[]) data[k])[offset]); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); double[] tmp = (double[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (tmp[offset]); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); double[] tmp = (double[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (tmp[offset]); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); double[] tmp = (double[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (tmp[offset]); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); double[] tmp = (double[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (tmp[offset]); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (((double[]) data[z])[offset]); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (((double[]) data[z])[offset]); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (((double[]) data[z])[offset]); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (((double[]) data[z])[offset]); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (((double[]) data[z])[offset]); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (((double[]) data[z])[offset]); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (((double[]) data[z])[offset]); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (((double[]) data[z])[offset]); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, byte[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { double[] tmp = (double[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (byte) (tmp[offset]); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, short[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { double[] tmp = (double[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (short) (tmp[offset]); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, float[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { double[] tmp = (double[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (float) (tmp[offset]); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, double[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { double[] tmp = (double[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (double) (tmp[offset]); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } // ------------------------------------------------------------------ // // getBlock section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; double[] tmp = (double[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (byte) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; double[] tmp = (double[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (short) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; double[] tmp = (double[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (float) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; double[] tmp = (double[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (double) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } double[] tmp = (double[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (byte) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } double[] tmp = (double[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (short) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } double[] tmp = (double[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (float) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } double[] tmp = (double[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (double) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (byte) (((double[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (short) (((double[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (float) (((double[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (double) (((double[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = (double[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = (double[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = (double[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = (double[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (((double[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (((double[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (((double[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (((double[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (byte) (((double[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (short) (((double[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (float) (((double[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (double) (((double[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = (double[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (byte) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = (double[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (short) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = (double[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (float) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = (double[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (double) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } // ------------------------------------------------------------------ // // getBlock section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; double[] tmp = ((double[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (byte) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; double[] tmp = ((double[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (short) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; double[] tmp = ((double[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (float) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; double[] tmp = ((double[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (double) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; double[] tmp = ((double[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (byte) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; double[] tmp = ((double[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (short) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; double[] tmp = ((double[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (float) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; double[] tmp = ((double[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (double) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (byte) (((double[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (short) (((double[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (float) (((double[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (double) (((double[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; double[] tmp = ((double[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; double[] tmp = ((double[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; double[] tmp = ((double[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; double[] tmp = ((double[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (((double[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (((double[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (((double[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (((double[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (byte) (((double[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (short) (((double[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (float) (((double[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (double) (((double[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = ((double[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (byte) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = ((double[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (short) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = ((double[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (float) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } double[] tmp = ((double[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (double) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } // ------------------------------------------------------------------ // // putBounded section // // ------------------------------------------------------------------ /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i] & 0xFF); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i] & 0xFFFF); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i] & 0xFF); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); double[] tmp = (double[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i] & 0xFF); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i] & 0xFFFF); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i]); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i]); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); double[] tmp = (double[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i][j] & 0xFF); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); double[] tmp = (double[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i][j] & 0xFFFF); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); double[] tmp = (double[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i][j]); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); double[] tmp = (double[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i][j]); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i][j] & 0xFF); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i][j] & 0xFFFF); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i][j]); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i][j]); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i][j] & 0xFF); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i][j] & 0xFFFF); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i][j]); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((double[]) data[k])[offset] = (double) (buffer[i][j]); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, byte[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { double[] tmp = (double[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i][j][k] & 0xFF); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, short[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { double[] tmp = (double[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i][j][k] & 0xFFFF); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, float[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { double[] tmp = (double[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i][j][k]); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, double[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { double[] tmp = (double[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (double) (buffer[i][j][k]); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/DoubleBuffer.java b/src/bilib/src/imageware/DoubleBuffer.java new file mode 100644 index 0000000000000000000000000000000000000000..7995ce66485d5d5eafe901f60b15d6c18f776dbb --- /dev/null +++ b/src/bilib/src/imageware/DoubleBuffer.java @@ -0,0 +1,2769 @@ +package imageware; + +import ij.ImageStack; +import ij.process.ByteProcessor; +import ij.process.ColorProcessor; +import ij.process.FloatProcessor; +import ij.process.ImageProcessor; +import ij.process.ShortProcessor; + +import java.awt.Image; +import java.awt.image.ImageObserver; +import java.awt.image.PixelGrabber; + +/** + * Class DoubleBuffer. + * + * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de + * Lausanne, Lausanne, Switzerland + */ + +public class DoubleBuffer implements Buffer { + + protected Object[] data = null; + protected int nx = 0; + protected int ny = 0; + protected int nz = 0; + protected int nxy = 0; + + /** + * Constructor of a empty 3D double buffer. + * + * @param nx + * size of the 3D buffer in the X axis + * @param ny + * size of the 3D buffer in the Y axis + * @param nz + * size of the 3D buffer in the Z axis + */ + protected DoubleBuffer(int nx, int ny, int nz) { + this.nx = nx; + this.ny = ny; + this.nz = nz; + if (nx <= 0 || ny <= 0 || nz <= 0) + throw_constructor(nx, ny, nz); + allocate(); + } + + /** + * Constructor of a double buffer from a object Image of Java. + * + * @param image + * source to build a new imageware + */ + protected DoubleBuffer(Image image, int mode) { + if (image == null) { + throw_constructor(); + } + ImageObserver observer = null; + this.nx = image.getWidth(observer); + this.ny = image.getHeight(observer); + this.nz = 1; + this.nxy = nx * ny; + byte[] pixels = new byte[nxy]; + PixelGrabber pg = new PixelGrabber(image, 0, 0, nx, ny, false); + try { + pg.grabPixels(); + pixels = (byte[]) (pg.getPixels()); + } + catch (Exception e) { + throw_constructor(); + } + allocate(); + for (int k = 0; k < nxy; k++) + ((double[]) data[0])[k] = (double) (pixels[k] & 0xFF); + } + + /** + * Constructor of a double buffer from a ImageStack. + * + * New data are allocated if the mode is CREATE, the imageware use the data + * of ImageJ if the mode is WRAP. + * + * @param stack + * source to build a new imageware + * @param mode + * WRAP or CREATE + */ + protected DoubleBuffer(ImageStack stack, int mode) { + if (stack == null) { + throw_constructor(); + } + this.nx = stack.getWidth(); + this.ny = stack.getHeight(); + this.nz = stack.getSize(); + this.nxy = nx * ny; + switch (mode) { + case ImageWare.WRAP: + throw_constructor(); + break; + case ImageWare.CREATE: + allocate(); + ImageProcessor ip = stack.getProcessor(1); + if (ip instanceof ByteProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + byte[] slice = (byte[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((double[]) data[z])[k] = (double) (slice[k] & 0xFF); + } + } + } + else if (ip instanceof ShortProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + short[] slice = (short[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((double[]) data[z])[k] = (double) (slice[k] & 0xFFFF); + } + } + } + else if (ip instanceof FloatProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + float[] slice = (float[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((double[]) data[z])[k] = (double) slice[k]; + } + } + } + else if (ip instanceof ColorProcessor) { + double r, g, b; + int c; + ColorProcessor cp; + int[] pixels; + for (int z = 0; z < nz; z++) { + cp = (ColorProcessor) stack.getProcessor(z + 1); + pixels = (int[]) cp.getPixels(); + for (int k = 0; k < nxy; k++) { + c = pixels[k]; + r = (double) ((c & 0xFF0000) >> 16); + g = (double) ((c & 0xFF00) >> 8); + b = (double) ((c & 0xFF)); + ((double[]) data[z])[k] = (double) ((r + g + b) / 3.0); + } + } + } + else { + throw_constructor(); + } + break; + default: + throw_constructor(); + break; + } + } + + /** + * Constructor of a double buffer from a specific color channel of + * ImageStack. + * + * New data are always allocated. If it is a gray image the imageware is + * created and fill up with data of the source ImageStack. If it is a color + * image only the selected channel is used to create this imageware. + * + * @param stack + * source to build a new imageware + * @param channel + * RED, GREEN or BLUE + */ + protected DoubleBuffer(ImageStack stack, byte channel) { + if (stack == null) { + throw_constructor(); + } + this.nx = stack.getWidth(); + this.ny = stack.getHeight(); + this.nz = stack.getSize(); + this.nxy = nx * ny; + allocate(); + ImageProcessor ip = stack.getProcessor(1); + if (ip instanceof ByteProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + byte[] slice = (byte[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((double[]) data[z])[k] = (double) (slice[k] & 0xFF); + } + } + } + else if (ip instanceof ShortProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + short[] slice = (short[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((double[]) data[z])[k] = (double) (slice[k] & 0xFFFF); + } + } + } + else if (ip instanceof FloatProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + float[] slice = (float[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((double[]) data[z])[k] = (double) slice[k]; + } + } + } + else if (ip instanceof ColorProcessor) { + ColorProcessor cp; + int[] pixels; + for (int z = 0; z < nz; z++) { + cp = (ColorProcessor) stack.getProcessor(z + 1); + pixels = (int[]) cp.getPixels(); + switch (channel) { + case ImageWare.RED: + for (int k = 0; k < nxy; k++) { + ((double[]) data[z])[k] = (double) ((pixels[k] & 0xFF0000) >> 16); + } + break; + case ImageWare.GREEN: + for (int k = 0; k < nxy; k++) { + ((double[]) data[z])[k] = (double) ((pixels[k] & 0xFF00) >> 8); + } + break; + case ImageWare.BLUE: + for (int k = 0; k < nxy; k++) { + ((double[]) data[z])[k] = (double) (pixels[k] & 0xFF); + } + break; + default: + throw_constructor(); + } + } + } + else { + throw_constructor(); + } + } + + /** + * Constructor of a double buffer from a byte array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(byte[] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = 1; + this.nz = 1; + allocate(); + putX(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a byte array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(byte[][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = 1; + allocate(); + putXY(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a byte array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(byte[][][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = array[0][0].length; + allocate(); + putXYZ(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a short array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(short[] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = 1; + this.nz = 1; + allocate(); + putX(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a short array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(short[][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = 1; + allocate(); + putXY(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a short array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(short[][][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = array[0][0].length; + allocate(); + putXYZ(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a float array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(float[] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = 1; + this.nz = 1; + allocate(); + putX(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a float array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(float[][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = 1; + allocate(); + putXY(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a float array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(float[][][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = array[0][0].length; + allocate(); + putXYZ(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a double array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(double[] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = 1; + this.nz = 1; + allocate(); + putX(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a double array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(double[][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = 1; + allocate(); + putXY(0, 0, 0, array); + } + + /** + * Constructor of a double buffer from a double array. + * + * @param array + * source to build this new imageware + */ + protected DoubleBuffer(double[][][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = array[0][0].length; + allocate(); + putXYZ(0, 0, 0, array); + } + + /** + * Return the type of this imageware. + * + * @return the type of this imageware + */ + public int getType() { + return ImageWare.DOUBLE; + } + + /** + * Return the type of this imageware in a string format. + * + * @return the type of this imageware translated in a string format + */ + public String getTypeToString() { + return "Double"; + } + + /** + * Return the number of dimension of this imageware (1, 2 or 3). + * + * @return the number of dimension of this imageware + */ + public int getDimension() { + int dims = 0; + dims += (nx > 1 ? 1 : 0); + dims += (ny > 1 ? 1 : 0); + dims += (nz > 1 ? 1 : 0); + return dims; + } + + /** + * Return the size of the imageware int[0] : x, int[1] : y, int[2] : z. + * + * @return an array given the size of the imageware + */ + public int[] getSize() { + int[] size = { nx, ny, nz }; + return size; + } + + /** + * Return the size in the X axis. + * + * @return the size in the X axis + */ + public int getSizeX() { + return nx; + } + + /** + * Return the size in the Y axis. + * + * @return the size in the Y axis + */ + public int getSizeY() { + return ny; + } + + /** + * Return the size in the Z axis. + * + * @return the size in the Z axis + */ + public int getSizeZ() { + return nz; + } + + /** + * Return the size in the X axis. + * + * @return the size in the X axis + */ + public int getWidth() { + return nx; + } + + /** + * Return the size in the Y axis. + * + * @return the size in the Y axis + */ + public int getHeight() { + return ny; + } + + /** + * Return the size in the Z axis. + * + * @return the size in the Z axis + */ + public int getDepth() { + return nz; + } + + /** + * Return the number of pixels in the imageware. + * + * @return number of pixels in the imageware + */ + public int getTotalSize() { + return nxy * nz; + } + + /** + * Return true is this imageware has the same size the imageware given as + * parameter. + * + * @param imageware + * imageware to be compared + * @return true if the imageware of the same size than this imageware + */ + public boolean isSameSize(ImageWare imageware) { + if (nx != imageware.getSizeX()) + return false; + if (ny != imageware.getSizeY()) + return false; + if (nz != imageware.getSizeZ()) + return false; + return true; + } + + // ------------------------------------------------------------------ + // + // put Section + // + // ------------------------------------------------------------------ + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putX(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + double buf[] = new double[bnx]; + buffer.getX(0, 0, 0, buf); + putX(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putY(int x, int y, int z, ImageWare buffer) { + int bny = buffer.getSizeY(); + double buf[] = new double[bny]; + buffer.getY(0, 0, 0, buf); + putY(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putZ(int x, int y, int z, ImageWare buffer) { + int bnz = buffer.getSizeZ(); + double buf[] = new double[bnz]; + buffer.getZ(0, 0, 0, buf); + putZ(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putXY(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bny = buffer.getSizeY(); + double buf[][] = new double[bnx][bny]; + buffer.getXY(0, 0, 0, buf); + putXY(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putXZ(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bnz = buffer.getSizeZ(); + double buf[][] = new double[bnx][bnz]; + buffer.getXZ(0, 0, 0, buf); + putXZ(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putYZ(int x, int y, int z, ImageWare buffer) { + int bny = buffer.getSizeY(); + int bnz = buffer.getSizeZ(); + double buf[][] = new double[bny][bnz]; + buffer.getYZ(0, 0, 0, buf); + putYZ(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putXYZ(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bny = buffer.getSizeY(); + int bnz = buffer.getSizeZ(); + double buf[][][] = new double[bnx][bny][bnz]; + buffer.getXYZ(0, 0, 0, buf); + putXYZ(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 1D array to put into the imageware + */ + public void putX(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + + for (int i = 0; i < leni; i++) { + tmp[offset] = (double) (buffer[i] & 0xFF); + offset++; + } + } + catch (Exception e) { + throw_put("X", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 1D array to put into the imageware + */ + public void putX(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + + for (int i = 0; i < leni; i++) { + tmp[offset] = (double) (buffer[i] & 0xFFFF); + offset++; + } + } + catch (Exception e) { + throw_put("X", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 1D array to put into the imageware + */ + public void putX(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + + for (int i = 0; i < leni; i++) { + tmp[offset] = (double) (buffer[i]); + offset++; + } + } + catch (Exception e) { + throw_put("X", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 1D array to put into the imageware + */ + public void putX(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + + System.arraycopy(buffer, 0, tmp, offset, leni); + } + catch (Exception e) { + throw_put("X", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 1D array to put into the imageware + */ + public void putY(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + for (int i = 0; i < leni; i++) { + tmp[offset] = (double) (buffer[i] & 0xFF); + offset += nx; + } + } + catch (Exception e) { + throw_put("Y", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 1D array to put into the imageware + */ + public void putY(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + for (int i = 0; i < leni; i++) { + tmp[offset] = (double) (buffer[i] & 0xFFFF); + offset += nx; + } + } + catch (Exception e) { + throw_put("Y", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 1D array to put into the imageware + */ + public void putY(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + for (int i = 0; i < leni; i++) { + tmp[offset] = (double) (buffer[i]); + offset += nx; + } + } + catch (Exception e) { + throw_put("Y", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 1D array to put into the imageware + */ + public void putY(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + for (int i = 0; i < leni; i++) { + tmp[offset] = (double) (buffer[i]); + offset += nx; + } + } + catch (Exception e) { + throw_put("Y", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * bybytete 1D array to put into the imageware + */ + public void putZ(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + ((double[]) data[z])[offset] = (double) (buffer[i] & 0xFF); + z++; + } + } + catch (Exception e) { + throw_put("Z", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byshortte 1D array to put into the imageware + */ + public void putZ(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + ((double[]) data[z])[offset] = (double) (buffer[i] & 0xFFFF); + z++; + } + } + catch (Exception e) { + throw_put("Z", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byfloatte 1D array to put into the imageware + */ + public void putZ(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + ((double[]) data[z])[offset] = (double) (buffer[i]); + z++; + } + } + catch (Exception e) { + throw_put("Z", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * bydoublete 1D array to put into the imageware + */ + public void putZ(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + ((double[]) data[z])[offset] = (double) (buffer[i]); + z++; + } + } + catch (Exception e) { + throw_put("Z", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 2D array to put into the imageware + */ + public void putXY(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (double) (buffer[i][j] & 0xFF); + } + } + } + catch (Exception e) { + throw_put("XY", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 2D array to put into the imageware + */ + public void putXY(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (double) (buffer[i][j] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_put("XY", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 2D array to put into the imageware + */ + public void putXY(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (double) (buffer[i][j]); + } + } + } + catch (Exception e) { + throw_put("XY", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 2D array to put into the imageware + */ + public void putXY(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (double) (buffer[i][j]); + } + } + } + catch (Exception e) { + throw_put("XY", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 2D array to put into the imageware + */ + public void putXZ(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + j * nx; + for (int i = 0; i < leni; i++, offset++) { + ((double[]) data[z])[offset] = (double) (buffer[i][j] & 0xFF); + } + } + } + catch (Exception e) { + throw_put("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 2D array to put into the imageware + */ + public void putXZ(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + j * nx; + for (int i = 0; i < leni; i++, offset++) { + ((double[]) data[z])[offset] = (double) (buffer[i][j] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_put("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 2D array to put into the imageware + */ + public void putXZ(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + j * nx; + for (int i = 0; i < leni; i++, offset++) { + ((double[]) data[z])[offset] = (double) (buffer[i][j]); + } + } + } + catch (Exception e) { + throw_put("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 2D array to put into the imageware + */ + public void putXZ(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + j * nx; + for (int i = 0; i < leni; i++, offset++) { + ((double[]) data[z])[offset] = (double) (buffer[i][j]); + } + } + } + catch (Exception e) { + throw_put("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 2D array to put into the imageware + */ + public void putYZ(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) + for (int i = 0; i < leni; i++, offset += nx) { + ((double[]) data[z])[offset] = (double) (buffer[i][j] & 0xFF); + } + } + catch (Exception e) { + throw_put("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 2D array to put into the imageware + */ + public void putYZ(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) + for (int i = 0; i < leni; i++, offset += nx) { + ((double[]) data[z])[offset] = (double) (buffer[i][j] & 0xFFFF); + } + } + catch (Exception e) { + throw_put("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 2D array to put into the imageware + */ + public void putYZ(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) + for (int i = 0; i < leni; i++, offset += nx) { + ((double[]) data[z])[offset] = (double) (buffer[i][j]); + } + } + catch (Exception e) { + throw_put("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 2D array to put into the imageware + */ + public void putYZ(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) + for (int i = 0; i < leni; i++, offset += nx) { + ((double[]) data[z])[offset] = (double) (buffer[i][j]); + } + } + catch (Exception e) { + throw_put("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 3D array to put into the imageware + */ + public void putXYZ(int x, int y, int z, byte[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (double) (buffer[i][j][k] & 0xFF); + } + } + } + } + catch (Exception e) { + throw_put("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 3D array to put into the imageware + */ + public void putXYZ(int x, int y, int z, short[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (double) (buffer[i][j][k] & 0xFFFF); + } + } + } + } + catch (Exception e) { + throw_put("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 3D array to put into the imageware + */ + public void putXYZ(int x, int y, int z, float[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (double) (buffer[i][j][k]); + } + } + } + } + catch (Exception e) { + throw_put("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 3D array to put into the imageware + */ + public void putXYZ(int x, int y, int z, double[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (double) (buffer[i][j][k]); + } + } + } + } + catch (Exception e) { + throw_put("XYZ", "No check", buffer, x, y, z); + } + } + + // ------------------------------------------------------------------ + // + // get Section + // + // ------------------------------------------------------------------ + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getX(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + double buf[] = new double[bnx]; + getX(x, y, z, buf); + buffer.putX(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getY(int x, int y, int z, ImageWare buffer) { + int bny = buffer.getSizeY(); + double buf[] = new double[bny]; + getY(x, y, z, buf); + buffer.putY(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getZ(int x, int y, int z, ImageWare buffer) { + int bnz = buffer.getSizeZ(); + double buf[] = new double[bnz]; + getZ(x, y, z, buf); + buffer.putZ(0, 0, 0, buf); + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getXY(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bny = buffer.getSizeY(); + double buf[][] = new double[bnx][bny]; + getXY(x, y, z, buf); + buffer.putXY(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getXZ(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bnz = buffer.getSizeZ(); + double buf[][] = new double[bnx][bnz]; + getXZ(x, y, z, buf); + buffer.putXZ(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the datase + */ + public void getYZ(int x, int y, int z, ImageWare buffer) { + int bny = buffer.getSizeY(); + int bnz = buffer.getSizeZ(); + double buf[][] = new double[bny][bnz]; + getYZ(x, y, z, buf); + buffer.putYZ(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getXYZ(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bny = buffer.getSizeY(); + int bnz = buffer.getSizeZ(); + double buf[][][] = new double[bnx][bny][bnz]; + getXYZ(x, y, z, buf); + buffer.putXYZ(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 1D array to get into the imageware + */ + public void getX(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + + for (int i = 0; i < leni; i++) { + buffer[i] = (byte) (tmp[offset]); + offset++; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 1D array to get into the imageware + */ + public void getX(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + + for (int i = 0; i < leni; i++) { + buffer[i] = (short) (tmp[offset]); + offset++; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 1D array to get into the imageware + */ + public void getX(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + + for (int i = 0; i < leni; i++) { + buffer[i] = (float) (tmp[offset]); + offset++; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 1D array to get into the imageware + */ + public void getX(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + + System.arraycopy(tmp, offset, buffer, 0, leni); + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 1D array to get into the imageware + */ + public void getY(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + for (int i = 0; i < leni; i++) { + buffer[i] = (byte) (tmp[offset]); + offset += nx; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 1D array to get into the imageware + */ + public void getY(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + for (int i = 0; i < leni; i++) { + buffer[i] = (short) (tmp[offset]); + offset += nx; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 1D array to get into the imageware + */ + public void getY(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + for (int i = 0; i < leni; i++) { + buffer[i] = (float) (tmp[offset]); + offset += nx; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 1D array to get into the imageware + */ + public void getY(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + double[] tmp = (double[]) data[z]; + for (int i = 0; i < leni; i++) { + buffer[i] = (double) (tmp[offset]); + offset += nx; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 1D array to get into the imageware + */ + public void getZ(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + buffer[i] = (byte) (((double[]) data[z])[offset]); + z++; + } + } + catch (Exception e) { + throw_get("Y", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 1D array to get into the imageware + */ + public void getZ(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + buffer[i] = (short) (((double[]) data[z])[offset]); + z++; + } + } + catch (Exception e) { + throw_get("Y", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 1D array to get into the imageware + */ + public void getZ(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + buffer[i] = (float) (((double[]) data[z])[offset]); + z++; + } + } + catch (Exception e) { + throw_get("Y", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 1D array to get into the imageware + */ + public void getZ(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + buffer[i] = (double) (((double[]) data[z])[offset]); + z++; + } + } + catch (Exception e) { + throw_get("Y", "No check", buffer, x, y, z); + } + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 2D array to get into the imageware + */ + public void getXY(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (byte) (tmp[offset]); + } + } + } + catch (Exception e) { + throw_get("XY", "No check", buffer, x, y, z); + } + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 2D array to get into the imageware + */ + public void getXY(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (short) (tmp[offset]); + } + } + } + catch (Exception e) { + throw_get("XY", "No check", buffer, x, y, z); + } + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 2D array to get into the imageware + */ + public void getXY(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (float) (tmp[offset]); + } + } + } + catch (Exception e) { + throw_get("XY", "No check", buffer, x, y, z); + } + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 2D array to get into the imageware + */ + public void getXY(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (double) (tmp[offset]); + } + } + } + catch (Exception e) { + throw_get("XY", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 2D array to get into the imageware + */ + public void getXZ(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + y * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (byte) (((double[]) data[z])[offset]); + } + } + } + catch (Exception e) { + throw_get("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 2D array to get into the imageware + */ + public void getXZ(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + y * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (short) (((double[]) data[z])[offset]); + } + } + } + catch (Exception e) { + throw_get("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 2D array to get into the imageware + */ + public void getXZ(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + y * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (float) (((double[]) data[z])[offset]); + } + } + } + catch (Exception e) { + throw_get("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 2D array to get into the imageware + */ + public void getXZ(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + y * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (double) (((double[]) data[z])[offset]); + } + } + } + catch (Exception e) { + throw_get("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 2D array to get into the datase + */ + public void getYZ(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { + for (int i = 0; i < leni; i++, offset += nx) { + buffer[i][j] = (byte) (((double[]) data[z])[offset]); + } + } + } + catch (Exception e) { + throw_get("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 2D array to get into the datase + */ + public void getYZ(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { + for (int i = 0; i < leni; i++, offset += nx) { + buffer[i][j] = (short) (((double[]) data[z])[offset]); + } + } + } + catch (Exception e) { + throw_get("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 2D array to get into the datase + */ + public void getYZ(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { + for (int i = 0; i < leni; i++, offset += nx) { + buffer[i][j] = (float) (((double[]) data[z])[offset]); + } + } + } + catch (Exception e) { + throw_get("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 2D array to get into the datase + */ + public void getYZ(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { + for (int i = 0; i < leni; i++, offset += nx) { + buffer[i][j] = (double) (((double[]) data[z])[offset]); + } + } + } + catch (Exception e) { + throw_get("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 3D array to get into the imageware + */ + public void getXYZ(int x, int y, int z, byte[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j][k] = (byte) (tmp[offset]); + } + } + } + } + catch (Exception e) { + throw_get("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 3D array to get into the imageware + */ + public void getXYZ(int x, int y, int z, short[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j][k] = (short) (tmp[offset]); + } + } + } + } + catch (Exception e) { + throw_get("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 3D array to get into the imageware + */ + public void getXYZ(int x, int y, int z, float[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j][k] = (float) (tmp[offset]); + } + } + } + } + catch (Exception e) { + throw_get("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 3D array to get into the imageware + */ + public void getXYZ(int x, int y, int z, double[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + double[] tmp = (double[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j][k] = (double) (tmp[offset]); + } + } + } + } + catch (Exception e) { + throw_get("XYZ", "No check", buffer, x, y, z); + } + } + + // ------------------------------------------------------------------ + // + // Private Section + // + // ------------------------------------------------------------------ + + /** + * Prepare a complete error message from the errors coming the constructors. + */ + protected void throw_constructor() { + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a double imageware.\n" + + "-------------------------------------------------------\n"); + } + + /** + * Prepare a complete error message from the errors coming the constructors. + */ + protected void throw_constructor(int nx, int ny, int nz) { + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a double imageware " + nx + "," + ny + + "," + nz + "].\n" + "-------------------------------------------------------\n"); + } + + /** + * Prepare a complete error message from the errors coming the get routines. + */ + protected void throw_get(String direction, String border, Object buffer, int x, int y, int z) { + int leni = 0; + int lenj = 0; + int lenk = 0; + String type = " unknown type"; + if (buffer instanceof byte[]) { + leni = ((byte[]) buffer).length; + type = " 1D byte"; + } + else if (buffer instanceof short[]) { + leni = ((short[]) buffer).length; + type = " 1D short"; + } + else if (buffer instanceof float[]) { + leni = ((float[]) buffer).length; + type = " 1D float"; + } + else if (buffer instanceof double[]) { + leni = ((double[]) buffer).length; + type = " 1D double"; + } + else if (buffer instanceof byte[][]) { + leni = ((byte[][]) buffer).length; + lenj = ((byte[][]) buffer)[0].length; + type = " 2D byte"; + } + else if (buffer instanceof short[][]) { + leni = ((short[][]) buffer).length; + lenj = ((short[][]) buffer)[0].length; + type = " 2D short"; + } + else if (buffer instanceof float[][]) { + leni = ((float[][]) buffer).length; + lenj = ((float[][]) buffer)[0].length; + type = " 2D float"; + } + else if (buffer instanceof double[][]) { + leni = ((double[][]) buffer).length; + lenj = ((double[][]) buffer)[0].length; + type = " 2D double"; + } + else if (buffer instanceof byte[][][]) { + leni = ((byte[][][]) buffer).length; + lenj = ((byte[][][]) buffer)[0].length; + lenk = ((byte[][][]) buffer)[0][0].length; + type = " 3D byte"; + } + else if (buffer instanceof short[][][]) { + leni = ((short[][][]) buffer).length; + lenj = ((short[][][]) buffer)[0].length; + lenk = ((short[][][]) buffer)[0][0].length; + type = " 3D short"; + } + else if (buffer instanceof float[][][]) { + leni = ((float[][][]) buffer).length; + lenj = ((float[][][]) buffer)[0].length; + lenk = ((float[][][]) buffer)[0][0].length; + type = " 3D float"; + } + else if (buffer instanceof double[][][]) { + leni = ((double[][][]) buffer).length; + lenj = ((double[][][]) buffer)[0].length; + lenk = ((double[][][]) buffer)[0][0].length; + type = " 3D double"; + } + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get a" + type + " buffer [" + + (leni == 0 ? "" : ("" + leni)) + (lenj == 0 ? "" : ("," + lenj)) + (lenk == 0 ? "" : ("," + lenk)) + "] \n" + "from the double imageware [" + nx + "," + ny + "," + nz + + "]\n" + "at the position (" + x + "," + y + "," + z + ") in direction " + direction + "\n" + "using " + border + ".\n" + + "-------------------------------------------------------\n"); + } + + /** + * Prepare a complete error message from the errors coming the put routines. + */ + protected void throw_put(String direction, String border, Object buffer, int x, int y, int z) { + int leni = 0; + int lenj = 0; + int lenk = 0; + String type = " unknown type"; + if (buffer instanceof byte[]) { + leni = ((byte[]) buffer).length; + type = " 1D byte"; + } + else if (buffer instanceof short[]) { + leni = ((short[]) buffer).length; + type = " 1D short"; + } + else if (buffer instanceof float[]) { + leni = ((float[]) buffer).length; + type = " 1D float"; + } + else if (buffer instanceof double[]) { + leni = ((double[]) buffer).length; + type = " 1D double"; + } + else if (buffer instanceof byte[][]) { + leni = ((byte[][]) buffer).length; + lenj = ((byte[][]) buffer)[0].length; + type = " 2D byte"; + } + else if (buffer instanceof short[][]) { + leni = ((short[][]) buffer).length; + lenj = ((short[][]) buffer)[0].length; + type = " 2D short"; + } + else if (buffer instanceof float[][]) { + leni = ((float[][]) buffer).length; + lenj = ((float[][]) buffer)[0].length; + type = " 2D float"; + } + else if (buffer instanceof double[][]) { + leni = ((double[][]) buffer).length; + lenj = ((double[][]) buffer)[0].length; + type = " 2D double"; + } + else if (buffer instanceof byte[][][]) { + leni = ((byte[][][]) buffer).length; + lenj = ((byte[][][]) buffer)[0].length; + lenk = ((byte[][][]) buffer)[0][0].length; + type = " 3D byte"; + } + else if (buffer instanceof short[][][]) { + leni = ((short[][][]) buffer).length; + lenj = ((short[][][]) buffer)[0].length; + lenk = ((short[][][]) buffer)[0][0].length; + type = " 3D short"; + } + else if (buffer instanceof float[][][]) { + leni = ((float[][][]) buffer).length; + lenj = ((float[][][]) buffer)[0].length; + lenk = ((float[][][]) buffer)[0][0].length; + type = " 3D float"; + } + else if (buffer instanceof double[][][]) { + leni = ((double[][][]) buffer).length; + lenj = ((double[][][]) buffer)[0].length; + lenk = ((double[][][]) buffer)[0][0].length; + type = " 3D double"; + } + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to put a" + type + " buffer [" + + (leni == 0 ? "" : ("" + leni)) + (lenj == 0 ? "" : ("," + lenj)) + (lenk == 0 ? "" : ("," + lenk)) + "] \n" + "into the double imageware [" + nx + "," + ny + "," + nz + + "]\n" + "at the position (" + x + "," + y + "," + z + ") in direction " + direction + "\n" + "using " + border + ".\n" + + "-------------------------------------------------------\n"); + } + + // ------------------------------------------------------------------ + // + // Get slice fast and direct access Section + // + // ------------------------------------------------------------------ + + /** + * Get a reference of the whole volume data. + * + * @return a reference of the data of this imageware + */ + public Object[] getVolume() { + return data; + } + + /** + * Get a specific slice, fast and direct access, but only for byte + * imageware. + * + * @param z + * number of the requested slice + * @return a reference of the data of one slice of this imageware + */ + public byte[] getSliceByte(int z) { + return null; + } + + /** + * Get a specific slice, fast and direct access, but only for short + * imageware. + * + * @param z + * number of the requested slice + * @return a reference of the data of one slice of this imageware + */ + public short[] getSliceShort(int z) { + return null; + } + + /** + * Get a specific slice, fast and direct access, but only for float + * imageware. + * + * @param z + * number of the requested slice + * @return a reference of the data of one slice of this imageware + */ + public float[] getSliceFloat(int z) { + return null; + } + + /** + * Get a specific slice, fast and direct access, but only for double + * imageware. + * + * @param z + * number of the requested slice + * @return a reference of the data of one slice of this imageware + */ + public double[] getSliceDouble(int z) { + return (double[]) data[z]; + } + + /** + * Allocate a buffer of size [nx,ny,nz]. + */ + private void allocate() { + try { + this.data = new Object[nz]; + this.nxy = nx * ny; + for (int z = 0; z < nz; z++) + this.data[z] = new double[nxy]; + } + catch (Exception e) { + throw_constructor(nx, ny, nz); + } + } + +} // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/DoublePointwise.java b/src/bilib/src/imageware/DoublePointwise.java new file mode 100644 index 0000000000000000000000000000000000000000..42f5b069fa9a8378ba4ba33a89fcb4993f2d0daf --- /dev/null +++ b/src/bilib/src/imageware/DoublePointwise.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import ij.process.FloatProcessor; import java.awt.Image; import java.util.Random; /** * Class DoublePointwise. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class DoublePointwise extends DoubleAccess implements Pointwise { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected DoublePointwise(int nx, int ny, int nz) { super(nx, ny, nz); } protected DoublePointwise(Image image, int mode) { super(image, mode); } protected DoublePointwise(ImageStack stack, int mode) { super(stack, mode); } protected DoublePointwise(ImageStack stack, byte chan) { super(stack, chan); } protected DoublePointwise(byte[] array, int mode) { super(array, mode); } protected DoublePointwise(byte[][] array, int mode) { super(array, mode); } protected DoublePointwise(byte[][][] array, int mode) { super(array, mode); } protected DoublePointwise(short[] array, int mode) { super(array, mode); } protected DoublePointwise(short[][] array, int mode) { super(array, mode); } protected DoublePointwise(short[][][] array, int mode) { super(array, mode); } protected DoublePointwise(float[] array, int mode) { super(array, mode); } protected DoublePointwise(float[][] array, int mode) { super(array, mode); } protected DoublePointwise(float[][][] array, int mode) { super(array, mode); } protected DoublePointwise(double[] array, int mode) { super(array, mode); } protected DoublePointwise(double[][] array, int mode) { super(array, mode); } protected DoublePointwise(double[][][] array, int mode) { super(array, mode); } /** * Fill this imageware with a constant value. * * @param value * the constant value */ public void fillConstant(double value) { double typedValue = (double) value; double[] slice = null; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) slice[k] = typedValue; } } /** * Fill this imageware with ramp. */ public void fillRamp() { int off = 0; double[] slice = null; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) slice[k] = (double) (off + k); off += nxy; } } /** * Generate a gaussian noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void fillGaussianNoise(double amplitude) { Random rnd = new Random(); double[] slice = null; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) ((rnd.nextGaussian()) * amplitude); } } } /** * Generate a uniform noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void fillUniformNoise(double amplitude) { Random rnd = new Random(); double[] slice = null; amplitude *= 2.0; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) ((rnd.nextDouble() - 0.5) * amplitude); } } } /** * Generate a salt and pepper noise. * * @param amplitudeSalt * amplitude of the salt noise * @param amplitudePepper * amplitude of the pepper noise * @param percentageSalt * percentage of the salt noise * @param percentagePepper * percentage of the pepper noise */ public void fillSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper) { Random rnd = new Random(); int index, z; if (percentageSalt > 0) { double nbSalt = nxy * nz / percentageSalt; for (int k = 0; k < nbSalt; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((double[]) data[z])[index] = (double) (rnd.nextDouble() * amplitudeSalt); } } if (percentagePepper > 0) { double nbPepper = nxy * nz / percentagePepper; for (int k = 0; k < nbPepper; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((double[]) data[z])[index] = (double) (-rnd.nextDouble() * amplitudeSalt); } } } /** * Build an ImageStack of ImageJ. */ public ImageStack buildImageStack() { ImageStack imagestack = new ImageStack(nx, ny); for (int z = 0; z < nz; z++) { FloatProcessor ip = new FloatProcessor(nx, ny); float pix[] = (float[]) ip.getPixels(); for (int k = 0; k < nxy; k++) pix[k] = (float) (((double[]) data[z])[k]); imagestack.addSlice("" + z, ip); } return imagestack; } /** * Invert the pixel intensity. */ public void invert() { double max = -Double.MAX_VALUE; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k]) > max) max = slice[k]; } } for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) (max - ((double) (slice[k]))); } } } /** * Negate the pixel intensity. */ public void negate() { double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) (-((double) (slice[k]))); } } } /** * Clip the pixel intensity into [0..255]. */ public void clip() { clip(0.0, 255.0); } /** * Clip the pixel intensity into [minLevel..maxLevel]. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void clip(double minLevel, double maxLevel) { double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; double value; double min = (double) minLevel; double max = (double) maxLevel; for (int k = 0; k < nxy; k++) { value = (double) (slice[k]); if (value < min) slice[k] = min; if (value > max) slice[k] = max; } } } /** * Rescale the pixel intensity into [0..255]. */ public void rescale() { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k]) > maxImage) maxImage = slice[k]; if ((slice[k]) < minImage) minImage = slice[k]; } } double a; if (minImage - maxImage == 0) { a = 1.0; minImage = 128.0; } else { a = 255.0 / (maxImage - minImage); } for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) (a * (((double) (slice[k])) - minImage)); } } } /** * Rescale the pixel intensity into [minLevel..maxLevel]. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void rescale(double minLevel, double maxLevel) { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k]) > maxImage) maxImage = slice[k]; if ((slice[k]) < minImage) minImage = slice[k]; } } double a; if (minImage - maxImage == 0) { a = 1.0; minImage = (maxLevel - minLevel) / 2.0; } else { a = (maxLevel - minLevel) / (maxImage - minImage); } for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) (a * (((double) (slice[k])) - minImage) + minLevel); } } } /** * Rescale the pixel intensity with a linear curve passing through * (maxLevel-minLevel)/2 at the 0 input intensity. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void rescaleCenter(double minLevel, double maxLevel) { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k]) > maxImage) maxImage = slice[k]; if ((slice[k]) < minImage) minImage = slice[k]; } } double center = (maxLevel + minLevel) / 2.0; double a; if (minImage - maxImage == 0) { a = 1.0; minImage = (maxLevel - minLevel) / 2.0; } else { if (Math.abs(maxImage) > Math.abs(minImage)) a = (maxLevel - center) / Math.abs(maxImage); else a = (center - minLevel) / Math.abs(minImage); } for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) (a * (((double) (slice[k])) - minImage) + center); } } } /** * Compute the absolute value of this imageware. */ public void abs() { double zero = (double) 0.0; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { if (slice[k] < zero) slice[k] = -slice[k]; } } } /** * Compute the log of this imageware. */ public void log() { double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) Math.log(slice[k]); } } } /** * Compute the exponential of this imageware. */ public void exp() { double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) Math.exp(slice[k]); } } } /** * Compute the square root of this imageware. */ public void sqrt() { double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) Math.sqrt(slice[k]); } } } /** * Compute the square of this imageware. */ public void sqr() { double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] *= slice[k]; } } } /** * Compute the power of a of this imageware. * * @param a * exponent */ public void pow(double a) { double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (double) Math.pow(slice[k], a); } } } /** * Add a constant value to this imageware. */ public void add(double constant) { double cst = (double) constant; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += cst; } } } /** * Multiply a constant value to this imageware. * * @param constant * the constant value */ public void multiply(double constant) { double cst = (double) constant; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] *= cst; } } } /** * Subtract a constant value to this imageware. * * @param constant * the constant value */ public void subtract(double constant) { double cst = (double) constant; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] -= cst; } } } /** * Divide by a constant value to this imageware. * * @param constant * the constant value */ public void divide(double constant) { if (constant == 0.0) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to divide because the constant is 0.\n" + "-------------------------------------------------------\n"); double cst = (double) constant; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] /= cst; } } } /** * Threshold a imageware in two levels 0 and 255. * * All the pixels values strictly greater than 'thresholdValue' and are set * to 0. The remaining values are set to 255. * * @param thresholdValue * double value given the threshold */ public void threshold(double thresholdValue) { threshold(thresholdValue, 0.0, 255.0); } /** * Threshold a imageware in two levels minLevel and maxLevel. * * All the pixels values strictly greater than 'thresholdValue' and are set * to maxLevel. The remaining values are set to minLevel. * * @param thresholdValue * double value given the threshold * @param minLevel * double value given the minimum level * @param maxLevel * double value given the maximum level */ public void threshold(double thresholdValue, double minLevel, double maxLevel) { double low = (double) (minLevel); double high = (double) (maxLevel); double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = ((double) (slice[k]) > thresholdValue ? high : low); } } } /** * Apply a soft thresholding. * * All the pixels values strictly greater than '-thresholdValue' and stricty * lower than 'thresholdValue' set to 0. The remaining positive values are * reduced by 'thresholdvalue'; the remaining negative values are augmented * by 'thresholdValue'. * * @param thresholdValue * double value given the threshold */ public void thresholdSoft(double thresholdValue) { double zero = (double) (0.0); double pixel; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { pixel = (double) (slice[k]); slice[k] = (pixel <= -thresholdValue ? (double) (pixel + thresholdValue) : (pixel > thresholdValue ? (double) (pixel - thresholdValue) : zero)); } } } /** * Apply a hard thresholding. * * All the pixels values strictly greater than '-thresholdValue' and stricty * lower than 'thresholdValue' are set to 0. The remaining values are * unchanged. * * @param thresholdValue * double value given the threshold */ public void thresholdHard(double thresholdValue) { double zero = (double) (0.0); double pixel; double[] slice; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { pixel = (double) (slice[k]); if (pixel > -thresholdValue && pixel < thresholdValue) slice[k] = zero; } } } /** * Add a gaussian noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void addGaussianNoise(double amplitude) { Random rnd = new Random(); double[] slice = null; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += (double) ((rnd.nextGaussian()) * amplitude); } } } /** * Add a uniform noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void addUniformNoise(double amplitude) { Random rnd = new Random(); double[] slice = null; amplitude *= 2.0; for (int z = 0; z < nz; z++) { slice = (double[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += (double) ((rnd.nextDouble() - 0.5) * amplitude); } } } /** * Add a salt and pepper noise. * * @param amplitudeSalt * amplitude of the salt noise * @param amplitudePepper * amplitude of the pepper noise * @param percentageSalt * percentage of the salt noise * @param percentagePepper * percentage of the pepper noise */ public void addSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper) { Random rnd = new Random(); int index, z; if (percentageSalt > 0) { double nbSalt = nxy * nz / percentageSalt; for (int k = 0; k < nbSalt; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((double[]) data[z])[index] += (double) (rnd.nextDouble() * amplitudeSalt); } } if (percentagePepper > 0) { double nbPepper = nxy * nz / percentagePepper; for (int k = 0; k < nbPepper; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((double[]) data[z])[index] -= (double) (rnd.nextDouble() * amplitudeSalt); } } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/DoubleProcess.java b/src/bilib/src/imageware/DoubleProcess.java new file mode 100644 index 0000000000000000000000000000000000000000..412d139aefcccf3dcae9442f45eaf0022c69986d --- /dev/null +++ b/src/bilib/src/imageware/DoubleProcess.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class DoubleProcess. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class DoubleProcess extends DoublePointwise implements Process { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected DoubleProcess(int nx, int ny, int nz) { super(nx, ny, nz); } protected DoubleProcess(Image image, int mode) { super(image, mode); } protected DoubleProcess(ImageStack stack, int mode) { super(stack, mode); } protected DoubleProcess(ImageStack stack, byte chan) { super(stack, chan); } protected DoubleProcess(byte[] array, int mode) { super(array, mode); } protected DoubleProcess(byte[][] array, int mode) { super(array, mode); } protected DoubleProcess(byte[][][] array, int mode) { super(array, mode); } protected DoubleProcess(short[] array, int mode) { super(array, mode); } protected DoubleProcess(short[][] array, int mode) { super(array, mode); } protected DoubleProcess(short[][][] array, int mode) { super(array, mode); } protected DoubleProcess(float[] array, int mode) { super(array, mode); } protected DoubleProcess(float[][] array, int mode) { super(array, mode); } protected DoubleProcess(float[][][] array, int mode) { super(array, mode); } protected DoubleProcess(double[] array, int mode) { super(array, mode); } protected DoubleProcess(double[][] array, int mode) { super(array, mode); } protected DoubleProcess(double[][][] array, int mode) { super(array, mode); } /** * Apply a separable gaussian smoothing over the image with the same * strengthness in all directions. To have a smmothing effect the * strengthness should be strictly greater than 0 and the size in the * considered directions should be greater strictly than 1. * * @param sigma * Strengthness of the smoothing */ public void smoothGaussian(double sigma) { smoothGaussian(sigma, sigma, sigma); } /** * Apply a separablegaussian smoothing over the image with an independant * strengthness in the different directions. To have a smmothing effect the * strengthness should be strictly greater than 0 and the size in the * considered directions should be greater strictly than 1. * * @param sigmaX * Strengthness of the smoothing in X axis * @param sigmaY * Strengthness of the smoothing in X axis * @param sigmaZ * Strengthness of the smoothing in X axis */ public void smoothGaussian(double sigmaX, double sigmaY, double sigmaZ) { int n = 3; double N = (double) n; double poles[] = new double[n]; if (nx > 1 && sigmaX > 0.0) { double s2 = sigmaX * sigmaX; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[nx]; for (int z = 0; z < nz; z++) { for (int y = 0; y < ny; y++) { getX(0, y, z, line); putX(0, y, z, Convolver.convolveIIR(line, poles)); } } } if (ny > 1 && sigmaY > 0.0) { double s2 = sigmaY * sigmaY; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[ny]; for (int x = 0; x < nx; x++) { for (int z = 0; z < nz; z++) { getY(x, 0, z, line); putY(x, 0, z, Convolver.convolveIIR(line, poles)); } } } if (nz > 1 && sigmaZ > 0.0) { double s2 = sigmaZ * sigmaZ; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[nz]; for (int y = 0; y < ny; y++) { for (int x = 0; x < nx; x++) { getZ(x, y, 0, line); putZ(x, y, 0, Convolver.convolveIIR(line, poles)); } } } } /** * Get the maximum of this imageware and a imageware. * * @param imageware * imageware to max */ public void max(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get the maximum because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { if (((double[]) data[z])[k] < (double) tmp[k]) ((double[]) data[z])[k] = (double) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { if (((double[]) data[z])[k] < (double) tmp[k]) ((double[]) data[z])[k] = (double) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { if (((double[]) data[z])[k] < (double) tmp[k]) ((double[]) data[z])[k] = (double) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { if (((double[]) data[z])[k] < (double) tmp[k]) ((double[]) data[z])[k] = (double) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Get the minimum of this imageware and a imageware. * * @param imageware * imageware to min */ public void min(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get the minimum because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { if (((double[]) data[z])[k] > (double) tmp[k]) ((double[]) data[z])[k] = (double) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { if (((double[]) data[z])[k] > (double) tmp[k]) ((double[]) data[z])[k] = (double) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { if (((double[]) data[z])[k] > (double) tmp[k]) ((double[]) data[z])[k] = (double) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { if (((double[]) data[z])[k] > (double) tmp[k]) ((double[]) data[z])[k] = (double) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Add a imageware to the current imageware. * * @param imageware * imageware to add */ public void add(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to add because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] += (double) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] += (double) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] += (double) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] += (double) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Multiply a imageware to the current imageware. * * @param imageware * imageware to multiply */ public void multiply(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to multiply because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] *= (double) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] *= (double) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] *= (double) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] *= (double) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Subtract a imageware to the current imageware. * * @param imageware * imageware to subtract */ public void subtract(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to subtract because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] -= (double) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] -= (double) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] -= (double) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] -= (double) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Divide a imageware to the current imageware. * * @param imageware * imageware to divide */ public void divide(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to divide because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] /= (double) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] /= (double) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] /= (double) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((double[]) data[z])[k] /= (double) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/DoubleSet.java b/src/bilib/src/imageware/DoubleSet.java new file mode 100644 index 0000000000000000000000000000000000000000..2d9ed25f24603f2e0385849d358e1c8142de9bbe --- /dev/null +++ b/src/bilib/src/imageware/DoubleSet.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class DoubleSet. * * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class DoubleSet extends DoubleProcess implements ImageWare { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected DoubleSet(int nx, int ny, int nz) { super(nx, ny, nz); } protected DoubleSet(Image image, int mode) { super(image, mode); } protected DoubleSet(ImageStack stack, int mode) { super(stack, mode); } protected DoubleSet(ImageStack stack, byte chan) { super(stack, chan); } protected DoubleSet(byte[] array, int mode) { super(array, mode); } protected DoubleSet(byte[][] array, int mode) { super(array, mode); } protected DoubleSet(byte[][][] array, int mode) { super(array, mode); } protected DoubleSet(short[] array, int mode) { super(array, mode); } protected DoubleSet(short[][] array, int mode) { super(array, mode); } protected DoubleSet(short[][][] array, int mode) { super(array, mode); } protected DoubleSet(float[] array, int mode) { super(array, mode); } protected DoubleSet(float[][] array, int mode) { super(array, mode); } protected DoubleSet(float[][][] array, int mode) { super(array, mode); } protected DoubleSet(double[] array, int mode) { super(array, mode); } protected DoubleSet(double[][] array, int mode) { super(array, mode); } protected DoubleSet(double[][][] array, int mode) { super(array, mode); } /** * Duplicate the imageware. * * Create a new imageware with the same size, same type and same data than * the calling one. * * @return a duplicated version of this imageware */ public ImageWare duplicate() { ImageWare out = new DoubleSet(nx, ny, nz); double[] outdata; for (int z = 0; z < nz; z++) { outdata = (double[]) (((DoubleSet) out).data[z]); System.arraycopy(data[z], 0, outdata, 0, nxy); } return out; } /** * Replicate the imageware. * * Create a new imageware with the same size, same type than the calling * one. The data are not copied. * * @return a replicated version of this imageware */ public ImageWare replicate() { return new DoubleSet(nx, ny, nz); } /** * Replicate the imageware. * * Create a new imageware with the same size and a specified type than the * calling one. The data are not copied. * * @param type * requested type * @return a replicated version of this imageware */ public ImageWare replicate(int type) { switch (type) { case ImageWare.BYTE: return new ByteSet(nx, ny, nz); case ImageWare.SHORT: return new ShortSet(nx, ny, nz); case ImageWare.FLOAT: return new FloatSet(nx, ny, nz); case ImageWare.DOUBLE: return new DoubleSet(nx, ny, nz); default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + "].\n" + "-------------------------------------------------------\n"); } } /** * Copy all the data of source in the current imageware. The source should * have the same size and same type than the calling one. * * @param source * a source imageware */ public void copy(ImageWare source) { if (nx != source.getSizeX()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + nx + " != " + source.getSizeX() + ").\n" + "-------------------------------------------------------\n"); if (ny != source.getSizeY()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + ny + " != " + source.getSizeY() + ").\n" + "-------------------------------------------------------\n"); if (nz != source.getSizeZ()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + nz + " != " + source.getSizeZ() + ").\n" + "-------------------------------------------------------\n"); if (getType() != source.getType()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same type (" + getType() + " != " + source.getType() + ").\n" + "-------------------------------------------------------\n"); double[] src; for (int z = 0; z < nz; z++) { src = (double[]) (((DoubleSet) source).data[z]); System.arraycopy(src, 0, data[z], 0, nxy); } } /** * convert the imageware in a specified type. * * Create a new imageware with the same size and converted data than the * calling one. * * @param type * indicates the type of the output * @return a converted version of this imageware */ public ImageWare convert(int type) { if (type == ImageWare.DOUBLE) return duplicate(); ImageWare out = null; switch (type) { case ImageWare.BYTE: { double[] slice; out = new ByteSet(nx, ny, nz); byte[] outslice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); outslice = ((byte[]) ((ByteSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (byte) (slice[k]); } } } break; case ImageWare.SHORT: { double[] slice; out = new ShortSet(nx, ny, nz); short[] outslice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); outslice = ((short[]) ((ShortSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (short) (slice[k]); } } } break; case ImageWare.FLOAT: { double[] slice; out = new FloatSet(nx, ny, nz); float[] outslice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); outslice = ((float[]) ((FloatSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (float) (slice[k]); } } } break; case ImageWare.DOUBLE: { double[] slice; out = new DoubleSet(nx, ny, nz); double[] outslice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); outslice = ((double[]) ((DoubleSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (double) (slice[k]); } } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + "].\n" + "-------------------------------------------------------\n"); } return out; } /** * Print information of this ImageWare object. */ public void printInfo() { System.out.println("ImageWare object information"); System.out.println("Dimension: " + getDimension()); System.out.println("Size: [" + nx + ", " + ny + ", " + nz + "]"); System.out.println("TotalSize: " + getTotalSize()); System.out.println("Type: " + getTypeToString()); System.out.println("Maximun: " + getMaximum()); System.out.println("Minimun: " + getMinimum()); System.out.println("Mean: " + getMean()); System.out.println("Norm1: " + getNorm1()); System.out.println("Norm2: " + getNorm2()); System.out.println("Total: " + getTotal()); System.out.println(""); } /** * Show this ImageWare object. */ public void show() { String title = getTypeToString(); switch (getDimension()) { case 1: title += " line"; break; case 2: title += " image"; break; case 3: title += " volume"; break; } Display.show(title, this); // ImagePlus imp = new ImagePlus(title, buildImageStack()); // imp.show(); } /** * Show the data in ImagePlus object with a specify title. * * @param title * a string given the title of the window */ public void show(String title) { Display.show(title, this); // ImagePlus imp = new ImagePlus(title, buildImageStack()); // imp.show(); } /** * Return the minimum value of this imageware. * * @return the min value of this imageware */ public double getMinimum() { double min = Double.MAX_VALUE; double[] slice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); for (int k = 0; k < nxy; k++) if ((slice[k]) < min) min = slice[k]; } return min; } /** * Return the maximum value of this imageware. * * @return the max value of this imageware */ public double getMaximum() { double max = -Double.MAX_VALUE; double[] slice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); for (int k = 0; k < nxy; k++) if ((slice[k]) > max) max = slice[k]; } return max; } /** * Return the mean value of this imageware. * * @return the mean value of this imageware */ public double getMean() { return getTotal() / (nz * nxy); } /** * Return the norm value of order 1. * * @return the norm value of this imageware in L1 sense */ public double getNorm1() { double norm = 0.0; double value = 0; double[] slice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); for (int k = 0; k < nxy; k++) { value = (double) (slice[k]); norm += (value > 0.0 ? value : -value); } } return norm; } /** * Return the norm value of order 2. * * @return the norm value of this imageware in L2 sense */ public double getNorm2() { double norm = 0.0; double[] slice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); for (int k = 0; k < nxy; k++) norm += (slice[k]) * (slice[k]); } return norm; } /** * Return the sum of all pixel in this imageware. * * @return the total sum of all pixel in this imageware */ public double getTotal() { double total = 0.0; double[] slice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); for (int k = 0; k < nxy; k++) total += slice[k]; } return total; } /** * Return the the minumum [0] and the maximum [1] value of this imageware. * Faster routine than call one getMinimum() and then one getMaximum(). * * @return an array of two values, the min and the max values of the images */ public double[] getMinMax() { double max = -Double.MAX_VALUE; double min = Double.MAX_VALUE; double[] slice; for (int z = 0; z < nz; z++) { slice = ((double[]) data[z]); for (int k = 0; k < nxy; k++) { if ((slice[k]) > max) max = slice[k]; if ((slice[k]) < min) min = slice[k]; } } double minmax[] = { min, max }; return minmax; } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/FMath.java b/src/bilib/src/imageware/FMath.java new file mode 100644 index 0000000000000000000000000000000000000000..ae00013ead516ba738d815074d336593b77a0784 --- /dev/null +++ b/src/bilib/src/imageware/FMath.java @@ -0,0 +1 @@ +package imageware; /** * Class FMath. The <b>FMath</b> class provides methods for carrying out a * number of elementary mathematical operations.<br> * <br> * * @author Erik Meijering Biomedical Imaging Group Swiss Federal Institute of * Technology Lausanne EPFL, CH-1015 Lausanne, Switzerland */ public final class FMath { /** * Returns the largest integral value that is not greater than the argument. * If the argument value is already equal to a mathematical integer, then * the result is the same as the argument. Note that the method works only * for <b>float</b> values that fall within the range spanned by the * integers. In that case, this method gives the same result as the * corresponding method in Java's <b>Math</b> class, but is in general much * faster. */ public static int floor(final float f) { if (f >= 0.0f) return (int) f; else { final int iAdd = (int) f - 1; return (((int) (f - iAdd)) + iAdd); } } /** * Returns the largest integral value that is not greater than the argument. * If the argument value is already equal to a mathematical integer, then * the result is the same as the argument. Note that the method works only * for <b>double</b> values that fall within the range spanned by the * integers. In that case, this method gives the same result as the * corresponding method in Java's <b>Math</b> class, but is in general much * faster. */ public static int floor(final double d) { if (d >= 0.0) return (int) d; else { final int iAdd = (int) d - 1; return (((int) (d - iAdd)) + iAdd); } } /** * Returns the smallest integral value that is not less than the argument. * If the argument value is already equal to a mathematical integer, then * the result is the same as the argument. Note that the method works only * for <b>float</b> values that fall within the range spanned by the * integers. In that case, this method gives the same result as the * corresponding method in Java's <b>Math</b> class, but is in general much * faster. */ public static int ceil(final float f) { final float mf = -f; if (mf >= 0.0f) return -((int) mf); else { final int iAdd = (int) mf - 1; return -(((int) (mf - iAdd)) + iAdd); } } /** * Returns the smallest integral value that is not less than the argument. * If the argument value is already equal to a mathematical integer, then * the result is the same as the argument. Note that the method works only * for <b>double</b> values that fall within the range spanned by the * integers. In that case, this method gives the same result as the * corresponding method in Java's <b>Math</b> class, but is in general much * faster. */ public static int ceil(final double d) { final double md = -d; if (md >= 0.0) return -((int) md); else { final int iAdd = (int) md - 1; return -(((int) (md - iAdd)) + iAdd); } } /** * Returns the integral value closest to the argument. Note that the method * works only for <b>float</b> values that fall within the range spanned by * the integers. In that case, this method gives the same result as the * corresponding method in Java's <b>Math</b> class, but is in general much * faster. */ public static int round(final float f) { final float f05 = f + 0.5f; if (f05 >= 0.0) return (int) f05; else { final int iAdd = (int) f05 - 1; return (((int) (f05 - iAdd)) + iAdd); } } /** * Returns the integral value closest to the argument. Note that the method * works only for <b>double</b> values that fall within the range spanned by * the integers. In that case, this method gives the same result as the * corresponding method in Java's <b>Math</b> class, but is in general much * faster. */ public static int round(final double d) { final double d05 = d + 0.5; if (d05 >= 0.0) return (int) d05; else { final int iAdd = (int) d05 - 1; return (((int) (d05 - iAdd)) + iAdd); } } /** Returns the minimum value of the two arguments. */ public static float min(final float f1, final float f2) { return ((f1 < f2) ? f1 : f2); } /** Returns the minimum value of the two arguments. */ public static double min(final double d1, final double d2) { return ((d1 < d2) ? d1 : d2); } /** Returns the minimum value of the two arguments. */ public static float max(final float f1, final float f2) { return ((f1 > f2) ? f1 : f2); } /** Returns the maximum value of the two arguments. */ public static double max(final double d1, final double d2) { return ((d1 > d2) ? d1 : d2); } } \ No newline at end of file diff --git a/src/bilib/src/imageware/FloatAccess.java b/src/bilib/src/imageware/FloatAccess.java new file mode 100644 index 0000000000000000000000000000000000000000..16823a8b13f52b2b4cff6557717d5d0263c005e8 --- /dev/null +++ b/src/bilib/src/imageware/FloatAccess.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class FloatAccess. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class FloatAccess extends FloatBuffer implements Access { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected FloatAccess(int nx, int ny, int nz) { super(nx, ny, nz); } protected FloatAccess(Image image, int mode) { super(image, mode); } protected FloatAccess(ImageStack stack, int mode) { super(stack, mode); } protected FloatAccess(ImageStack stack, byte chan) { super(stack, chan); } protected FloatAccess(byte[] array, int mode) { super(array, mode); } protected FloatAccess(byte[][] array, int mode) { super(array, mode); } protected FloatAccess(byte[][][] array, int mode) { super(array, mode); } protected FloatAccess(short[] array, int mode) { super(array, mode); } protected FloatAccess(short[][] array, int mode) { super(array, mode); } protected FloatAccess(short[][][] array, int mode) { super(array, mode); } protected FloatAccess(float[] array, int mode) { super(array, mode); } protected FloatAccess(float[][] array, int mode) { super(array, mode); } protected FloatAccess(float[][][] array, int mode) { super(array, mode); } protected FloatAccess(double[] array, int mode) { super(array, mode); } protected FloatAccess(double[][] array, int mode) { super(array, mode); } protected FloatAccess(double[][][] array, int mode) { super(array, mode); } // ------------------------------------------------------------------ // // getPixel section // // ------------------------------------------------------------------ /** * Get a pixel at specific position without specific boundary conditions * * If the positions is outside of this imageware, the method return 0.0. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a pixel value */ public double getPixel(int x, int y, int z) { if (x >= nx) return 0.0; if (y >= ny) return 0.0; if (z >= nz) return 0.0; if (x < 0) return 0.0; if (y < 0) return 0.0; if (z < 0) return 0.0; return ((float[]) data[z])[x + y * nx]; } /** * Get a pixel at specific position with specific boundary conditions * * If the positions is outside of this imageware, the method apply the * boundary conditions to return a value. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a pixel value */ public double getPixel(int x, int y, int z, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to put a pixel \n" + "at the position (" + x + "," + y + "," + z + ".\n" + "-------------------------------------------------------\n"); } int xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } return ((float[]) data[zp])[xp + yp * nx]; } /** * Get a interpolated pixel value at specific position without specific * boundary conditions. * * If the positions is not on the pixel grid, the method return a * interpolated value of the pixel (linear interpolation). If the positions * is outside of this imageware, the method return 0.0. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a interpolated value */ public double getInterpolatedPixel(double x, double y, double z) { if (x > nx - 1) return 0.0; if (y > ny - 1) return 0.0; if (z > nz - 1) return 0.0; if (x < 0) return 0.0; if (y < 0) return 0.0; if (z < 0) return 0.0; double output = 0.0; /* * int i = (x >= 0.0 ? ((int)x) : ((int)x - 1)); int j = (y >= 0.0 ? * ((int)y) : ((int)y - 1)); int k = (z >= 0.0 ? ((int)z) : ((int)z - * 1)); */ int i = (x >= 0.0 ? ((int) x) : ((int) x - 1)); int j = (y >= 0.0 ? ((int) y) : ((int) y - 1)); int k = (z >= 0.0 ? ((int) z) : ((int) z - 1)); boolean fi = (i == nx - 1); boolean fj = (j == ny - 1); boolean fk = (k == nz - 1); int index = i + j * nx; switch (getDimension()) { case 1: double v1_0 = (double) (((float[]) data[k])[index]); double v1_1 = (fi ? v1_0 : (double) (((float[]) data[k])[index + 1])); double dx1 = x - (double) i; return v1_1 * dx1 - v1_0 * (dx1 - 1.0); case 2: double v2_00 = (double) (((float[]) data[k])[index]); double v2_10 = (fi ? v2_00 : (double) (((float[]) data[k])[index + 1])); double v2_01 = (fj ? v2_00 : (double) (((float[]) data[k])[index + nx])); double v2_11 = (fi ? (fj ? v2_00 : v2_01) : (double) (((float[]) data[k])[index + 1 + nx])); double dx2 = x - (double) i; double dy2 = y - (double) j; return (dx2 * (v2_11 * dy2 - v2_10 * (dy2 - 1.0)) - (dx2 - 1.0) * (v2_01 * dy2 - v2_00 * (dy2 - 1.0))); case 3: double v3_000 = (double) (((float[]) data[k])[index]); double v3_100 = (fi ? v3_000 : (double) (((float[]) data[k])[index + 1])); double v3_010 = (fj ? v3_000 : (double) (((float[]) data[k])[index + nx])); double v3_110 = (fi ? (fj ? v3_000 : v3_010) : (double) (((float[]) data[k])[index + 1 + nx])); double v3_001 = (fk ? v3_000 : (double) (((float[]) data[k + 1])[index])); double v3_011 = (fk ? (fj ? v3_000 : v3_010) : (double) (((float[]) data[k + 1])[index + 1])); double v3_101 = (fk ? (fi ? v3_000 : v3_100) : (double) (((float[]) data[k + 1])[index + nx])); double v3_111 = (fk ? (fj ? (fi ? v3_000 : v3_100) : v3_110) : (double) (((float[]) data[k + 1])[index + 1 + nx])); double dx3 = x - (double) i; double dy3 = y - (double) j; double dz3 = z - (double) k; double z1 = (dx3 * (v3_110 * dy3 - v3_100 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_010 * dy3 - v3_000 * (dy3 - 1.0))); double z2 = (dx3 * (v3_111 * dy3 - v3_101 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_011 * dy3 - v3_001 * (dy3 - 1.0))); return z2 * dz3 - z1 * (dz3 - 1.0); } return output; } /** * Get a interpolated pixel value at specific position with specific * boundary conditions. * * If the positions is not on the pixel grid, the method return a * interpolated value of the pixel (linear interpolation). If the positions * is outside of this imageware, the method apply the boundary conditions to * return a value. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @param boundaryConditions * MIRROR or PERIODIC boundary conditions * @return a interpolated value */ public double getInterpolatedPixel(double x, double y, double z, byte boundaryConditions) { double output = 0.0; int i = (x >= 0.0 ? ((int) x) : ((int) x - 1)); int j = (y >= 0.0 ? ((int) y) : ((int) y - 1)); int k = (z >= 0.0 ? ((int) z) : ((int) z - 1)); switch (getDimension()) { case 1: double v1_0 = getPixel(i, j, k, boundaryConditions); double v1_1 = getPixel(i + 1, j, k, boundaryConditions); double dx1 = x - (double) i; return v1_1 * dx1 - v1_0 * (dx1 - 1.0); case 2: double v2_00 = getPixel(i, j, k, boundaryConditions); double v2_10 = getPixel(i + 1, j, k, boundaryConditions); double v2_01 = getPixel(i, j + 1, k, boundaryConditions); double v2_11 = getPixel(i + 1, j + 1, k, boundaryConditions); double dx2 = x - (double) i; double dy2 = y - (double) j; return (dx2 * (v2_11 * dy2 - v2_10 * (dy2 - 1.0)) - (dx2 - 1.0) * (v2_01 * dy2 - v2_00 * (dy2 - 1.0))); case 3: double v3_000 = getPixel(i, j, k, boundaryConditions); double v3_100 = getPixel(i + 1, j, k, boundaryConditions); double v3_010 = getPixel(i, j + 1, k, boundaryConditions); double v3_110 = getPixel(i + 1, j + 1, k, boundaryConditions); double v3_001 = getPixel(i, j, k + 1, boundaryConditions); double v3_011 = getPixel(i + 1, j, k + 1, boundaryConditions); double v3_101 = getPixel(i, j + 1, k + 1, boundaryConditions); double v3_111 = getPixel(i + 1, j + 1, k + 1, boundaryConditions); double dx3 = x - (double) i; double dy3 = y - (double) j; double dz3 = z - (double) k; double z1 = (dx3 * (v3_110 * dy3 - v3_100 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_010 * dy3 - v3_000 * (dy3 - 1.0))); double z2 = (dx3 * (v3_111 * dy3 - v3_101 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_011 * dy3 - v3_001 * (dy3 - 1.0))); return z2 * dz3 - z1 * (dz3 - 1.0); } return output; } // ------------------------------------------------------------------ // // putPixel section // // ------------------------------------------------------------------ /** * Put a pixel at specific position * * If the positions is outside of this imageware, the method does nothing. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis */ public void putPixel(int x, int y, int z, double value) { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; if (x < 0) return; if (y < 0) return; if (z < 0) return; ((float[]) data[z])[x + y * nx] = (float) value; } // ------------------------------------------------------------------ // // getBounded section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (short) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (float) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (double) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (short) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (float) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (double) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (((float[]) data[k])[offset]); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (short) (((float[]) data[k])[offset]); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (float) (((float[]) data[k])[offset]); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (double) (((float[]) data[k])[offset]); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); float[] tmp = (float[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (tmp[offset]); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); float[] tmp = (float[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (tmp[offset]); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); float[] tmp = (float[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (tmp[offset]); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); float[] tmp = (float[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (tmp[offset]); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (((float[]) data[z])[offset]); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (((float[]) data[z])[offset]); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (((float[]) data[z])[offset]); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (((float[]) data[z])[offset]); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (((float[]) data[z])[offset]); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (((float[]) data[z])[offset]); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (((float[]) data[z])[offset]); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (((float[]) data[z])[offset]); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, byte[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { float[] tmp = (float[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (byte) (tmp[offset]); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, short[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { float[] tmp = (float[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (short) (tmp[offset]); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, float[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { float[] tmp = (float[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (float) (tmp[offset]); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, double[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { float[] tmp = (float[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (double) (tmp[offset]); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } // ------------------------------------------------------------------ // // getBlock section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; float[] tmp = (float[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (byte) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; float[] tmp = (float[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (short) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; float[] tmp = (float[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (float) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; float[] tmp = (float[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (double) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } float[] tmp = (float[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (byte) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } float[] tmp = (float[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (short) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } float[] tmp = (float[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (float) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } float[] tmp = (float[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (double) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (byte) (((float[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (short) (((float[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (float) (((float[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (double) (((float[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = (float[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = (float[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = (float[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = (float[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (((float[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (((float[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (((float[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (((float[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (byte) (((float[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (short) (((float[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (float) (((float[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (double) (((float[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = (float[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (byte) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = (float[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (short) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = (float[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (float) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = (float[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (double) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } // ------------------------------------------------------------------ // // getBlock section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; float[] tmp = ((float[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (byte) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; float[] tmp = ((float[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (short) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; float[] tmp = ((float[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (float) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; float[] tmp = ((float[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (double) (tmp[xp + yp]); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; float[] tmp = ((float[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (byte) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; float[] tmp = ((float[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (short) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; float[] tmp = ((float[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (float) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; float[] tmp = ((float[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (double) (tmp[xp + yp * nx]); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (byte) (((float[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (short) (((float[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (float) (((float[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (double) (((float[]) data[zp])[xyp]); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; float[] tmp = ((float[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; float[] tmp = ((float[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; float[] tmp = ((float[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; float[] tmp = ((float[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (tmp[xp + yp]); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (((float[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (((float[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (((float[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (((float[]) data[zp])[xp + yp]); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (byte) (((float[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (short) (((float[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (float) (((float[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (double) (((float[]) data[zp])[xp + yp * nx]); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = ((float[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (byte) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = ((float[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (short) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = ((float[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (float) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } float[] tmp = ((float[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (double) (tmp[xp + yp]); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } // ------------------------------------------------------------------ // // putBounded section // // ------------------------------------------------------------------ /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i] & 0xFF); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i] & 0xFFFF); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i] & 0xFF); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); float[] tmp = (float[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i] & 0xFF); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i] & 0xFFFF); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i]); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i]); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); float[] tmp = (float[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i][j] & 0xFF); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); float[] tmp = (float[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i][j] & 0xFFFF); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); float[] tmp = (float[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i][j]); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); float[] tmp = (float[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i][j]); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i][j] & 0xFF); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i][j] & 0xFFFF); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i][j]); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i][j]); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i][j] & 0xFF); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i][j] & 0xFFFF); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i][j]); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((float[]) data[k])[offset] = (float) (buffer[i][j]); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, byte[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { float[] tmp = (float[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i][j][k] & 0xFF); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, short[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { float[] tmp = (float[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i][j][k] & 0xFFFF); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, float[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { float[] tmp = (float[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i][j][k]); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, double[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { float[] tmp = (float[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (float) (buffer[i][j][k]); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/FloatBuffer.java b/src/bilib/src/imageware/FloatBuffer.java new file mode 100644 index 0000000000000000000000000000000000000000..2da717da435bef43f70dc12dae12521015d9443f --- /dev/null +++ b/src/bilib/src/imageware/FloatBuffer.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import ij.process.ByteProcessor; import ij.process.ColorProcessor; import ij.process.FloatProcessor; import ij.process.ImageProcessor; import ij.process.ShortProcessor; import java.awt.Image; import java.awt.image.ImageObserver; import java.awt.image.PixelGrabber; /** * Class FloatBuffer. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class FloatBuffer implements Buffer { protected Object[] data = null; protected int nx = 0; protected int ny = 0; protected int nz = 0; protected int nxy = 0; /** * Constructor of a empty 3D float buffer. * * @param nx * size of the 3D buffer in the X axis * @param ny * size of the 3D buffer in the Y axis * @param nz * size of the 3D buffer in the Z axis */ protected FloatBuffer(int nx, int ny, int nz) { this.nx = nx; this.ny = ny; this.nz = nz; if (nx <= 0 || ny <= 0 || nz <= 0) throw_constructor(nx, ny, nz); allocate(); } /** * Constructor of a float buffer from a object Image of Java. * * @param image * source to build a new imageware */ protected FloatBuffer(Image image, int mode) { if (image == null) { throw_constructor(); } ImageObserver observer = null; this.nx = image.getWidth(observer); this.ny = image.getHeight(observer); this.nz = 1; this.nxy = nx * ny; byte[] pixels = new byte[nxy]; PixelGrabber pg = new PixelGrabber(image, 0, 0, nx, ny, false); try { pg.grabPixels(); pixels = (byte[]) (pg.getPixels()); } catch (Exception e) { throw_constructor(); } allocate(); for (int k = 0; k < nxy; k++) ((float[]) data[0])[k] = (float) (pixels[k] & 0xFF); } /** * Constructor of a float buffer from a ImageStack. * * New data are allocated if the mode is CREATE, the imageware use the data * of ImageJ if the mode is WRAP. * * @param stack * source to build a new imageware * @param mode * WRAP or CREATE */ protected FloatBuffer(ImageStack stack, int mode) { if (stack == null) { throw_constructor(); } this.nx = stack.getWidth(); this.ny = stack.getHeight(); this.nz = stack.getSize(); this.nxy = nx * ny; switch (mode) { case ImageWare.WRAP: this.data = stack.getImageArray(); break; case ImageWare.CREATE: allocate(); ImageProcessor ip = stack.getProcessor(1); if (ip instanceof ByteProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { byte[] slice = (byte[]) vol[z]; for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] = (float) (slice[k] & 0xFF); } } } else if (ip instanceof ShortProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { short[] slice = (short[]) vol[z]; for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] = (float) (slice[k] & 0xFFFF); } } } else if (ip instanceof FloatProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { float[] slice = (float[]) vol[z]; for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] = (float) slice[k]; } } } else if (ip instanceof ColorProcessor) { double r, g, b; int c; ColorProcessor cp; int[] pixels; for (int z = 0; z < nz; z++) { cp = (ColorProcessor) stack.getProcessor(z + 1); pixels = (int[]) cp.getPixels(); for (int k = 0; k < nxy; k++) { c = pixels[k]; r = (double) ((c & 0xFF0000) >> 16); g = (double) ((c & 0xFF00) >> 8); b = (double) ((c & 0xFF)); ((float[]) data[z])[k] = (float) ((r + g + b) / 3.0); } } } else { throw_constructor(); } break; default: throw_constructor(); break; } } /** * Constructor of a float buffer from a specific color channel of * ImageStack. * * New data are always allocated. If it is a gray image the imageware is * created and fill up with data of the source ImageStack. If it is a color * image only the selected channel is used to create this imageware. * * @param stack * source to build a new imageware * @param channel * RED, GREEN or BLUE */ protected FloatBuffer(ImageStack stack, byte channel) { if (stack == null) { throw_constructor(); } this.nx = stack.getWidth(); this.ny = stack.getHeight(); this.nz = stack.getSize(); this.nxy = nx * ny; allocate(); ImageProcessor ip = stack.getProcessor(1); if (ip instanceof ByteProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { byte[] slice = (byte[]) vol[z]; for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] = (float) (slice[k] & 0xFF); } } } else if (ip instanceof ShortProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { short[] slice = (short[]) vol[z]; for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] = (float) (slice[k] & 0xFFFF); } } } else if (ip instanceof FloatProcessor) { Object[] vol = stack.getImageArray(); for (int z = 0; z < nz; z++) { float[] slice = (float[]) vol[z]; for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] = (float) slice[k]; } } } else if (ip instanceof ColorProcessor) { ColorProcessor cp; int[] pixels; for (int z = 0; z < nz; z++) { cp = (ColorProcessor) stack.getProcessor(z + 1); pixels = (int[]) cp.getPixels(); switch (channel) { case ImageWare.RED: for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] = (float) ((pixels[k] & 0xFF0000) >> 16); } break; case ImageWare.GREEN: for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] = (float) ((pixels[k] & 0xFF00) >> 8); } break; case ImageWare.BLUE: for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] = (float) (pixels[k] & 0xFF); } break; default: throw_constructor(); } } } else { throw_constructor(); } } /** * Constructor of a float buffer from a byte array. * * @param array * source to build this new imageware */ protected FloatBuffer(byte[] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = 1; this.nz = 1; allocate(); putX(0, 0, 0, array); } /** * Constructor of a float buffer from a byte array. * * @param array * source to build this new imageware */ protected FloatBuffer(byte[][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = 1; allocate(); putXY(0, 0, 0, array); } /** * Constructor of a float buffer from a byte array. * * @param array * source to build this new imageware */ protected FloatBuffer(byte[][][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = array[0][0].length; allocate(); putXYZ(0, 0, 0, array); } /** * Constructor of a float buffer from a short array. * * @param array * source to build this new imageware */ protected FloatBuffer(short[] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = 1; this.nz = 1; allocate(); putX(0, 0, 0, array); } /** * Constructor of a float buffer from a short array. * * @param array * source to build this new imageware */ protected FloatBuffer(short[][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = 1; allocate(); putXY(0, 0, 0, array); } /** * Constructor of a float buffer from a short array. * * @param array * source to build this new imageware */ protected FloatBuffer(short[][][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = array[0][0].length; allocate(); putXYZ(0, 0, 0, array); } /** * Constructor of a float buffer from a float array. * * @param array * source to build this new imageware */ protected FloatBuffer(float[] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = 1; this.nz = 1; allocate(); putX(0, 0, 0, array); } /** * Constructor of a float buffer from a float array. * * @param array * source to build this new imageware */ protected FloatBuffer(float[][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = 1; allocate(); putXY(0, 0, 0, array); } /** * Constructor of a float buffer from a float array. * * @param array * source to build this new imageware */ protected FloatBuffer(float[][][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = array[0][0].length; allocate(); putXYZ(0, 0, 0, array); } /** * Constructor of a float buffer from a double array. * * @param array * source to build this new imageware */ protected FloatBuffer(double[] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = 1; this.nz = 1; allocate(); putX(0, 0, 0, array); } /** * Constructor of a float buffer from a double array. * * @param array * source to build this new imageware */ protected FloatBuffer(double[][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = 1; allocate(); putXY(0, 0, 0, array); } /** * Constructor of a float buffer from a double array. * * @param array * source to build this new imageware */ protected FloatBuffer(double[][][] array, int mode) { if (array == null) { throw_constructor(); } this.nx = array.length; this.ny = array[0].length; this.nz = array[0][0].length; allocate(); putXYZ(0, 0, 0, array); } /** * Return the type of this imageware. * * @return the type of this imageware */ public int getType() { return ImageWare.FLOAT; } /** * Return the type of this imageware in a string format. * * @return the type of this imageware translated in a string format */ public String getTypeToString() { return "Float"; } /** * Return the number of dimension of this imageware (1, 2 or 3). * * @return the number of dimension of this imageware */ public int getDimension() { int dims = 0; dims += (nx > 1 ? 1 : 0); dims += (ny > 1 ? 1 : 0); dims += (nz > 1 ? 1 : 0); return dims; } /** * Return the size of the imageware int[0] : x, int[1] : y, int[2] : z. * * @return an array given the size of the imageware */ public int[] getSize() { int[] size = { nx, ny, nz }; return size; } /** * Return the size in the X axis. * * @return the size in the X axis */ public int getSizeX() { return nx; } /** * Return the size in the Y axis. * * @return the size in the Y axis */ public int getSizeY() { return ny; } /** * Return the size in the Z axis. * * @return the size in the Z axis */ public int getSizeZ() { return nz; } /** * Return the size in the X axis. * * @return the size in the X axis */ public int getWidth() { return nx; } /** * Return the size in the Y axis. * * @return the size in the Y axis */ public int getHeight() { return ny; } /** * Return the size in the Z axis. * * @return the size in the Z axis */ public int getDepth() { return nz; } /** * Return the number of pixels in the imageware. * * @return number of pixels in the imageware */ public int getTotalSize() { return nxy * nz; } /** * Return true is this imageware has the same size the imageware given as * parameter. * * @param imageware * imageware to be compared * @return true if the imageware of the same size than this imageware */ public boolean isSameSize(ImageWare imageware) { if (nx != imageware.getSizeX()) return false; if (ny != imageware.getSizeY()) return false; if (nz != imageware.getSizeZ()) return false; return true; } // ------------------------------------------------------------------ // // put Section // // ------------------------------------------------------------------ /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putX(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); double buf[] = new double[bnx]; buffer.getX(0, 0, 0, buf); putX(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putY(int x, int y, int z, ImageWare buffer) { int bny = buffer.getSizeY(); double buf[] = new double[bny]; buffer.getY(0, 0, 0, buf); putY(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putZ(int x, int y, int z, ImageWare buffer) { int bnz = buffer.getSizeZ(); double buf[] = new double[bnz]; buffer.getZ(0, 0, 0, buf); putZ(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putXY(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bny = buffer.getSizeY(); double buf[][] = new double[bnx][bny]; buffer.getXY(0, 0, 0, buf); putXY(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putXZ(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bnz = buffer.getSizeZ(); double buf[][] = new double[bnx][bnz]; buffer.getXZ(0, 0, 0, buf); putXZ(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putYZ(int x, int y, int z, ImageWare buffer) { int bny = buffer.getSizeY(); int bnz = buffer.getSizeZ(); double buf[][] = new double[bny][bnz]; buffer.getYZ(0, 0, 0, buf); putYZ(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * ImageWare object to put into the imageware */ public void putXYZ(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bny = buffer.getSizeY(); int bnz = buffer.getSizeZ(); double buf[][][] = new double[bnx][bny][bnz]; buffer.getXYZ(0, 0, 0, buf); putXYZ(x, y, z, buf); } /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putX(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (float) (buffer[i] & 0xFF); offset++; } } catch (Exception e) { throw_put("X", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putX(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (float) (buffer[i] & 0xFFFF); offset++; } } catch (Exception e) { throw_put("X", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putX(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; System.arraycopy(buffer, 0, tmp, offset, leni); } catch (Exception e) { throw_put("X", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putX(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (float) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putY(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (float) (buffer[i] & 0xFF); offset += nx; } } catch (Exception e) { throw_put("Y", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putY(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (float) (buffer[i] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_put("Y", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putY(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (float) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putY(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { tmp[offset] = (float) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * bybytete 1D array to put into the imageware */ public void putZ(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { ((float[]) data[z])[offset] = (float) (buffer[i] & 0xFF); z++; } } catch (Exception e) { throw_put("Z", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byshortte 1D array to put into the imageware */ public void putZ(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { ((float[]) data[z])[offset] = (float) (buffer[i] & 0xFFFF); z++; } } catch (Exception e) { throw_put("Z", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byfloatte 1D array to put into the imageware */ public void putZ(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { ((float[]) data[z])[offset] = (float) (buffer[i]); z++; } } catch (Exception e) { throw_put("Z", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * bydoublete 1D array to put into the imageware */ public void putZ(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { ((float[]) data[z])[offset] = (float) (buffer[i]); z++; } } catch (Exception e) { throw_put("Z", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putXY(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (float) (buffer[i][j] & 0xFF); } } } catch (Exception e) { throw_put("XY", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putXY(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (float) (buffer[i][j] & 0xFFFF); } } } catch (Exception e) { throw_put("XY", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putXY(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (float) (buffer[i][j]); } } } catch (Exception e) { throw_put("XY", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putXY(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (float) (buffer[i][j]); } } } catch (Exception e) { throw_put("XY", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putXZ(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + j * nx; for (int i = 0; i < leni; i++, offset++) { ((float[]) data[z])[offset] = (float) (buffer[i][j] & 0xFF); } } } catch (Exception e) { throw_put("YZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putXZ(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + j * nx; for (int i = 0; i < leni; i++, offset++) { ((float[]) data[z])[offset] = (float) (buffer[i][j] & 0xFFFF); } } } catch (Exception e) { throw_put("YZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putXZ(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + j * nx; for (int i = 0; i < leni; i++, offset++) { ((float[]) data[z])[offset] = (float) (buffer[i][j]); } } } catch (Exception e) { throw_put("YZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putXZ(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + j * nx; for (int i = 0; i < leni; i++, offset++) { ((float[]) data[z])[offset] = (float) (buffer[i][j]); } } } catch (Exception e) { throw_put("YZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putYZ(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) for (int i = 0; i < leni; i++, offset += nx) { ((float[]) data[z])[offset] = (float) (buffer[i][j] & 0xFF); } } catch (Exception e) { throw_put("XZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putYZ(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) for (int i = 0; i < leni; i++, offset += nx) { ((float[]) data[z])[offset] = (float) (buffer[i][j] & 0xFFFF); } } catch (Exception e) { throw_put("XZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putYZ(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) for (int i = 0; i < leni; i++, offset += nx) { ((float[]) data[z])[offset] = (float) (buffer[i][j]); } } catch (Exception e) { throw_put("XZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putYZ(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) for (int i = 0; i < leni; i++, offset += nx) { ((float[]) data[z])[offset] = (float) (buffer[i][j]); } } catch (Exception e) { throw_put("XZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to put into the imageware */ public void putXYZ(int x, int y, int z, byte[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (float) (buffer[i][j][k] & 0xFF); } } } } catch (Exception e) { throw_put("XYZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to put into the imageware */ public void putXYZ(int x, int y, int z, short[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (float) (buffer[i][j][k] & 0xFFFF); } } } } catch (Exception e) { throw_put("XYZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to put into the imageware */ public void putXYZ(int x, int y, int z, float[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (float) (buffer[i][j][k]); } } } } catch (Exception e) { throw_put("XYZ", "No check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to put into the imageware */ public void putXYZ(int x, int y, int z, double[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { tmp[offset] = (float) (buffer[i][j][k]); } } } } catch (Exception e) { throw_put("XYZ", "No check", buffer, x, y, z); } } // ------------------------------------------------------------------ // // get Section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getX(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); double buf[] = new double[bnx]; getX(x, y, z, buf); buffer.putX(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getY(int x, int y, int z, ImageWare buffer) { int bny = buffer.getSizeY(); double buf[] = new double[bny]; getY(x, y, z, buf); buffer.putY(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getZ(int x, int y, int z, ImageWare buffer) { int bnz = buffer.getSizeZ(); double buf[] = new double[bnz]; getZ(x, y, z, buf); buffer.putZ(0, 0, 0, buf); } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getXY(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bny = buffer.getSizeY(); double buf[][] = new double[bnx][bny]; getXY(x, y, z, buf); buffer.putXY(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getXZ(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bnz = buffer.getSizeZ(); double buf[][] = new double[bnx][bnz]; getXZ(x, y, z, buf); buffer.putXZ(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the datase */ public void getYZ(int x, int y, int z, ImageWare buffer) { int bny = buffer.getSizeY(); int bnz = buffer.getSizeZ(); double buf[][] = new double[bny][bnz]; getYZ(x, y, z, buf); buffer.putYZ(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * ImageWare object to get into the imageware */ public void getXYZ(int x, int y, int z, ImageWare buffer) { int bnx = buffer.getSizeX(); int bny = buffer.getSizeY(); int bnz = buffer.getSizeZ(); double buf[][][] = new double[bnx][bny][bnz]; getXYZ(x, y, z, buf); buffer.putXYZ(0, 0, 0, buf); } /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware */ public void getX(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (byte) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware */ public void getX(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (short) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware */ public void getX(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; System.arraycopy(tmp, offset, buffer, 0, leni); } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware */ public void getX(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (double) (tmp[offset]); offset++; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware */ public void getY(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (byte) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware */ public void getY(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (short) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware */ public void getY(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (float) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware */ public void getY(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; float[] tmp = (float[]) data[z]; for (int i = 0; i < leni; i++) { buffer[i] = (double) (tmp[offset]); offset += nx; } } catch (Exception e) { throw_get("X", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware */ public void getZ(int x, int y, int z, byte[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { buffer[i] = (byte) (((float[]) data[z])[offset]); z++; } } catch (Exception e) { throw_get("Y", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware */ public void getZ(int x, int y, int z, short[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { buffer[i] = (short) (((float[]) data[z])[offset]); z++; } } catch (Exception e) { throw_get("Y", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware */ public void getZ(int x, int y, int z, float[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { buffer[i] = (float) (((float[]) data[z])[offset]); z++; } } catch (Exception e) { throw_get("Y", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware */ public void getZ(int x, int y, int z, double[] buffer) { try { int offset = x + y * nx; int leni = buffer.length; for (int i = 0; i < leni; i++) { buffer[i] = (double) (((float[]) data[z])[offset]); z++; } } catch (Exception e) { throw_get("Y", "No check", buffer, x, y, z); } } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware */ public void getXY(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (byte) (tmp[offset]); } } } catch (Exception e) { throw_get("XY", "No check", buffer, x, y, z); } } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware */ public void getXY(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (short) (tmp[offset]); } } } catch (Exception e) { throw_get("XY", "No check", buffer, x, y, z); } } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware */ public void getXY(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (float) (tmp[offset]); } } } catch (Exception e) { throw_get("XY", "No check", buffer, x, y, z); } } /** * get an array into the imageware at the position (x,y,z) in XY axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware */ public void getXY(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (y + j) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (double) (tmp[offset]); } } } catch (Exception e) { throw_get("XY", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware */ public void getXZ(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + y * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (byte) (((float[]) data[z])[offset]); } } } catch (Exception e) { throw_get("XZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware */ public void getXZ(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + y * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (short) (((float[]) data[z])[offset]); } } } catch (Exception e) { throw_get("XZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware */ public void getXZ(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + y * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (float) (((float[]) data[z])[offset]); } } } catch (Exception e) { throw_get("XZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware */ public void getXZ(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++) { offset = x + y * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j] = (double) (((float[]) data[z])[offset]); } } } catch (Exception e) { throw_get("XZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the datase */ public void getYZ(int x, int y, int z, byte[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { for (int i = 0; i < leni; i++, offset += nx) { buffer[i][j] = (byte) (((float[]) data[z])[offset]); } } } catch (Exception e) { throw_get("YZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the datase */ public void getYZ(int x, int y, int z, short[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { for (int i = 0; i < leni; i++, offset += nx) { buffer[i][j] = (short) (((float[]) data[z])[offset]); } } } catch (Exception e) { throw_get("YZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the datase */ public void getYZ(int x, int y, int z, float[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { for (int i = 0; i < leni; i++, offset += nx) { buffer[i][j] = (float) (((float[]) data[z])[offset]); } } } catch (Exception e) { throw_get("YZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the datase */ public void getYZ(int x, int y, int z, double[][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { for (int i = 0; i < leni; i++, offset += nx) { buffer[i][j] = (double) (((float[]) data[z])[offset]); } } } catch (Exception e) { throw_get("YZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware */ public void getXYZ(int x, int y, int z, byte[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j][k] = (byte) (tmp[offset]); } } } } catch (Exception e) { throw_get("XYZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware */ public void getXYZ(int x, int y, int z, short[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j][k] = (short) (tmp[offset]); } } } } catch (Exception e) { throw_get("XYZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware */ public void getXYZ(int x, int y, int z, float[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j][k] = (float) (tmp[offset]); } } } } catch (Exception e) { throw_get("XYZ", "No check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. No * check are performed if the array is outside of the imageware. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware */ public void getXYZ(int x, int y, int z, double[][][] buffer) { try { int offset = x + y * nx; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++, z++) { float[] tmp = (float[]) data[z]; for (int j = 0; j < lenj; j++) { offset = x + (j + y) * nx; for (int i = 0; i < leni; i++, offset++) { buffer[i][j][k] = (double) (tmp[offset]); } } } } catch (Exception e) { throw_get("XYZ", "No check", buffer, x, y, z); } } // ------------------------------------------------------------------ // // Private Section // // ------------------------------------------------------------------ /** * Prepare a complete error message from the errors coming the constructors. */ protected void throw_constructor() { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a float imageware.\n" + "-------------------------------------------------------\n"); } /** * Prepare a complete error message from the errors coming the constructors. */ protected void throw_constructor(int nx, int ny, int nz) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a float imageware " + nx + "," + ny + "," + nz + "].\n" + "-------------------------------------------------------\n"); } /** * Prepare a complete error message from the errors coming the get routines. */ protected void throw_get(String direction, String border, Object buffer, int x, int y, int z) { int leni = 0; int lenj = 0; int lenk = 0; String type = " unknown type"; if (buffer instanceof byte[]) { leni = ((byte[]) buffer).length; type = " 1D byte"; } else if (buffer instanceof short[]) { leni = ((short[]) buffer).length; type = " 1D short"; } else if (buffer instanceof float[]) { leni = ((float[]) buffer).length; type = " 1D float"; } else if (buffer instanceof double[]) { leni = ((double[]) buffer).length; type = " 1D double"; } else if (buffer instanceof byte[][]) { leni = ((byte[][]) buffer).length; lenj = ((byte[][]) buffer)[0].length; type = " 2D byte"; } else if (buffer instanceof short[][]) { leni = ((short[][]) buffer).length; lenj = ((short[][]) buffer)[0].length; type = " 2D short"; } else if (buffer instanceof float[][]) { leni = ((float[][]) buffer).length; lenj = ((float[][]) buffer)[0].length; type = " 2D float"; } else if (buffer instanceof double[][]) { leni = ((double[][]) buffer).length; lenj = ((double[][]) buffer)[0].length; type = " 2D double"; } else if (buffer instanceof byte[][][]) { leni = ((byte[][][]) buffer).length; lenj = ((byte[][][]) buffer)[0].length; lenk = ((byte[][][]) buffer)[0][0].length; type = " 3D byte"; } else if (buffer instanceof short[][][]) { leni = ((short[][][]) buffer).length; lenj = ((short[][][]) buffer)[0].length; lenk = ((short[][][]) buffer)[0][0].length; type = " 3D short"; } else if (buffer instanceof float[][][]) { leni = ((float[][][]) buffer).length; lenj = ((float[][][]) buffer)[0].length; lenk = ((float[][][]) buffer)[0][0].length; type = " 3D float"; } else if (buffer instanceof double[][][]) { leni = ((double[][][]) buffer).length; lenj = ((double[][][]) buffer)[0].length; lenk = ((double[][][]) buffer)[0][0].length; type = " 3D double"; } throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get a" + type + " buffer [" + (leni == 0 ? "" : ("" + leni)) + (lenj == 0 ? "" : ("," + lenj)) + (lenk == 0 ? "" : ("," + lenk)) + "] \n" + "from the float imageware [" + nx + "," + ny + "," + nz + "]\n" + "at the position (" + x + "," + y + "," + z + ") in direction " + direction + "\n" + "using " + border + ".\n" + "-------------------------------------------------------\n"); } /** * Prepare a complete error message from the errors coming the put routines. */ protected void throw_put(String direction, String border, Object buffer, int x, int y, int z) { int leni = 0; int lenj = 0; int lenk = 0; String type = " unknown type"; if (buffer instanceof byte[]) { leni = ((byte[]) buffer).length; type = " 1D byte"; } else if (buffer instanceof short[]) { leni = ((short[]) buffer).length; type = " 1D short"; } else if (buffer instanceof float[]) { leni = ((float[]) buffer).length; type = " 1D float"; } else if (buffer instanceof double[]) { leni = ((double[]) buffer).length; type = " 1D double"; } else if (buffer instanceof byte[][]) { leni = ((byte[][]) buffer).length; lenj = ((byte[][]) buffer)[0].length; type = " 2D byte"; } else if (buffer instanceof short[][]) { leni = ((short[][]) buffer).length; lenj = ((short[][]) buffer)[0].length; type = " 2D short"; } else if (buffer instanceof float[][]) { leni = ((float[][]) buffer).length; lenj = ((float[][]) buffer)[0].length; type = " 2D float"; } else if (buffer instanceof double[][]) { leni = ((double[][]) buffer).length; lenj = ((double[][]) buffer)[0].length; type = " 2D double"; } else if (buffer instanceof byte[][][]) { leni = ((byte[][][]) buffer).length; lenj = ((byte[][][]) buffer)[0].length; lenk = ((byte[][][]) buffer)[0][0].length; type = " 3D byte"; } else if (buffer instanceof short[][][]) { leni = ((short[][][]) buffer).length; lenj = ((short[][][]) buffer)[0].length; lenk = ((short[][][]) buffer)[0][0].length; type = " 3D short"; } else if (buffer instanceof float[][][]) { leni = ((float[][][]) buffer).length; lenj = ((float[][][]) buffer)[0].length; lenk = ((float[][][]) buffer)[0][0].length; type = " 3D float"; } else if (buffer instanceof double[][][]) { leni = ((double[][][]) buffer).length; lenj = ((double[][][]) buffer)[0].length; lenk = ((double[][][]) buffer)[0][0].length; type = " 3D double"; } throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to put a" + type + " buffer [" + (leni == 0 ? "" : ("" + leni)) + (lenj == 0 ? "" : ("," + lenj)) + (lenk == 0 ? "" : ("," + lenk)) + "] \n" + "into the float imageware [" + nx + "," + ny + "," + nz + "]\n" + "at the position (" + x + "," + y + "," + z + ") in direction " + direction + "\n" + "using " + border + ".\n" + "-------------------------------------------------------\n"); } // ------------------------------------------------------------------ // // Get slice fast and direct access Section // // ------------------------------------------------------------------ /** * Get a reference of the whole volume data. * * @return a reference of the data of this imageware */ public Object[] getVolume() { return data; } /** * Get a specific slice, fast and direct access, but only for byte * imageware. * * @param z * number of the requested slice * @return a reference of the data of one slice of this imageware */ public byte[] getSliceByte(int z) { return null; } /** * Get a specific slice, fast and direct access, but only for short * imageware. * * @param z * number of the requested slice * @return a reference of the data of one slice of this imageware */ public short[] getSliceShort(int z) { return null; } /** * Get a specific slice, fast and direct access, but only for float * imageware. * * @param z * number of the requested slice * @return a reference of the data of one slice of this imageware */ public float[] getSliceFloat(int z) { return (float[]) data[z]; } /** * Get a specific slice, fast and direct access, but only for double * imageware. * * @param z * number of the requested slice * @return a reference of the data of one slice of this imageware */ public double[] getSliceDouble(int z) { return null; } /** * Allocate a buffer of size [nx,ny,nz]. */ private void allocate() { try { this.data = new Object[nz]; this.nxy = nx * ny; for (int z = 0; z < nz; z++) this.data[z] = new float[nxy]; } catch (Exception e) { throw_constructor(nx, ny, nz); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/FloatPointwise.java b/src/bilib/src/imageware/FloatPointwise.java new file mode 100644 index 0000000000000000000000000000000000000000..0883b25d0a135c67b62be7589414fa78789cb992 --- /dev/null +++ b/src/bilib/src/imageware/FloatPointwise.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import ij.process.FloatProcessor; import java.awt.Image; import java.util.Random; /** * Class FloatPointwise. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class FloatPointwise extends FloatAccess implements Pointwise { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected FloatPointwise(int nx, int ny, int nz) { super(nx, ny, nz); } protected FloatPointwise(Image image, int mode) { super(image, mode); } protected FloatPointwise(ImageStack stack, int mode) { super(stack, mode); } protected FloatPointwise(ImageStack stack, byte chan) { super(stack, chan); } protected FloatPointwise(byte[] array, int mode) { super(array, mode); } protected FloatPointwise(byte[][] array, int mode) { super(array, mode); } protected FloatPointwise(byte[][][] array, int mode) { super(array, mode); } protected FloatPointwise(short[] array, int mode) { super(array, mode); } protected FloatPointwise(short[][] array, int mode) { super(array, mode); } protected FloatPointwise(short[][][] array, int mode) { super(array, mode); } protected FloatPointwise(float[] array, int mode) { super(array, mode); } protected FloatPointwise(float[][] array, int mode) { super(array, mode); } protected FloatPointwise(float[][][] array, int mode) { super(array, mode); } protected FloatPointwise(double[] array, int mode) { super(array, mode); } protected FloatPointwise(double[][] array, int mode) { super(array, mode); } protected FloatPointwise(double[][][] array, int mode) { super(array, mode); } /** * Fill this imageware with a constant value. * * @param value * the constant value */ public void fillConstant(double value) { float typedValue = (float) value; float[] slice = null; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) slice[k] = typedValue; } } /** * Fill this imageware with ramp. */ public void fillRamp() { int off = 0; float[] slice = null; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) slice[k] = (float) (off + k); off += nxy; } } /** * Generate a gaussian noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void fillGaussianNoise(double amplitude) { Random rnd = new Random(); float[] slice = null; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) ((rnd.nextGaussian()) * amplitude); } } } /** * Generate a uniform noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void fillUniformNoise(double amplitude) { Random rnd = new Random(); float[] slice = null; amplitude *= 2.0; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) ((rnd.nextDouble() - 0.5) * amplitude); } } } /** * Generate a salt and pepper noise. * * @param amplitudeSalt * amplitude of the salt noise * @param amplitudePepper * amplitude of the pepper noise * @param percentageSalt * percentage of the salt noise * @param percentagePepper * percentage of the pepper noise */ public void fillSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper) { Random rnd = new Random(); int index, z; if (percentageSalt > 0) { double nbSalt = nxy * nz / percentageSalt; for (int k = 0; k < nbSalt; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((float[]) data[z])[index] = (float) (rnd.nextDouble() * amplitudeSalt); } } if (percentagePepper > 0) { double nbPepper = nxy * nz / percentagePepper; for (int k = 0; k < nbPepper; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((float[]) data[z])[index] = (float) (-rnd.nextDouble() * amplitudeSalt); } } } /** * Build an ImageStack of ImageJ. */ public ImageStack buildImageStack() { ImageStack imagestack = new ImageStack(nx, ny); for (int z = 0; z < nz; z++) { FloatProcessor ip = new FloatProcessor(nx, ny); float pix[] = (float[]) ip.getPixels(); for (int k = 0; k < nxy; k++) pix[k] = (float) (((float[]) data[z])[k]); imagestack.addSlice("" + z, ip); } return imagestack; } /** * Invert the pixel intensity. */ public void invert() { double max = -Double.MAX_VALUE; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k]) > max) max = slice[k]; } } for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) (max - ((double) (slice[k]))); } } } /** * Negate the pixel intensity. */ public void negate() { float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) (-((double) (slice[k]))); } } } /** * Clip the pixel intensity into [0..255]. */ public void clip() { clip(0.0, 255.0); } /** * Clip the pixel intensity into [minLevel..maxLevel]. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void clip(double minLevel, double maxLevel) { float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; float value; float min = (float) minLevel; float max = (float) maxLevel; for (int k = 0; k < nxy; k++) { value = (float) (slice[k]); if (value < min) slice[k] = min; if (value > max) slice[k] = max; } } } /** * Rescale the pixel intensity into [0..255]. */ public void rescale() { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k]) > maxImage) maxImage = slice[k]; if ((slice[k]) < minImage) minImage = slice[k]; } } double a; if (minImage - maxImage == 0) { a = 1.0; minImage = 128.0; } else { a = 255.0 / (maxImage - minImage); } for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) (a * (((double) (slice[k])) - minImage)); } } } /** * Rescale the pixel intensity into [minLevel..maxLevel]. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void rescale(double minLevel, double maxLevel) { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k]) > maxImage) maxImage = slice[k]; if ((slice[k]) < minImage) minImage = slice[k]; } } double a; if (minImage - maxImage == 0) { a = 1.0; minImage = (maxLevel - minLevel) / 2.0; } else { a = (maxLevel - minLevel) / (maxImage - minImage); } for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) (a * (((double) (slice[k])) - minImage) + minLevel); } } } /** * Rescale the pixel intensity with a linear curve passing through * (maxLevel-minLevel)/2 at the 0 input intensity. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void rescaleCenter(double minLevel, double maxLevel) { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k]) > maxImage) maxImage = slice[k]; if ((slice[k]) < minImage) minImage = slice[k]; } } double center = (maxLevel + minLevel) / 2.0; double a; if (minImage - maxImage == 0) { a = 1.0; minImage = (maxLevel - minLevel) / 2.0; } else { if (Math.abs(maxImage) > Math.abs(minImage)) a = (maxLevel - center) / Math.abs(maxImage); else a = (center - minLevel) / Math.abs(minImage); } for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) (a * (((double) (slice[k])) - minImage) + center); } } } /** * Compute the absolute value of this imageware. */ public void abs() { float zero = (float) 0.0; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { if (slice[k] < zero) slice[k] = -slice[k]; } } } /** * Compute the log of this imageware. */ public void log() { float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) Math.log(slice[k]); } } } /** * Compute the exponential of this imageware. */ public void exp() { float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) Math.exp(slice[k]); } } } /** * Compute the square root of this imageware. */ public void sqrt() { float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) Math.sqrt(slice[k]); } } } /** * Compute the square of this imageware. */ public void sqr() { float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] *= slice[k]; } } } /** * Compute the power of a of this imageware. * * @param a * exponent */ public void pow(double a) { float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (float) Math.pow(slice[k], a); } } } /** * Add a constant value to this imageware. */ public void add(double constant) { float cst = (float) constant; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += cst; } } } /** * Multiply a constant value to this imageware. * * @param constant * the constant value */ public void multiply(double constant) { float cst = (float) constant; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] *= cst; } } } /** * Subtract a constant value to this imageware. * * @param constant * the constant value */ public void subtract(double constant) { float cst = (float) constant; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] -= cst; } } } /** * Divide by a constant value to this imageware. * * @param constant * the constant value */ public void divide(double constant) { if (constant == 0.0) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to divide because the constant is 0.\n" + "-------------------------------------------------------\n"); float cst = (float) constant; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] /= cst; } } } /** * Threshold a imageware in two levels 0 and 255. * * All the pixels values strictly greater than 'thresholdValue' and are set * to 0. The remaining values are set to 255. * * @param thresholdValue * double value given the threshold */ public void threshold(double thresholdValue) { threshold(thresholdValue, 0.0, 255.0); } /** * Threshold a imageware in two levels minLevel and maxLevel. * * All the pixels values strictly greater than 'thresholdValue' and are set * to maxLevel. The remaining values are set to minLevel. * * @param thresholdValue * double value given the threshold * @param minLevel * double value given the minimum level * @param maxLevel * double value given the maximum level */ public void threshold(double thresholdValue, double minLevel, double maxLevel) { float low = (float) (minLevel); float high = (float) (maxLevel); float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = ((double) (slice[k]) > thresholdValue ? high : low); } } } /** * Apply a soft thresholding. * * All the pixels values strictly greater than '-thresholdValue' and stricty * lower than 'thresholdValue' set to 0. The remaining positive values are * reduced by 'thresholdvalue'; the remaining negative values are augmented * by 'thresholdValue'. * * @param thresholdValue * double value given the threshold */ public void thresholdSoft(double thresholdValue) { float zero = (float) (0.0); double pixel; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { pixel = (double) (slice[k]); slice[k] = (pixel <= -thresholdValue ? (float) (pixel + thresholdValue) : (pixel > thresholdValue ? (float) (pixel - thresholdValue) : zero)); } } } /** * Apply a hard thresholding. * * All the pixels values strictly greater than '-thresholdValue' and stricty * lower than 'thresholdValue' are set to 0. The remaining values are * unchanged. * * @param thresholdValue * double value given the threshold */ public void thresholdHard(double thresholdValue) { float zero = (float) (0.0); double pixel; float[] slice; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { pixel = (double) (slice[k]); if (pixel > -thresholdValue && pixel < thresholdValue) slice[k] = zero; } } } /** * Add a gaussian noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void addGaussianNoise(double amplitude) { Random rnd = new Random(); float[] slice = null; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += (float) ((rnd.nextGaussian()) * amplitude); } } } /** * Add a uniform noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void addUniformNoise(double amplitude) { Random rnd = new Random(); float[] slice = null; amplitude *= 2.0; for (int z = 0; z < nz; z++) { slice = (float[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += (float) ((rnd.nextDouble() - 0.5) * amplitude); } } } /** * Add a salt and pepper noise. * * @param amplitudeSalt * amplitude of the salt noise * @param amplitudePepper * amplitude of the pepper noise * @param percentageSalt * percentage of the salt noise * @param percentagePepper * percentage of the pepper noise */ public void addSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper) { Random rnd = new Random(); int index, z; if (percentageSalt > 0) { double nbSalt = nxy * nz / percentageSalt; for (int k = 0; k < nbSalt; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((float[]) data[z])[index] += (float) (rnd.nextDouble() * amplitudeSalt); } } if (percentagePepper > 0) { double nbPepper = nxy * nz / percentagePepper; for (int k = 0; k < nbPepper; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((float[]) data[z])[index] -= (float) (rnd.nextDouble() * amplitudeSalt); } } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/FloatProcess.java b/src/bilib/src/imageware/FloatProcess.java new file mode 100644 index 0000000000000000000000000000000000000000..bfdf542e50351f7830972edf6ef7790d9924a2a4 --- /dev/null +++ b/src/bilib/src/imageware/FloatProcess.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class FloatProcess. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class FloatProcess extends FloatPointwise implements Process { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected FloatProcess(int nx, int ny, int nz) { super(nx, ny, nz); } protected FloatProcess(Image image, int mode) { super(image, mode); } protected FloatProcess(ImageStack stack, int mode) { super(stack, mode); } protected FloatProcess(ImageStack stack, byte chan) { super(stack, chan); } protected FloatProcess(byte[] array, int mode) { super(array, mode); } protected FloatProcess(byte[][] array, int mode) { super(array, mode); } protected FloatProcess(byte[][][] array, int mode) { super(array, mode); } protected FloatProcess(short[] array, int mode) { super(array, mode); } protected FloatProcess(short[][] array, int mode) { super(array, mode); } protected FloatProcess(short[][][] array, int mode) { super(array, mode); } protected FloatProcess(float[] array, int mode) { super(array, mode); } protected FloatProcess(float[][] array, int mode) { super(array, mode); } protected FloatProcess(float[][][] array, int mode) { super(array, mode); } protected FloatProcess(double[] array, int mode) { super(array, mode); } protected FloatProcess(double[][] array, int mode) { super(array, mode); } protected FloatProcess(double[][][] array, int mode) { super(array, mode); } /** * Apply a separable gaussian smoothing over the image with the same * strengthness in all directions. To have a smmothing effect the * strengthness should be strictly greater than 0 and the size in the * considered directions should be greater strictly than 1. * * @param sigma * Strengthness of the smoothing */ public void smoothGaussian(double sigma) { smoothGaussian(sigma, sigma, sigma); } /** * Apply a separablegaussian smoothing over the image with an independant * strengthness in the different directions. To have a smmothing effect the * strengthness should be strictly greater than 0 and the size in the * considered directions should be greater strictly than 1. * * @param sigmaX * Strengthness of the smoothing in X axis * @param sigmaY * Strengthness of the smoothing in X axis * @param sigmaZ * Strengthness of the smoothing in X axis */ public void smoothGaussian(double sigmaX, double sigmaY, double sigmaZ) { int n = 3; double N = (double) n; double poles[] = new double[n]; if (nx > 1 && sigmaX > 0.0) { double s2 = sigmaX * sigmaX; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[nx]; for (int z = 0; z < nz; z++) { for (int y = 0; y < ny; y++) { getX(0, y, z, line); putX(0, y, z, Convolver.convolveIIR(line, poles)); } } } if (ny > 1 && sigmaY > 0.0) { double s2 = sigmaY * sigmaY; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[ny]; for (int x = 0; x < nx; x++) { for (int z = 0; z < nz; z++) { getY(x, 0, z, line); putY(x, 0, z, Convolver.convolveIIR(line, poles)); } } } if (nz > 1 && sigmaZ > 0.0) { double s2 = sigmaZ * sigmaZ; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[nz]; for (int y = 0; y < ny; y++) { for (int x = 0; x < nx; x++) { getZ(x, y, 0, line); putZ(x, y, 0, Convolver.convolveIIR(line, poles)); } } } } /** * Get the maximum of this imageware and a imageware. * * @param imageware * imageware to max */ public void max(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get the maximum because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { if (((float[]) data[z])[k] < (float) tmp[k]) ((float[]) data[z])[k] = (float) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { if (((float[]) data[z])[k] < (float) tmp[k]) ((float[]) data[z])[k] = (float) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { if (((float[]) data[z])[k] < (float) tmp[k]) ((float[]) data[z])[k] = (float) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { if (((float[]) data[z])[k] < (float) tmp[k]) ((float[]) data[z])[k] = (float) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Get the minimum of this imageware and a imageware. * * @param imageware * imageware to min */ public void min(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get the minimum because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { if (((float[]) data[z])[k] > (float) tmp[k]) ((float[]) data[z])[k] = (float) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { if (((float[]) data[z])[k] > (float) tmp[k]) ((float[]) data[z])[k] = (float) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { if (((float[]) data[z])[k] > (float) tmp[k]) ((float[]) data[z])[k] = (float) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { if (((float[]) data[z])[k] > (float) tmp[k]) ((float[]) data[z])[k] = (float) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Add a imageware to the current imageware. * * @param imageware * imageware to add */ public void add(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to add because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] += (float) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] += (float) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] += (float) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] += (float) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Multiply a imageware to the current imageware. * * @param imageware * imageware to multiply */ public void multiply(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to multiply because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] *= (float) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] *= (float) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] *= (float) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] *= (float) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Subtract a imageware to the current imageware. * * @param imageware * imageware to subtract */ public void subtract(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to subtract because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] -= (float) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] -= (float) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] -= (float) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] -= (float) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Divide a imageware to the current imageware. * * @param imageware * imageware to divide */ public void divide(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to divide because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] /= (float) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] /= (float) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] /= (float) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((float[]) data[z])[k] /= (float) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/FloatSet.java b/src/bilib/src/imageware/FloatSet.java new file mode 100644 index 0000000000000000000000000000000000000000..706b92217f203b4e0a60f3bfc7ecb959cdd1f2c1 --- /dev/null +++ b/src/bilib/src/imageware/FloatSet.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class FloatSet. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class FloatSet extends FloatProcess implements ImageWare { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected FloatSet(int nx, int ny, int nz) { super(nx, ny, nz); } protected FloatSet(Image image, int mode) { super(image, mode); } protected FloatSet(ImageStack stack, int mode) { super(stack, mode); } protected FloatSet(ImageStack stack, byte chan) { super(stack, chan); } protected FloatSet(byte[] array, int mode) { super(array, mode); } protected FloatSet(byte[][] array, int mode) { super(array, mode); } protected FloatSet(byte[][][] array, int mode) { super(array, mode); } protected FloatSet(short[] array, int mode) { super(array, mode); } protected FloatSet(short[][] array, int mode) { super(array, mode); } protected FloatSet(short[][][] array, int mode) { super(array, mode); } protected FloatSet(float[] array, int mode) { super(array, mode); } protected FloatSet(float[][] array, int mode) { super(array, mode); } protected FloatSet(float[][][] array, int mode) { super(array, mode); } protected FloatSet(double[] array, int mode) { super(array, mode); } protected FloatSet(double[][] array, int mode) { super(array, mode); } protected FloatSet(double[][][] array, int mode) { super(array, mode); } /** * Duplicate the imageware. * * Create a new imageware with the same size, same type and same data than * the calling one. * * @return a duplicated version of this imageware */ public ImageWare duplicate() { ImageWare out = new FloatSet(nx, ny, nz); float[] outdata; for (int z = 0; z < nz; z++) { outdata = (float[]) (((FloatSet) out).data[z]); System.arraycopy(data[z], 0, outdata, 0, nxy); } return out; } /** * Replicate the imageware. * * Create a new imageware with the same size, same type than the calling * one. The data are not copied. * * @return a replicated version of this imageware */ public ImageWare replicate() { return new FloatSet(nx, ny, nz); } /** * Replicate the imageware. * * Create a new imageware with the same size and a specified type than the * calling one. The data are not copied. * * @param type * requested type * @return a replicated version of this imageware */ public ImageWare replicate(int type) { switch (type) { case ImageWare.BYTE: return new ByteSet(nx, ny, nz); case ImageWare.SHORT: return new ShortSet(nx, ny, nz); case ImageWare.FLOAT: return new FloatSet(nx, ny, nz); case ImageWare.DOUBLE: return new DoubleSet(nx, ny, nz); default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + "].\n" + "-------------------------------------------------------\n"); } } /** * Copy all the data of source in the current imageware. The source should * have the same size and same type than the calling one. * * @param source * a source imageware */ public void copy(ImageWare source) { if (nx != source.getSizeX()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + nx + " != " + source.getSizeX() + ").\n" + "-------------------------------------------------------\n"); if (ny != source.getSizeY()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + ny + " != " + source.getSizeY() + ").\n" + "-------------------------------------------------------\n"); if (nz != source.getSizeZ()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + nz + " != " + source.getSizeZ() + ").\n" + "-------------------------------------------------------\n"); if (getType() != source.getType()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same type (" + getType() + " != " + source.getType() + ").\n" + "-------------------------------------------------------\n"); float[] src; for (int z = 0; z < nz; z++) { src = (float[]) (((FloatSet) source).data[z]); System.arraycopy(src, 0, data[z], 0, nxy); } } /** * convert the imageware in a specified type. * * Create a new imageware with the same size and converted data than the * calling one. * * @param type * indicates the type of the output * @return a converted version of this imageware */ public ImageWare convert(int type) { if (type == ImageWare.FLOAT) return duplicate(); ImageWare out = null; switch (type) { case ImageWare.BYTE: { float[] slice; out = new ByteSet(nx, ny, nz); byte[] outslice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); outslice = ((byte[]) ((ByteSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (byte) (slice[k]); } } } break; case ImageWare.SHORT: { float[] slice; out = new ShortSet(nx, ny, nz); short[] outslice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); outslice = ((short[]) ((ShortSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (short) (slice[k]); } } } break; case ImageWare.FLOAT: { float[] slice; out = new FloatSet(nx, ny, nz); float[] outslice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); outslice = ((float[]) ((FloatSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (float) (slice[k]); } } } break; case ImageWare.DOUBLE: { float[] slice; out = new DoubleSet(nx, ny, nz); double[] outslice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); outslice = ((double[]) ((DoubleSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (double) (slice[k]); } } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + "].\n" + "-------------------------------------------------------\n"); } return out; } /** * Print information of this ImageWare object. */ public void printInfo() { System.out.println("ImageWare object information"); System.out.println("Dimension: " + getDimension()); System.out.println("Size: [" + nx + ", " + ny + ", " + nz + "]"); System.out.println("TotalSize: " + getTotalSize()); System.out.println("Type: " + getTypeToString()); System.out.println("Maximun: " + getMaximum()); System.out.println("Minimun: " + getMinimum()); System.out.println("Mean: " + getMean()); System.out.println("Norm1: " + getNorm1()); System.out.println("Norm2: " + getNorm2()); System.out.println("Total: " + getTotal()); System.out.println(""); } /** * Show this ImageWare object. */ public void show() { String title = getTypeToString(); switch (getDimension()) { case 1: title += " line"; break; case 2: title += " image"; break; case 3: title += " volume"; break; } Display.show(title, this); // ImagePlus imp = new ImagePlus(title, buildImageStack()); // imp.show(); } /** * Show the data in ImagePlus object with a specify title. * * @param title * a string given the title of the window */ public void show(String title) { Display.show(title, this); // ImagePlus imp = new ImagePlus(title, buildImageStack()); // imp.show(); } /** * Return the minimum value of this imageware. * * @return the min value of this imageware */ public double getMinimum() { double min = Double.MAX_VALUE; float[] slice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); for (int k = 0; k < nxy; k++) if ((slice[k]) < min) min = slice[k]; } return min; } /** * Return the maximum value of this imageware. * * @return the max value of this imageware */ public double getMaximum() { double max = -Double.MAX_VALUE; float[] slice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); for (int k = 0; k < nxy; k++) if ((slice[k]) > max) max = slice[k]; } return max; } /** * Return the mean value of this imageware. * * @return the mean value of this imageware */ public double getMean() { return getTotal() / (nz * nxy); } /** * Return the norm value of order 1. * * @return the norm value of this imageware in L1 sense */ public double getNorm1() { double norm = 0.0; double value = 0; float[] slice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); for (int k = 0; k < nxy; k++) { value = (double) (slice[k]); norm += (value > 0.0 ? value : -value); } } return norm; } /** * Return the norm value of order 2. * * @return the norm value of this imageware in L2 sense */ public double getNorm2() { double norm = 0.0; float[] slice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); for (int k = 0; k < nxy; k++) norm += (slice[k]) * (slice[k]); } return norm; } /** * Return the sum of all pixel in this imageware. * * @return the total sum of all pixel in this imageware */ public double getTotal() { double total = 0.0; float[] slice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); for (int k = 0; k < nxy; k++) total += slice[k]; } return total; } /** * Return the the minumum [0] and the maximum [1] value of this imageware. * Faster routine than call one getMinimum() and then one getMaximum(). * * @return an array of two values, the min and the max values of the images */ public double[] getMinMax() { double max = -Double.MAX_VALUE; double min = Double.MAX_VALUE; float[] slice; for (int z = 0; z < nz; z++) { slice = ((float[]) data[z]); for (int k = 0; k < nxy; k++) { if ((slice[k]) > max) max = slice[k]; if ((slice[k]) < min) min = slice[k]; } } double minmax[] = { min, max }; return minmax; } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/ImageAccess.java b/src/bilib/src/imageware/ImageAccess.java new file mode 100644 index 0000000000000000000000000000000000000000..2a3222786a13367dde412fad6cf284168a2b9d75 --- /dev/null +++ b/src/bilib/src/imageware/ImageAccess.java @@ -0,0 +1 @@ +package imageware; import ij.ImagePlus; import ij.process.ByteProcessor; import ij.process.ColorProcessor; import ij.process.FloatProcessor; import ij.process.ImageProcessor; import ij.process.ShortProcessor; /** * ImageAccess is an interface layer to facilitate the access to the pixels of * ImageJ images. Methods of ImageAccess provides an easy and robust way to * access to the pixels of images. * * The data are stored in an double array. Many methods get/put allows to access * to the data. If the user try to access outside of the image, the mirror * boundary conditions are applied. * * This version of ImageAccess is based on the imageware library. * * @author Daniel Sage Biomedical Imaging Group Swiss Federal Institute of * Technology Lausanne EPFL, CH-1015 Lausanne, Switzerland */ public class ImageAccess extends Object { public static final int PATTERN_SQUARE_3x3 = 0; public static final int PATTERN_CROSS_3x3 = 1; private ImageWare imageware = null; private int nx = 0; private int ny = 0; /** * Creates a new ImageAccess object from a 2D double array of pixels. The * size of the array determines the size of the image. * * @param array * an array of pixel (2D) */ public ImageAccess(double[][] array) { if (array == null) throw new ArrayStoreException("Constructor: array == null."); imageware = Builder.create(array); this.nx = imageware.getSizeX(); this.ny = imageware.getSizeY(); } /** * Creates a new object of the class ImageAccess from an ImageProcessor * object. * * ImageProcessor object contains the image data, the size and the type of * the image. The ImageProcessor is provided by ImageJ, it should by a * 8-bit, 16-bit. * * @param ip * an ImageProcessor object provided by ImageJ */ public ImageAccess(ImageProcessor ip) { if (ip == null) throw new ArrayStoreException("Constructor: ImageProcessor == null."); ImagePlus imp = new ImagePlus("", ip); if (ip instanceof ByteProcessor) imageware = Builder.create(imp, ImageWare.DOUBLE); else if (ip instanceof ShortProcessor) imageware = Builder.create(imp, ImageWare.DOUBLE); else if (ip instanceof FloatProcessor) imageware = Builder.create(imp, ImageWare.DOUBLE); this.nx = imageware.getSizeX(); this.ny = imageware.getSizeY(); } /** * Creates a new object of the class ImageAccess from an ColorProcessor * object. * * ImageProcessor object contains the image data, the size and the type of * the image. The ColorProcessor is provided by ImageJ, The ImageAccess * contains one plane (red, green or blue) selected with the colorPlane * parameter. * * @param cp * an ColorProcessor object * @param colorPlane * index of the color plane 0, 1 or 2 */ public ImageAccess(ColorProcessor cp, int colorPlane) { if (cp == null) throw new ArrayStoreException("Constructor: ColorProcessor == null."); if (colorPlane < 0) throw new ArrayStoreException("Constructor: colorPlane < 0."); if (colorPlane > 2) throw new ArrayStoreException("Constructor: colorPlane > 2."); this.nx = cp.getWidth(); this.ny = cp.getHeight(); ImagePlus imp = new ImagePlus("", cp); imageware = new DoubleSet(imp.getStack(), (byte) colorPlane); } /** * Creates a new object of the class tImageAccess. * * The size of the image are given as parameter. The data pixels are empty * and are not initialized. * * @param nx * the size of the image along the X-axis * @param ny * the size of the image along the Y-axis */ public ImageAccess(int nx, int ny) { imageware = new DoubleSet(nx, ny, 1); this.nx = nx; this.ny = ny; } /** * Return the imageware of the image. * * @return the imageware object */ public ImageWare getDataset() { return imageware; } /** * Return the width of the image. * * @return the image width */ public int getWidth() { return nx; } /** * Return the height of the image. * * @return the image height */ public int getHeight() { return ny; } /** * Return the maximum value of ImageAccess. * * @return the maximum value */ public double getMaximum() { return imageware.getMaximum(); } /** * Return the minimum value of ImageAccess. * * @return the minimum value */ public double getMinimum() { return imageware.getMinimum(); } /** * Return the mean value of ImageAccess. * * @return the mean value */ public double getMean() { return imageware.getMean(); } /** * Returns a copy of the pixel data organize in a 2D array. * * @return the 2D double array */ public double[][] getArrayPixels() { double[][] array = new double[nx][ny]; imageware.getXY(0, 0, 0, array); return array; } /** * Returns a reference to the pixel data in double (1D). * * @return the 1D double array */ public double[] getPixels() { return imageware.getSliceDouble(0); } /** * Create a FloatProcessor from the pixel data. * * @return the FloatProcessor */ public FloatProcessor createFloatProcessor() { FloatProcessor fp = new FloatProcessor(nx, ny); double[] pixels = getPixels(); int size = pixels.length; float[] fsrc = new float[size]; for (int k = 0; k < size; k++) fsrc[k] = (float) (pixels[k]); fp.setPixels(fsrc); return fp; } /** * Create a ByteProcessor from the pixel data. * * @return the ByteProcessor */ public ByteProcessor createByteProcessor() { ByteProcessor bp = new ByteProcessor(nx, ny); double[] pixels = getPixels(); int size = pixels.length; byte[] bsrc = new byte[size]; double p; for (int k = 0; k < size; k++) { p = pixels[k]; if (p < 0) p = 0.0; if (p > 255.0) p = 255.0; bsrc[k] = (byte) p; } bp.setPixels(bsrc); return bp; } /** * Create a new ImageAccess object by duplication of the current the * ImageAccess object. * * @return a new ImageAccess object **/ public ImageAccess duplicate() { double[][] array = new double[nx][ny]; imageware.getXY(0, 0, 0, array); ImageAccess ia = new ImageAccess(array); return ia; } /** * An ImageAccess object calls this method for getting the gray level of a * selected pixel. * * Mirror border conditions are applied. * * @param x * input, the integer x-coordinate of a pixel * @param y * input, the integer y-coordinate of a pixel * @return the gray level of the pixel (double) */ public double getPixel(int x, int y) { return imageware.getPixel(x, y, 0, ImageWare.MIRROR); } /** * An ImageAccess object calls this method for getting the gray level of a * selected pixel using a bilinear interpolation. The coordinates can be * given in double and the bilinear interpolation is applied the find the * gray level. * * Mirror border conditions are applied. * * @param x * input, the double x-coordinate of a pixel * @param y * input, the double y-coordinate of a pixel * @return the gray level of the pixel (double) */ public double getInterpolatedPixel(double x, double y) { return imageware.getInterpolatedPixel(x, y, 0, ImageWare.MIRROR); } /** * An ImageAccess object calls this method for getting a whole column of the * image. * * The column should already created with the correct size [ny]. * * @param x * input, the integer x-coordinate of a column * @param column * output, an array of the type double */ public void getColumn(int x, double[] column) { if (x < 0) throw new IndexOutOfBoundsException("getColumn: x < 0."); if (x >= nx) throw new IndexOutOfBoundsException("getColumn: x >= nx."); if (column == null) throw new ArrayStoreException("getColumn: column == null."); if (column.length != ny) throw new ArrayStoreException("getColumn: column.length != ny."); imageware.getBlockY(x, 0, 0, column, ImageWare.MIRROR); } /** * An ImageAccess object calls this method for getting a part of column. The * starting point is given by the y parameter and the ending determine by * the size of the column parameter. The column parameter should already * created. * * @param x * input, the integer x-coordinate of a column * @param y * input, starting point * @param column * output, an array of the type double */ public void getColumn(int x, int y, double[] column) { if (x < 0) throw new IndexOutOfBoundsException("getColumn: x < 0."); if (x >= nx) throw new IndexOutOfBoundsException("getColumn: x >= nx."); if (column == null) throw new ArrayStoreException("getColumn: column == null."); imageware.getBlockY(x, y, 0, column, ImageWare.MIRROR); } /** * An ImageAccess object calls this method for getting a whole row of the * image. * * The row should already created with the correct size [nx]. * * @param y * input, the integer y-coordinate of a row * @param row * output, an array of the type double */ public void getRow(int y, double[] row) { if (y < 0) throw new IndexOutOfBoundsException("getRow: y < 0."); if (y >= ny) throw new IndexOutOfBoundsException("getRow: y >= ny."); if (row == null) throw new ArrayStoreException("getColumn: row == null."); if (row.length != nx) throw new ArrayStoreException("getColumn: row.length != nx."); imageware.getBlockX(0, y, 0, row, ImageWare.MIRROR); } /** * An ImageAccess object calls this method for getting a part of row. The * starting point is given by the y parameter and the ending determine by * the size of the row parameter. The row parameter should already created. * * @param x * input, starting point * @param y * input, the integer y-coordinate of a row * @param row * output, an array of the type double */ public void getRow(int x, int y, double[] row) { if (y < 0) throw new IndexOutOfBoundsException("getRow: y < 0."); if (y >= ny) throw new IndexOutOfBoundsException("getRow: y >= ny."); if (row == null) throw new ArrayStoreException("getRow: row == null."); imageware.getBlockX(x, y, 0, row, ImageWare.MIRROR); } /** * An ImageAccess object calls this method for getting a neighborhood * arround a pixel position. * * The neigh parameter should already created. The size of the array * determines the neighborhood block. * * <br> * Mirror border conditions are applied. <br> * <br> * The pixel value of (x-n/2, y-n/2) is put into neigh[0][0] <br> * ... <br> * The pixel value of (x+n/2, y+n/2) is put into neigh[n-1][n-1] <br> * <br> * For example if neigh is a double[4][4]: <br> * The pixel value of (x-1, y-1) is put into neigh[0][0] <br> * The pixel value of (x , y ) is put into neigh[1][1] <br> * The pixel value of (x+1, y+1) is put into neigh[2][2] <br> * The pixel value of (x+2, y+2) is put into neigh[3][3] <br> * ... <br> * For example if neigh is a double[5][5]: <br> * The pixel value of (x-2, y-2) is put into neigh[0][0] <br> * The pixel value of (x-1, y-1) is put into neigh[1][1] <br> * The pixel value of (x , y ) is put into neigh[2][2] <br> * The pixel value of (x+1, y+1) is put into neigh[3][3] <br> * The pixel value of (x+2, y+2) is put into neigh[4][4] * * @param x * the integer x-coordinate of a selected central pixel * @param y * the integer y-coordinate of a selected central pixel * @param neigh * output, a 2D array s */ public void getNeighborhood(int x, int y, double neigh[][]) { imageware.getNeighborhoodXY(x, y, 0, neigh, ImageWare.MIRROR); } /** * An ImageAccess object calls this method for getting a neighborhood of a * predefined pattern around a selected pixel (x,y). <br> * The available patterns are: <br> * - a 3*3 block: PATTERN_SQUARE_3x3 (8-connect) <br> * - a 3*3 cross: PATTERN_CROSS_3x3 (4-connect) <br> * <br> * Mirror border conditions are applied. <br> * The pixel is arranged in a 1D array according the following rules: <br> * <br> * If the pattern is PATTERN_SQUARE_3x3 (8-connect) <br> * The pixel value of (x-1, y-1) are put into neigh[0] <br> * The pixel value of (x , y-1) are put into neigh[1] <br> * The pixel value of (x+1, y-1) are put into neigh[2] <br> * The pixel value of (x-1, y ) are put into neigh[3] <br> * The pixel value of (x , y ) are put into neigh[4] <br> * The pixel value of (x+1, y ) are put into neigh[5] <br> * The pixel value of (x-1, y+1) are put into neigh[6] <br> * The pixel value of (x , y+1) are put into neigh[7] <br> * The pixel value of (x+1, y+1) are put into neigh[8] <br> * <br> * If the pattern is PATTERN_CROSS_3x3 (4-connect) <br> * The pixel value of (x , y-1) are put into neigh[0] <br> * The pixel value of (x-1, y ) are put into neigh[1] <br> * The pixel value of (x , y ) are put into neigh[2] <br> * The pixel value of (x+1, y ) are put into neigh[3] <br> * The pixel value of (x , y+1) are put into neigh[4] <br> * <br> * The neigh should already created as a double array of 9 elements for the * PATTERN_SQUARE_3x3 or 5 elements for the PATTERN_CROSS_3x3. * * @param x * x-coordinate of a selected central pixel * @param y * y-coordinate of a selected central pixel * @param neigh * output, an array consisting of 9 or 5 elements * @param pattern * PATTERN_SQUARE_3x3 or PATTERN_CROSS_3x3. */ public void getPattern(int x, int y, double neigh[], int pattern) { if (neigh == null) throw new ArrayStoreException("getPattern: neigh == null."); double block[][] = new double[3][3]; imageware.getNeighborhoodXY(x, y, 0, block, ImageWare.MIRROR); switch (pattern) { case PATTERN_SQUARE_3x3: if (neigh.length != 9) throw new ArrayStoreException("getPattern: neigh.length != 9."); neigh[0] = block[0][0]; neigh[1] = block[1][0]; neigh[2] = block[2][0]; neigh[3] = block[0][1]; neigh[4] = block[1][1]; neigh[5] = block[2][1]; neigh[6] = block[0][2]; neigh[7] = block[1][2]; neigh[8] = block[2][2]; break; case PATTERN_CROSS_3x3: if (neigh.length != 5) throw new ArrayStoreException("getPattern: neigh.length != 5"); neigh[0] = block[1][0]; neigh[1] = block[0][1]; neigh[2] = block[1][1]; neigh[3] = block[2][1]; neigh[4] = block[0][1]; break; default: throw new ArrayStoreException("getPattern: unexpected pattern."); } } /** * An ImageAccess object calls this method to get a sub-image with the upper * left corner in the coordinate (x,y). * * The sub-image ouptut should be already created. * * @param x * x-coordinate in the source image * @param y * y-coordinate in the source image * @param output * an ImageAccess object with the sub-image; */ public void getSubImage(int x, int y, ImageAccess output) { if (output == null) throw new ArrayStoreException("getSubImage: output == null."); if (x < 0) throw new ArrayStoreException("getSubImage: Incompatible image size"); if (y < 0) throw new ArrayStoreException("getSubImage: Incompatible image size"); if (x >= nx) throw new ArrayStoreException("getSubImage: Incompatible image size"); if (y >= ny) throw new ArrayStoreException("getSubImage: Incompatible image size"); int nxcopy = output.getWidth(); int nycopy = output.getHeight(); double[][] neigh = new double[nxcopy][nycopy]; imageware.getBlockXY(x, y, 0, neigh, ImageWare.MIRROR); output.putArrayPixels(neigh); } /** * An ImageAccess object calls this method in order a value of the gray * level to be put to a position inside it given by the coordinates. * * @param x * input, the integer x-coordinate of a pixel * @param y * input, the integer y-coordinate of a pixel * @param value * input, a value of the gray level of the type double */ public void putPixel(int x, int y, double value) { if (x < 0) throw new IndexOutOfBoundsException("putPixel: x < 0"); if (x >= nx) throw new IndexOutOfBoundsException("putPixel: x >= nx"); if (y < 0) throw new IndexOutOfBoundsException("putPixel: y < 0"); if (y >= ny) throw new IndexOutOfBoundsException("putPixel: y >= ny"); imageware.putPixel(x, y, 0, value); } /** * An ImageAccess object calls this method to put a whole column in a * specified position into the image. * * @param x * input, the integer x-coordinate of a column * @param column * input, an array of the type double */ public void putColumn(int x, double[] column) { if (x < 0) throw new IndexOutOfBoundsException("putColumn: x < 0."); if (x >= nx) throw new IndexOutOfBoundsException("putColumn: x >= nx."); if (column == null) throw new ArrayStoreException("putColumn: column == null."); if (column.length != ny) throw new ArrayStoreException("putColumn: column.length != ny."); imageware.putBoundedY(x, 0, 0, column); } /** * An ImageAccess object calls this method to put a part of column into the * image. The starting poisition in given by y and the ending position is * determined by the size of the column array. * * @param x * input, the integer x-coordinate of a column * @param y * input, the integer y-coordinate of a column * @param column * input, an array of the type double */ public void putColumn(int x, int y, double[] column) { if (x < 0) throw new IndexOutOfBoundsException("putColumn: x < 0."); if (x >= nx) throw new IndexOutOfBoundsException("putColumn: x >= nx."); if (column == null) throw new ArrayStoreException("putColumn: column == null."); imageware.putBoundedY(x, y, 0, column); } /** * An ImageAccess object calls this method to put a whole row in a specified * position into the image. * * @param y * input, the integer x-coordinate of a column * @param row * input, an array of the type double */ public void putRow(int y, double[] row) { if (y < 0) throw new IndexOutOfBoundsException("putRow: y < 0."); if (y >= ny) throw new IndexOutOfBoundsException("putRow: y >= ny."); if (row == null) throw new ArrayStoreException("putRow: row == null."); if (row.length != nx) throw new ArrayStoreException("putRow: row.length != nx."); imageware.putBoundedX(0, y, 0, row); } /** * An ImageAccess object calls this method to put a part of row into the * image. The starting poisition in given by x and the ending position is * determined by the size of the row array. * * @param x * input, the integer x-coordinate of a column * @param y * input, the integer y-coordinate of a column * @param row * input, an array of the type double */ public void putRow(int x, int y, double[] row) { if (y < 0) throw new IndexOutOfBoundsException("putRow: y < 0."); if (y >= ny) throw new IndexOutOfBoundsException("putRow: y >= ny."); if (row == null) throw new ArrayStoreException("putRow: row == null."); imageware.putBoundedX(x, y, 0, row); } /** * An ImageAccess object calls this method in order to put an 2D array of * double in an ImageAccess. * * @param array * input, the double array */ public void putArrayPixels(double[][] array) { if (array == null) throw new IndexOutOfBoundsException("putArrayPixels: array == null."); imageware.putBoundedXY(0, 0, 0, array); } /** * An ImageAccess object calls this method to put a sub-image with the upper * left corner in the coordinate (x,y). * * The sub-image input should be already created. * * @param x * x-coordinate in the source image * @param y * y-coordinate in the source image * @param input * an ImageAccess object that we want to put; */ public void putSubImage(int x, int y, ImageAccess input) { if (input == null) throw new ArrayStoreException("putSubImage: input == null."); if (x < 0) throw new IndexOutOfBoundsException("putSubImage: x < 0."); if (y < 0) throw new IndexOutOfBoundsException("putSubImage: y < 0."); if (x >= nx) throw new IndexOutOfBoundsException("putSubImage: x >= nx."); if (y >= ny) throw new IndexOutOfBoundsException("putSubImage: y >= ny."); double[][] sub = input.getArrayPixels(); imageware.putBoundedXY(x, y, 0, sub); } /** * An ImageAccess object calls this method to set a constant value to all * pixels of the image. * * @param constant * a constant value */ public void setConstant(double constant) { imageware.fillConstant(constant); } /** * Stretches the contrast inside an image so that the gray levels are in the * range 0 to 255. */ public void normalizeContrast() { imageware.rescale(); } /** * Display an image at a specific position (x, y). * * @param title * a string for the title * @param loc * Point for the location */ public void show(String title, java.awt.Point loc) { FloatProcessor fp = createFloatProcessor(); fp.resetMinAndMax(); ImagePlus impResult = new ImagePlus(title, fp); ij.gui.ImageWindow window = impResult.getWindow(); window.setLocation(loc.x, loc.y); impResult.show(); } /** * Display an image. * * @param title * a string for the title of the window */ public void show(String title) { imageware.show(title); } /** * Compute the absolute value. */ public void abs() { imageware.abs(); } /** * Compute the square root of an ImageAccess. */ public void sqrt() { imageware.sqrt(); } /** * Raised an ImageAccess object to the power a. * * @param a * input */ public void pow(final double a) { imageware.pow(a); } /** * An ImageAccess object calls this method for adding a constant to each * pixel. * * @param constant * a constant to be added */ public void add(double constant) { imageware.add(constant); } /** * An ImageAccess object calls this method for multiplying a constant to * each pixel. * * @param constant * a constant to be multiplied */ public void multiply(final double constant) { imageware.multiply(constant); } /** * An ImageAccess object calls this method for adding a constant to each * pixel. * * @param constant * a constant to be added */ public void subtract(final double constant) { imageware.add(-constant); } /** * An ImageAccess object calls this method for dividing a constant to each * pixel. * * @param constant * a constant to be multiplied */ public void divide(final double constant) { if (constant == 0.0) throw new ArrayStoreException("divide: Divide by 0"); imageware.multiply(1.0 / constant); } /** * An ImageAccess object calls this method for adding two ImageAccess * objects. * * [this = im1 + im2] * * The resulting ImageAccess and the two operands should have the same size. * * @param im1 * an ImageAccess object to be added * @param im2 * an ImageAccess object to be added */ public void add(ImageAccess im1, ImageAccess im2) { if (im1.getWidth() != nx) throw new ArrayStoreException("add: incompatible size."); if (im1.getHeight() != ny) throw new ArrayStoreException("add: incompatible size."); if (im2.getWidth() != nx) throw new ArrayStoreException("add: incompatible size."); if (im2.getHeight() != ny) throw new ArrayStoreException("add: incompatible size."); imageware.copy(im1.getDataset()); imageware.add(im2.getDataset()); } /** * An ImageAccess object calls this method for multiplying two ImageAccess * objects. * * The resulting ImageAccess and the two operands should have the same size. * * [this = im1 * im2] * * @param im1 * an ImageAccess object to be multiplied * @param im2 * an ImageAccess object to be multiplied */ public void multiply(ImageAccess im1, ImageAccess im2) { if (im1.getWidth() != nx) throw new ArrayStoreException("multiply: incompatible size."); if (im1.getHeight() != ny) throw new ArrayStoreException("multiply: incompatible size."); if (im2.getWidth() != nx) throw new ArrayStoreException("multiply: incompatible size."); if (im2.getHeight() != ny) throw new ArrayStoreException("multiply: incompatible size."); imageware.copy(im1.getDataset()); imageware.multiply(im2.getDataset()); } /** * An ImageAccess object calls this method for subtracting two ImageAccess * objects. * * The resulting ImageAccess and the two operands should have the same size. * * [this = im1 - im2] * * @param im1 * an ImageAccess object to be subtracted * @param im2 * an ImageAccess object to be subtracted */ public void subtract(ImageAccess im1, ImageAccess im2) { if (im1.getWidth() != nx) throw new ArrayStoreException("subtract: incompatible size."); if (im1.getHeight() != ny) throw new ArrayStoreException("subtract: incompatible size."); if (im2.getWidth() != nx) throw new ArrayStoreException("subtract: incompatible size."); if (im2.getHeight() != ny) throw new ArrayStoreException("subtract: incompatible size."); imageware.copy(im1.getDataset()); imageware.subtract(im2.getDataset()); } /** * An ImageAccess object calls this method for dividing two ImageAccess * objects. * * [this = im1 / im2] * * The resulting ImageAccess and the two operands should have the same size. * * @param im1 * numerator * @param im2 * denominator */ public void divide(ImageAccess im1, ImageAccess im2) { if (im1.getWidth() != nx) throw new ArrayStoreException("divide: incompatible size."); if (im1.getHeight() != ny) throw new ArrayStoreException("divide: incompatible size."); if (im2.getWidth() != nx) throw new ArrayStoreException("divide: incompatible size."); if (im2.getHeight() != ny) throw new ArrayStoreException("divide: incompatible size."); imageware.copy(im1.getDataset()); imageware.divide(im2.getDataset()); } } // end of class ImageAccess \ No newline at end of file diff --git a/src/bilib/src/imageware/ImageWare.java b/src/bilib/src/imageware/ImageWare.java new file mode 100644 index 0000000000000000000000000000000000000000..885f8ced701b8b49d6f136480ea9589743856040 --- /dev/null +++ b/src/bilib/src/imageware/ImageWare.java @@ -0,0 +1,62 @@ +package imageware; + +/** + * Class ImageWare. + * + * + * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de + * Lausanne, Lausanne, Switzerland + */ + +public interface ImageWare extends Process { + + public static final int UNDEFINED_TYPE = 0; + public static final int BYTE = 1; + public static final int SHORT = 2; + public static final int FLOAT = 3; + public static final int DOUBLE = 4; + + public static final byte UNDEFINED_BOUNDARY = 0; + public static final byte NONE = 1; + public static final byte MIRROR = 2; + public static final byte PERIODIC = 3; + + public static final int UNDEFINED = 0; + public static final int CREATE = 1; + public static final int WRAP = 2; + + public static final byte RED = 0; + public static final byte GREEN = 1; + public static final byte BLUE = 2; + + public ImageWare duplicate(); + + public ImageWare replicate(); + + public ImageWare replicate(int type); + + public void copy(ImageWare source); + + public ImageWare convert(int type); + + public void printInfo(); + + public void show(); + + public void show(String title); + + public double getMinimum(); + + public double getMaximum(); + + public double getMean(); + + public double getNorm1(); + + public double getNorm2(); + + public double getTotal(); + + public double[] getMinMax(); + +} diff --git a/src/bilib/src/imageware/Pointwise.java b/src/bilib/src/imageware/Pointwise.java new file mode 100644 index 0000000000000000000000000000000000000000..60c7698de433045f4c97a35e3caafdac632e37cf --- /dev/null +++ b/src/bilib/src/imageware/Pointwise.java @@ -0,0 +1,72 @@ +package imageware; + +import ij.ImageStack; + +/** + * Class Pointwise. + * + * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de + * Lausanne, Lausanne, Switzerland + */ + +public interface Pointwise extends Access { + public void fillConstant(double value); + + public void fillRamp(); + + public void fillGaussianNoise(double amplitude); + + public void fillUniformNoise(double amplitude); + + public void fillSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper); + + public ImageStack buildImageStack(); + + public void invert(); + + public void negate(); + + public void rescale(); + + public void clip(); + + public void clip(double minLevel, double maxLevel); + + public void rescale(double minLevel, double maxLevel); + + public void rescaleCenter(double minLevel, double maxLevel); + + public void abs(); + + public void log(); + + public void exp(); + + public void sqrt(); + + public void sqr(); + + public void pow(double a); + + public void add(double constant); + + public void multiply(double constant); + + public void subtract(double constant); + + public void divide(double constant); + + public void threshold(double thresholdValue); + + public void threshold(double thresholdValue, double minLevel, double maxLevel); + + public void thresholdHard(double thresholdValue); + + public void thresholdSoft(double thresholdValue); + + public void addGaussianNoise(double amplitude); + + public void addUniformNoise(double amplitude); + + public void addSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper); +} diff --git a/src/bilib/src/imageware/Process.java b/src/bilib/src/imageware/Process.java new file mode 100644 index 0000000000000000000000000000000000000000..47209c45018802d54dc2a8c811a4ffbf3d63532d --- /dev/null +++ b/src/bilib/src/imageware/Process.java @@ -0,0 +1,27 @@ +package imageware; + +/** + * Class Process. + * + * + * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de + * Lausanne, Lausanne, Switzerland + */ + +public interface Process extends Pointwise { + public void smoothGaussian(double sigma); + + public void smoothGaussian(double sigmaX, double sigmaY, double sigmaZ); + + public void max(ImageWare imageware); + + public void min(ImageWare imageware); + + public void add(ImageWare imageware); + + public void multiply(ImageWare imageware); + + public void subtract(ImageWare imageware); + + public void divide(ImageWare imageware); +} diff --git a/src/bilib/src/imageware/ShortAccess.java b/src/bilib/src/imageware/ShortAccess.java new file mode 100644 index 0000000000000000000000000000000000000000..e24d4f69970c6abfaa84310384b71d6f4447ea2f --- /dev/null +++ b/src/bilib/src/imageware/ShortAccess.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class ShortAccess. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class ShortAccess extends ShortBuffer implements Access { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected ShortAccess(int nx, int ny, int nz) { super(nx, ny, nz); } protected ShortAccess(Image image, int mode) { super(image, mode); } protected ShortAccess(ImageStack stack, int mode) { super(stack, mode); } protected ShortAccess(ImageStack stack, byte chan) { super(stack, chan); } protected ShortAccess(byte[] array, int mode) { super(array, mode); } protected ShortAccess(byte[][] array, int mode) { super(array, mode); } protected ShortAccess(byte[][][] array, int mode) { super(array, mode); } protected ShortAccess(short[] array, int mode) { super(array, mode); } protected ShortAccess(short[][] array, int mode) { super(array, mode); } protected ShortAccess(short[][][] array, int mode) { super(array, mode); } protected ShortAccess(float[] array, int mode) { super(array, mode); } protected ShortAccess(float[][] array, int mode) { super(array, mode); } protected ShortAccess(float[][][] array, int mode) { super(array, mode); } protected ShortAccess(double[] array, int mode) { super(array, mode); } protected ShortAccess(double[][] array, int mode) { super(array, mode); } protected ShortAccess(double[][][] array, int mode) { super(array, mode); } // ------------------------------------------------------------------ // // getPixel section // // ------------------------------------------------------------------ /** * Get a pixel at specific position without specific boundary conditions * * If the positions is outside of this imageware, the method return 0.0. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a pixel value */ public double getPixel(int x, int y, int z) { if (x >= nx) return 0.0; if (y >= ny) return 0.0; if (z >= nz) return 0.0; if (x < 0) return 0.0; if (y < 0) return 0.0; if (z < 0) return 0.0; return ((short[]) data[z])[x + y * nx] & 0xFFFF; } /** * Get a pixel at specific position with specific boundary conditions * * If the positions is outside of this imageware, the method apply the * boundary conditions to return a value. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a pixel value */ public double getPixel(int x, int y, int z, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to put a pixel \n" + "at the position (" + x + "," + y + "," + z + ".\n" + "-------------------------------------------------------\n"); } int xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } return ((short[]) data[zp])[xp + yp * nx] & 0xFFFF; } /** * Get a interpolated pixel value at specific position without specific * boundary conditions. * * If the positions is not on the pixel grid, the method return a * interpolated value of the pixel (linear interpolation). If the positions * is outside of this imageware, the method return 0.0. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @return a interpolated value */ public double getInterpolatedPixel(double x, double y, double z) { if (x > nx - 1) return 0.0; if (y > ny - 1) return 0.0; if (z > nz - 1) return 0.0; if (x < 0) return 0.0; if (y < 0) return 0.0; if (z < 0) return 0.0; double output = 0.0; /* * int i = (x >= 0.0 ? ((int)x) : ((int)x - 1)); int j = (y >= 0.0 ? * ((int)y) : ((int)y - 1)); int k = (z >= 0.0 ? ((int)z) : ((int)z - * 1)); */ int i = (x >= 0.0 ? ((int) x) : ((int) x - 1)); int j = (y >= 0.0 ? ((int) y) : ((int) y - 1)); int k = (z >= 0.0 ? ((int) z) : ((int) z - 1)); boolean fi = (i == nx - 1); boolean fj = (j == ny - 1); boolean fk = (k == nz - 1); int index = i + j * nx; switch (getDimension()) { case 1: double v1_0 = (double) (((short[]) data[k])[index] & 0xFFFF); double v1_1 = (fi ? v1_0 : (double) (((short[]) data[k])[index + 1] & 0xFFFF)); double dx1 = x - (double) i; return v1_1 * dx1 - v1_0 * (dx1 - 1.0); case 2: double v2_00 = (double) (((short[]) data[k])[index] & 0xFFFF); double v2_10 = (fi ? v2_00 : (double) (((short[]) data[k])[index + 1] & 0xFFFF)); double v2_01 = (fj ? v2_00 : (double) (((short[]) data[k])[index + nx] & 0xFFFF)); double v2_11 = (fi ? (fj ? v2_00 : v2_01) : (double) (((short[]) data[k])[index + 1 + nx] & 0xFFFF)); double dx2 = x - (double) i; double dy2 = y - (double) j; return (dx2 * (v2_11 * dy2 - v2_10 * (dy2 - 1.0)) - (dx2 - 1.0) * (v2_01 * dy2 - v2_00 * (dy2 - 1.0))); case 3: double v3_000 = (double) (((short[]) data[k])[index] & 0xFFFF); double v3_100 = (fi ? v3_000 : (double) (((short[]) data[k])[index + 1] & 0xFFFF)); double v3_010 = (fj ? v3_000 : (double) (((short[]) data[k])[index + nx] & 0xFFFF)); double v3_110 = (fi ? (fj ? v3_000 : v3_010) : (double) (((short[]) data[k])[index + 1 + nx] & 0xFFFF)); double v3_001 = (fk ? v3_000 : (double) (((short[]) data[k + 1])[index] & 0xFFFF)); double v3_011 = (fk ? (fj ? v3_000 : v3_010) : (double) (((short[]) data[k + 1])[index + 1] & 0xFFFF)); double v3_101 = (fk ? (fi ? v3_000 : v3_100) : (double) (((short[]) data[k + 1])[index + nx] & 0xFFFF)); double v3_111 = (fk ? (fj ? (fi ? v3_000 : v3_100) : v3_110) : (double) (((short[]) data[k + 1])[index + 1 + nx] & 0xFFFF)); double dx3 = x - (double) i; double dy3 = y - (double) j; double dz3 = z - (double) k; double z1 = (dx3 * (v3_110 * dy3 - v3_100 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_010 * dy3 - v3_000 * (dy3 - 1.0))); double z2 = (dx3 * (v3_111 * dy3 - v3_101 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_011 * dy3 - v3_001 * (dy3 - 1.0))); return z2 * dz3 - z1 * (dz3 - 1.0); } return output; } /** * Get a interpolated pixel value at specific position with specific * boundary conditions. * * If the positions is not on the pixel grid, the method return a * interpolated value of the pixel (linear interpolation). If the positions * is outside of this imageware, the method apply the boundary conditions to * return a value. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis * @param boundaryConditions * MIRROR or PERIODIC boundary conditions * @return a interpolated value */ public double getInterpolatedPixel(double x, double y, double z, byte boundaryConditions) { double output = 0.0; int i = (x >= 0.0 ? ((int) x) : ((int) x - 1)); int j = (y >= 0.0 ? ((int) y) : ((int) y - 1)); int k = (z >= 0.0 ? ((int) z) : ((int) z - 1)); switch (getDimension()) { case 1: double v1_0 = getPixel(i, j, k, boundaryConditions); double v1_1 = getPixel(i + 1, j, k, boundaryConditions); double dx1 = x - (double) i; return v1_1 * dx1 - v1_0 * (dx1 - 1.0); case 2: double v2_00 = getPixel(i, j, k, boundaryConditions); double v2_10 = getPixel(i + 1, j, k, boundaryConditions); double v2_01 = getPixel(i, j + 1, k, boundaryConditions); double v2_11 = getPixel(i + 1, j + 1, k, boundaryConditions); double dx2 = x - (double) i; double dy2 = y - (double) j; return (dx2 * (v2_11 * dy2 - v2_10 * (dy2 - 1.0)) - (dx2 - 1.0) * (v2_01 * dy2 - v2_00 * (dy2 - 1.0))); case 3: double v3_000 = getPixel(i, j, k, boundaryConditions); double v3_100 = getPixel(i + 1, j, k, boundaryConditions); double v3_010 = getPixel(i, j + 1, k, boundaryConditions); double v3_110 = getPixel(i + 1, j + 1, k, boundaryConditions); double v3_001 = getPixel(i, j, k + 1, boundaryConditions); double v3_011 = getPixel(i + 1, j, k + 1, boundaryConditions); double v3_101 = getPixel(i, j + 1, k + 1, boundaryConditions); double v3_111 = getPixel(i + 1, j + 1, k + 1, boundaryConditions); double dx3 = x - (double) i; double dy3 = y - (double) j; double dz3 = z - (double) k; double z1 = (dx3 * (v3_110 * dy3 - v3_100 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_010 * dy3 - v3_000 * (dy3 - 1.0))); double z2 = (dx3 * (v3_111 * dy3 - v3_101 * (dy3 - 1.0)) - (dx3 - 1.0) * (v3_011 * dy3 - v3_001 * (dy3 - 1.0))); return z2 * dz3 - z1 * (dz3 - 1.0); } return output; } // ------------------------------------------------------------------ // // putPixel section // // ------------------------------------------------------------------ /** * Put a pixel at specific position * * If the positions is outside of this imageware, the method does nothing. * * @param x * position in the X axis * @param y * position in the Y axis * @param z * position in the Z axis */ public void putPixel(int x, int y, int z, double value) { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; if (x < 0) return; if (y < 0) return; if (z < 0) return; ((short[]) data[z])[x + y * nx] = (short) value; } // ------------------------------------------------------------------ // // getBounded section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (tmp[offset] & 0xFFFF); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (short) (tmp[offset] & 0xFFFF); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (float) (tmp[offset] & 0xFFFF); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedX(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (double) (tmp[offset] & 0xFFFF); offset++; } } catch (Exception e) { throw_get("X", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (tmp[offset] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (short) (tmp[offset] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (float) (tmp[offset] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedY(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { buffer[i] = (double) (tmp[offset] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_get("Y", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (byte) (((short[]) data[k])[offset] & 0xFFFF); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (short) (((short[]) data[k])[offset] & 0xFFFF); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (float) (((short[]) data[k])[offset] & 0xFFFF); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to get into the imageware */ public void getBoundedZ(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { buffer[i] = (double) (((short[]) data[k])[offset] & 0xFFFF); k++; } } catch (Exception e) { throw_get("Z", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); short[] tmp = (short[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (tmp[offset] & 0xFFFF); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); short[] tmp = (short[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (tmp[offset] & 0xFFFF); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); short[] tmp = (short[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (tmp[offset] & 0xFFFF); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedXY(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); short[] tmp = (short[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (tmp[offset] & 0xFFFF); offset++; } } } catch (Exception e) { throw_get("XY", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (((short[]) data[z])[offset] & 0xFFFF); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (((short[]) data[z])[offset] & 0xFFFF); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (((short[]) data[z])[offset] & 0xFFFF); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedXZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (((short[]) data[z])[offset] & 0xFFFF); offset++; } k++; } } catch (Exception e) { throw_get("YZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (byte) (((short[]) data[z])[offset] & 0xFFFF); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (short) (((short[]) data[z])[offset] & 0xFFFF); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (float) (((short[]) data[z])[offset] & 0xFFFF); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to get into the imageware */ public void getBoundedYZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j] = (double) (((short[]) data[z])[offset] & 0xFFFF); offset += nx; } k++; } } catch (Exception e) { throw_get("XZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, byte[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { short[] tmp = (short[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (byte) (tmp[offset] & 0xFFFF); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, short[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { short[] tmp = (short[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (short) (tmp[offset] & 0xFFFF); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, float[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { short[] tmp = (short[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (float) (tmp[offset] & 0xFFFF); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } /** * Get an array from the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to get into the imageware */ public void getBoundedXYZ(int x, int y, int z, double[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { short[] tmp = (short[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { buffer[i][j][k] = (double) (tmp[offset] & 0xFFFF); offset++; } } ko++; } } catch (Exception e) { throw_get("XYZ", "Bounded check", buffer, x, y, z); } } // ------------------------------------------------------------------ // // getBlock section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; short[] tmp = (short[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (byte) (tmp[xp + yp] & 0xFFFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; short[] tmp = (short[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (short) (tmp[xp + yp] & 0xFFFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; short[] tmp = (short[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (float) (tmp[xp + yp] & 0xFFFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockX(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; short[] tmp = (short[]) data[zp]; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (double) (tmp[xp + yp] & 0xFFFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } short[] tmp = (short[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (byte) (tmp[xp + yp * nx] & 0xFFFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } short[] tmp = (short[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (short) (tmp[xp + yp * nx] & 0xFFFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } short[] tmp = (short[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (float) (tmp[xp + yp * nx] & 0xFFFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockY(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } short[] tmp = (short[]) data[zp]; for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (double) (tmp[xp + yp * nx] & 0xFFFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (byte) (((short[]) data[zp])[xyp] & 0xFFFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (short) (((short[]) data[zp])[xyp] & 0xFFFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (float) (((short[]) data[zp])[xyp] & 0xFFFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockZ(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; for (int i = 0; i < leni; i++) { zp = z + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (double) (((short[]) data[zp])[xyp] & 0xFFFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = (short[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (tmp[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = (short[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (tmp[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = (short[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (tmp[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the start position (x,y,z) in XY axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXY(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = (short[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (tmp[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (((short[]) data[zp])[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (((short[]) data[zp])[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (((short[]) data[zp])[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (((short[]) data[zp])[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (byte) (((short[]) data[zp])[xp + yp * nx] & 0xFFFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (short) (((short[]) data[zp])[xp + yp * nx] & 0xFFFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (float) (((short[]) data[zp])[xp + yp * nx] & 0xFFFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in YZ axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } for (int j = 0; j < lenj; j++) { zp = z + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = y + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (double) (((short[]) data[zp])[xp + yp * nx] & 0xFFFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = (short[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (byte) (tmp[xp + yp] & 0xFFFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = (short[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (short) (tmp[xp + yp] & 0xFFFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = (short[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (float) (tmp[xp + yp] & 0xFFFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the start position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getBlockXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions) { int xperiod = 0; int yperiod = 0; int zperiod = 0; switch (boundaryConditions) { case ImageWare.MIRROR: xperiod = (nx <= 1 ? 1 : 2 * nx - 2); yperiod = (ny <= 1 ? 1 : 2 * ny - 2); zperiod = (nz <= 1 ? 1 : 2 * nz - 2); break; case ImageWare.PERIODIC: xperiod = nx; yperiod = ny; zperiod = nz; break; default: throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; for (int k = 0; k < lenk; k++) { zp = z + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = (short[]) data[zp]; for (int j = 0; j < lenj; j++) { yp = y + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = x + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (double) (tmp[xp + yp] & 0xFFFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } // ------------------------------------------------------------------ // // getBlock section // // ------------------------------------------------------------------ /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; short[] tmp = ((short[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (byte) (tmp[xp + yp] & 0xFFFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; short[] tmp = ((short[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (short) (tmp[xp + yp] & 0xFFFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; short[] tmp = ((short[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (float) (tmp[xp + yp] & 0xFFFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in X axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodX(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; short[] tmp = ((short[]) data[zp]); for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i] = (double) (tmp[xp + yp] & 0xFFFF); } } catch (Exception e) { throw_get("X", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; short[] tmp = ((short[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (byte) (tmp[xp + yp * nx] & 0xFFFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; short[] tmp = ((short[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (short) (tmp[xp + yp * nx] & 0xFFFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; short[] tmp = ((short[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (float) (tmp[xp + yp * nx] & 0xFFFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Y axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodY(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; short[] tmp = ((short[]) data[zp]); for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i] = (double) (tmp[xp + yp * nx] & 0xFFFF); } } catch (Exception e) { throw_get("Y", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, byte[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (byte) (((short[]) data[zp])[xyp] & 0xFFFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, short[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (short) (((short[]) data[zp])[xyp] & 0xFFFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, float[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (float) (((short[]) data[zp])[xyp] & 0xFFFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in Z axis. * Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 1D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodZ(int x, int y, int z, double[] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } int xyp = xp + yp * nx; int zs = z - leni / 2; for (int i = 0; i < leni; i++) { zp = zs + i; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } buffer[i] = (double) (((short[]) data[zp])[xyp] & 0xFFFF); } } catch (Exception e) { throw_get("Z", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; short[] tmp = ((short[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (tmp[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; short[] tmp = ((short[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (tmp[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; short[] tmp = ((short[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (tmp[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * get an array into the imageware at the center position (x,y,z) in XY * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXY(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; zp = z; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } int xs = x - leni / 2; int ys = y - lenj / 2; short[] tmp = ((short[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (tmp[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XY", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (byte) (((short[]) data[zp])[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (short) (((short[]) data[zp])[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (float) (((short[]) data[zp])[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; yp = y; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; int xs = x - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - yp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j] = (double) (((short[]) data[zp])[xp + yp] & 0xFFFF); } } } catch (Exception e) { throw_get("XZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, byte[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (byte) (((short[]) data[zp])[xp + yp * nx] & 0xFFFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, short[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (short) (((short[]) data[zp])[xp + yp * nx] & 0xFFFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, float[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (float) (((short[]) data[zp])[xp + yp * nx] & 0xFFFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in YZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 2D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodYZ(int x, int y, int z, double[][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; xp = x; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } int ys = y - leni / 2; int zs = z - lenj / 2; for (int j = 0; j < lenj; j++) { zp = zs + j; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } for (int i = 0; i < leni; i++) { yp = ys + i; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } buffer[i][j] = (double) (((short[]) data[zp])[xp + yp * nx] & 0xFFFF); } } } catch (Exception e) { throw_get("YZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * byte 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, byte[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = ((short[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (byte) (tmp[xp + yp] & 0xFFFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * short 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, short[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = ((short[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (short) (tmp[xp + yp] & 0xFFFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * float 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, float[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = ((short[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (float) (tmp[xp + yp] & 0xFFFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } /** * Get an array from the imageware at the center position (x,y,z) in XYZ * axis. Apply boundary conditions to get the outside area. * * @param x * X starting position to get the buffer * @param y * Y starting position to get the buffer * @param z * Z starting position to get the buffer * @param buffer * double 3D array to get into the imageware * @param boundaryConditions * mirror or periodic boundary conditions */ public void getNeighborhoodXYZ(int x, int y, int z, double[][][] buffer, byte boundaryConditions) { int xperiod = (boundaryConditions == ImageWare.MIRROR ? (nx <= 1 ? 1 : 2 * nx - 2) : nx); int yperiod = (boundaryConditions == ImageWare.MIRROR ? (ny <= 1 ? 1 : 2 * ny - 2) : ny); int zperiod = (boundaryConditions == ImageWare.MIRROR ? (nz <= 1 ? 1 : 2 * nz - 2) : nz); int xp, yp, zp; try { int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; int xs = x - leni / 2; int ys = y - lenj / 2; int zs = z - lenk / 2; for (int k = 0; k < lenk; k++) { zp = zs + k; while (zp < 0) zp += zperiod; while (zp >= nz) { zp = zperiod - zp; zp = (zp < 0 ? -zp : zp); } short[] tmp = ((short[]) data[zp]); for (int j = 0; j < lenj; j++) { yp = ys + j; while (yp < 0) yp += yperiod; while (yp >= ny) { yp = yperiod - yp; yp = (yp < 0 ? -yp : yp); } yp *= nx; for (int i = 0; i < leni; i++) { xp = xs + i; while (xp < 0) xp += xperiod; while (xp >= nx) { xp = xperiod - xp; xp = (xp < 0 ? -xp : xp); } buffer[i][j][k] = (double) (tmp[xp + yp] & 0xFFFF); } } } } catch (Exception e) { throw_get("XYZ", "Mirror or periodic boundaray conditions", buffer, x, y, z); } } // ------------------------------------------------------------------ // // putBounded section // // ------------------------------------------------------------------ /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i] & 0xFF); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i] & 0xFFFF); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in X axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedX(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int offset = (x + iinf) + (y) * nx; int leni = buffer.length; if (x + leni < 0) return; if (y < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i]); offset++; } } catch (Exception e) { throw_put("X", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i] & 0xFF); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i] & 0xFFFF); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Y axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedY(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int offset = (x) + (y + iinf) * nx; int leni = buffer.length; if (x < 0) return; if (y + leni < 0) return; if (z < 0) return; int isup = (y + leni >= ny ? ny - y : leni); short[] tmp = (short[]) data[z]; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i]); offset += nx; } } catch (Exception e) { throw_put("Y", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, byte[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i] & 0xFF); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, short[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i] & 0xFFFF); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, float[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i]); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in Z axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 1D array to put into the imageware */ public void putBoundedZ(int x, int y, int z, double[] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (z < 0 ? -z : 0); int k = z + iinf; int offset = (x) + (y) * nx; int leni = buffer.length; if (x < 0) return; if (y < 0) return; if (z + leni < 0) return; int isup = (z + leni >= nz ? nz - z : leni); for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i]); k++; } } catch (Exception e) { throw_put("Z", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); short[] tmp = (short[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i][j] & 0xFF); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); short[] tmp = (short[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i][j] & 0xFFFF); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); short[] tmp = (short[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i][j]); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XY axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedXY(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); short[] tmp = (short[]) data[z]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i][j]); offset++; } } } catch (Exception e) { throw_put("XY", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i][j] & 0xFF); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i][j] & 0xFFFF); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i][j]); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedXZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x + leni < 0) return; if (y < 0) return; if (z + lenj < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y) * nx; for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i][j]); offset++; } k++; } } catch (Exception e) { throw_put("YZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, byte[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i][j] & 0xFF); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, short[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i][j] & 0xFFFF); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, float[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i][j]); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in YZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 2D array to put into the imageware */ public void putBoundedYZ(int x, int y, int z, double[][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (y < 0 ? -y : 0); int jinf = (z < 0 ? -z : 0); int k = z + jinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; if (x < 0) return; if (y + leni < 0) return; if (z + lenj < 0) return; int isup = (y + leni >= ny ? ny - y : leni); int jsup = (z + lenj >= nz ? nz - z : lenj); for (int j = jinf; j < jsup; j++) { offset = x + (y + iinf) * nx; for (int i = iinf; i < isup; i++) { ((short[]) data[k])[offset] = (short) (buffer[i][j]); offset += nx; } k++; } } catch (Exception e) { throw_put("XZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * byte 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, byte[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { short[] tmp = (short[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i][j][k] & 0xFF); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * short 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, short[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { short[] tmp = (short[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i][j][k] & 0xFFFF); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * float 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, float[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { short[] tmp = (short[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i][j][k]); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } /** * Put an array into the imageware at the position (x,y,z) in XYZ axis. Copy * only the bounded area, intersection between the array and the imageware. * * @param x * X starting position to put the buffer * @param y * Y starting position to put the buffer * @param z * Z starting position to put the buffer * @param buffer * double 3D array to put into the imageware */ public void putBoundedXYZ(int x, int y, int z, double[][][] buffer) { try { if (x >= nx) return; if (y >= ny) return; if (z >= nz) return; int iinf = (x < 0 ? -x : 0); int jinf = (y < 0 ? -y : 0); int kinf = (z < 0 ? -z : 0); int ko = z + kinf; int offset = 0; int leni = buffer.length; int lenj = buffer[0].length; int lenk = buffer[0][0].length; if (x + leni < 0) return; if (y + lenj < 0) return; if (z + lenk < 0) return; int isup = (x + leni >= nx ? nx - x : leni); int jsup = (y + lenj >= ny ? ny - y : lenj); int ksup = (z + lenk >= nz ? nz - z : lenk); for (int k = kinf; k < ksup; k++) { short[] tmp = (short[]) data[ko]; for (int j = jinf; j < jsup; j++) { offset = (x + iinf) + (y + j) * nx; for (int i = iinf; i < isup; i++) { tmp[offset] = (short) (buffer[i][j][k]); offset++; } } ko++; } } catch (Exception e) { throw_put("XYZ", "Bounded check", buffer, x, y, z); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/ShortBuffer.java b/src/bilib/src/imageware/ShortBuffer.java new file mode 100644 index 0000000000000000000000000000000000000000..b4d24f033e7c9fef643323d7d4c8f1a981fcbd9c --- /dev/null +++ b/src/bilib/src/imageware/ShortBuffer.java @@ -0,0 +1,2768 @@ +package imageware; + +import ij.ImageStack; +import ij.process.ByteProcessor; +import ij.process.ColorProcessor; +import ij.process.FloatProcessor; +import ij.process.ImageProcessor; +import ij.process.ShortProcessor; + +import java.awt.Image; +import java.awt.image.ImageObserver; +import java.awt.image.PixelGrabber; + +/** + * Class ShortBuffer. + * + * + * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de + * Lausanne, Lausanne, Switzerland + */ + +public class ShortBuffer implements Buffer { + + protected Object[] data = null; + protected int nx = 0; + protected int ny = 0; + protected int nz = 0; + protected int nxy = 0; + + /** + * Constructor of a empty 3D short buffer. + * + * @param nx + * size of the 3D buffer in the X axis + * @param ny + * size of the 3D buffer in the Y axis + * @param nz + * size of the 3D buffer in the Z axis + */ + protected ShortBuffer(int nx, int ny, int nz) { + this.nx = nx; + this.ny = ny; + this.nz = nz; + if (nx <= 0 || ny <= 0 || nz <= 0) + throw_constructor(nx, ny, nz); + allocate(); + } + + /** + * Constructor of a short buffer from a object Image of Java. + * + * @param image + * source to build a new imageware + */ + protected ShortBuffer(Image image, int mode) { + if (image == null) { + throw_constructor(); + } + ImageObserver observer = null; + this.nx = image.getWidth(observer); + this.ny = image.getHeight(observer); + this.nz = 1; + this.nxy = nx * ny; + byte[] pixels = new byte[nxy]; + PixelGrabber pg = new PixelGrabber(image, 0, 0, nx, ny, false); + try { + pg.grabPixels(); + pixels = (byte[]) (pg.getPixels()); + } + catch (Exception e) { + throw_constructor(); + } + allocate(); + for (int k = 0; k < nxy; k++) + ((short[]) data[0])[k] = (short) (pixels[k] & 0xFF); + } + + /** + * Constructor of a short buffer from a ImageStack. + * + * New data are allocated if the mode is CREATE, the imageware use the data + * of ImageJ if the mode is WRAP. + * + * @param stack + * source to build a new imageware + * @param mode + * WRAP or CREATE + */ + protected ShortBuffer(ImageStack stack, int mode) { + if (stack == null) { + throw_constructor(); + } + this.nx = stack.getWidth(); + this.ny = stack.getHeight(); + this.nz = stack.getSize(); + this.nxy = nx * ny; + switch (mode) { + case ImageWare.WRAP: + this.data = stack.getImageArray(); + break; + case ImageWare.CREATE: + allocate(); + ImageProcessor ip = stack.getProcessor(1); + if (ip instanceof ByteProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + byte[] slice = (byte[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((short[]) data[z])[k] = (short) (slice[k] & 0xFF); + } + } + } + else if (ip instanceof ShortProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + short[] slice = (short[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((short[]) data[z])[k] = (short) (slice[k] & 0xFFFF); + } + } + } + else if (ip instanceof FloatProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + float[] slice = (float[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((short[]) data[z])[k] = (short) slice[k]; + } + } + } + else if (ip instanceof ColorProcessor) { + double r, g, b; + int c; + ColorProcessor cp; + int[] pixels; + for (int z = 0; z < nz; z++) { + cp = (ColorProcessor) stack.getProcessor(z + 1); + pixels = (int[]) cp.getPixels(); + for (int k = 0; k < nxy; k++) { + c = pixels[k]; + r = (double) ((c & 0xFF0000) >> 16); + g = (double) ((c & 0xFF00) >> 8); + b = (double) ((c & 0xFF)); + ((short[]) data[z])[k] = (short) ((r + g + b) / 3.0); + } + } + } + else { + throw_constructor(); + } + break; + default: + throw_constructor(); + break; + } + } + + /** + * Constructor of a short buffer from a specific color channel of + * ImageStack. + * + * New data are always allocated. If it is a gray image the imageware is + * created and fill up with data of the source ImageStack. If it is a color + * image only the selected channel is used to create this imageware. + * + * @param stack + * source to build a new imageware + * @param channel + * RED, GREEN or BLUE + */ + protected ShortBuffer(ImageStack stack, byte channel) { + if (stack == null) { + throw_constructor(); + } + this.nx = stack.getWidth(); + this.ny = stack.getHeight(); + this.nz = stack.getSize(); + this.nxy = nx * ny; + allocate(); + ImageProcessor ip = stack.getProcessor(1); + if (ip instanceof ByteProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + byte[] slice = (byte[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((short[]) data[z])[k] = (short) (slice[k] & 0xFF); + } + } + } + else if (ip instanceof ShortProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + short[] slice = (short[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((short[]) data[z])[k] = (short) (slice[k] & 0xFFFF); + } + } + } + else if (ip instanceof FloatProcessor) { + Object[] vol = stack.getImageArray(); + for (int z = 0; z < nz; z++) { + float[] slice = (float[]) vol[z]; + for (int k = 0; k < nxy; k++) { + ((short[]) data[z])[k] = (short) slice[k]; + } + } + } + else if (ip instanceof ColorProcessor) { + ColorProcessor cp; + int[] pixels; + for (int z = 0; z < nz; z++) { + cp = (ColorProcessor) stack.getProcessor(z + 1); + pixels = (int[]) cp.getPixels(); + switch (channel) { + case ImageWare.RED: + for (int k = 0; k < nxy; k++) { + ((short[]) data[z])[k] = (short) ((pixels[k] & 0xFF0000) >> 16); + } + break; + case ImageWare.GREEN: + for (int k = 0; k < nxy; k++) { + ((short[]) data[z])[k] = (short) ((pixels[k] & 0xFF00) >> 8); + } + break; + case ImageWare.BLUE: + for (int k = 0; k < nxy; k++) { + ((short[]) data[z])[k] = (short) (pixels[k] & 0xFF); + } + break; + default: + throw_constructor(); + } + } + } + else { + throw_constructor(); + } + } + + /** + * Constructor of a short buffer from a byte array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(byte[] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = 1; + this.nz = 1; + allocate(); + putX(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a byte array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(byte[][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = 1; + allocate(); + putXY(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a byte array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(byte[][][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = array[0][0].length; + allocate(); + putXYZ(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a short array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(short[] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = 1; + this.nz = 1; + allocate(); + putX(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a short array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(short[][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = 1; + allocate(); + putXY(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a short array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(short[][][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = array[0][0].length; + allocate(); + putXYZ(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a float array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(float[] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = 1; + this.nz = 1; + allocate(); + putX(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a float array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(float[][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = 1; + allocate(); + putXY(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a float array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(float[][][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = array[0][0].length; + allocate(); + putXYZ(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a double array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(double[] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = 1; + this.nz = 1; + allocate(); + putX(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a double array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(double[][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = 1; + allocate(); + putXY(0, 0, 0, array); + } + + /** + * Constructor of a short buffer from a double array. + * + * @param array + * source to build this new imageware + */ + protected ShortBuffer(double[][][] array, int mode) { + if (array == null) { + throw_constructor(); + } + this.nx = array.length; + this.ny = array[0].length; + this.nz = array[0][0].length; + allocate(); + putXYZ(0, 0, 0, array); + } + + /** + * Return the type of this imageware. + * + * @return the type of this imageware + */ + public int getType() { + return ImageWare.SHORT; + } + + /** + * Return the type of this imageware in a string format. + * + * @return the type of this imageware translated in a string format + */ + public String getTypeToString() { + return "Short"; + } + + /** + * Return the number of dimension of this imageware (1, 2 or 3). + * + * @return the number of dimension of this imageware + */ + public int getDimension() { + int dims = 0; + dims += (nx > 1 ? 1 : 0); + dims += (ny > 1 ? 1 : 0); + dims += (nz > 1 ? 1 : 0); + return dims; + } + + /** + * Return the size of the imageware int[0] : x, int[1] : y, int[2] : z. + * + * @return an array given the size of the imageware + */ + public int[] getSize() { + int[] size = { nx, ny, nz }; + return size; + } + + /** + * Return the size in the X axis. + * + * @return the size in the X axis + */ + public int getSizeX() { + return nx; + } + + /** + * Return the size in the Y axis. + * + * @return the size in the Y axis + */ + public int getSizeY() { + return ny; + } + + /** + * Return the size in the Z axis. + * + * @return the size in the Z axis + */ + public int getSizeZ() { + return nz; + } + + /** + * Return the size in the X axis. + * + * @return the size in the X axis + */ + public int getWidth() { + return nx; + } + + /** + * Return the size in the Y axis. + * + * @return the size in the Y axis + */ + public int getHeight() { + return ny; + } + + /** + * Return the size in the Z axis. + * + * @return the size in the Z axis + */ + public int getDepth() { + return nz; + } + + /** + * Return the number of pixels in the imageware. + * + * @return number of pixels in the imageware + */ + public int getTotalSize() { + return nxy * nz; + } + + /** + * Return true is this imageware has the same size the imageware given as + * parameter. + * + * @param imageware + * imageware to be compared + * @return true if the imageware of the same size than this imageware + */ + public boolean isSameSize(ImageWare imageware) { + if (nx != imageware.getSizeX()) + return false; + if (ny != imageware.getSizeY()) + return false; + if (nz != imageware.getSizeZ()) + return false; + return true; + } + + // ------------------------------------------------------------------ + // + // put Section + // + // ------------------------------------------------------------------ + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putX(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + double buf[] = new double[bnx]; + buffer.getX(0, 0, 0, buf); + putX(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putY(int x, int y, int z, ImageWare buffer) { + int bny = buffer.getSizeY(); + double buf[] = new double[bny]; + buffer.getY(0, 0, 0, buf); + putY(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putZ(int x, int y, int z, ImageWare buffer) { + int bnz = buffer.getSizeZ(); + double buf[] = new double[bnz]; + buffer.getZ(0, 0, 0, buf); + putZ(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putXY(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bny = buffer.getSizeY(); + double buf[][] = new double[bnx][bny]; + buffer.getXY(0, 0, 0, buf); + putXY(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putXZ(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bnz = buffer.getSizeZ(); + double buf[][] = new double[bnx][bnz]; + buffer.getXZ(0, 0, 0, buf); + putXZ(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putYZ(int x, int y, int z, ImageWare buffer) { + int bny = buffer.getSizeY(); + int bnz = buffer.getSizeZ(); + double buf[][] = new double[bny][bnz]; + buffer.getYZ(0, 0, 0, buf); + putYZ(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * ImageWare object to put into the imageware + */ + public void putXYZ(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bny = buffer.getSizeY(); + int bnz = buffer.getSizeZ(); + double buf[][][] = new double[bnx][bny][bnz]; + buffer.getXYZ(0, 0, 0, buf); + putXYZ(x, y, z, buf); + } + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 1D array to put into the imageware + */ + public void putX(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + + for (int i = 0; i < leni; i++) { + tmp[offset] = (short) (buffer[i] & 0xFF); + offset++; + } + } + catch (Exception e) { + throw_put("X", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 1D array to put into the imageware + */ + public void putX(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + + System.arraycopy(buffer, 0, tmp, offset, leni); + } + catch (Exception e) { + throw_put("X", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 1D array to put into the imageware + */ + public void putX(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + + for (int i = 0; i < leni; i++) { + tmp[offset] = (short) (buffer[i]); + offset++; + } + } + catch (Exception e) { + throw_put("X", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 1D array to put into the imageware + */ + public void putX(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + + for (int i = 0; i < leni; i++) { + tmp[offset] = (short) (buffer[i]); + offset++; + } + } + catch (Exception e) { + throw_put("X", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 1D array to put into the imageware + */ + public void putY(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + for (int i = 0; i < leni; i++) { + tmp[offset] = (short) (buffer[i] & 0xFF); + offset += nx; + } + } + catch (Exception e) { + throw_put("Y", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 1D array to put into the imageware + */ + public void putY(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + for (int i = 0; i < leni; i++) { + tmp[offset] = (short) (buffer[i] & 0xFFFF); + offset += nx; + } + } + catch (Exception e) { + throw_put("Y", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 1D array to put into the imageware + */ + public void putY(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + for (int i = 0; i < leni; i++) { + tmp[offset] = (short) (buffer[i]); + offset += nx; + } + } + catch (Exception e) { + throw_put("Y", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 1D array to put into the imageware + */ + public void putY(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + for (int i = 0; i < leni; i++) { + tmp[offset] = (short) (buffer[i]); + offset += nx; + } + } + catch (Exception e) { + throw_put("Y", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * bybytete 1D array to put into the imageware + */ + public void putZ(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + ((short[]) data[z])[offset] = (short) (buffer[i] & 0xFF); + z++; + } + } + catch (Exception e) { + throw_put("Z", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byshortte 1D array to put into the imageware + */ + public void putZ(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + ((short[]) data[z])[offset] = (short) (buffer[i] & 0xFFFF); + z++; + } + } + catch (Exception e) { + throw_put("Z", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byfloatte 1D array to put into the imageware + */ + public void putZ(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + ((short[]) data[z])[offset] = (short) (buffer[i]); + z++; + } + } + catch (Exception e) { + throw_put("Z", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * bydoublete 1D array to put into the imageware + */ + public void putZ(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + ((short[]) data[z])[offset] = (short) (buffer[i]); + z++; + } + } + catch (Exception e) { + throw_put("Z", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 2D array to put into the imageware + */ + public void putXY(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (short) (buffer[i][j] & 0xFF); + } + } + } + catch (Exception e) { + throw_put("XY", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 2D array to put into the imageware + */ + public void putXY(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (short) (buffer[i][j] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_put("XY", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 2D array to put into the imageware + */ + public void putXY(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (short) (buffer[i][j]); + } + } + } + catch (Exception e) { + throw_put("XY", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 2D array to put into the imageware + */ + public void putXY(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (short) (buffer[i][j]); + } + } + } + catch (Exception e) { + throw_put("XY", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 2D array to put into the imageware + */ + public void putXZ(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + j * nx; + for (int i = 0; i < leni; i++, offset++) { + ((short[]) data[z])[offset] = (short) (buffer[i][j] & 0xFF); + } + } + } + catch (Exception e) { + throw_put("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 2D array to put into the imageware + */ + public void putXZ(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + j * nx; + for (int i = 0; i < leni; i++, offset++) { + ((short[]) data[z])[offset] = (short) (buffer[i][j] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_put("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 2D array to put into the imageware + */ + public void putXZ(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + j * nx; + for (int i = 0; i < leni; i++, offset++) { + ((short[]) data[z])[offset] = (short) (buffer[i][j]); + } + } + } + catch (Exception e) { + throw_put("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 2D array to put into the imageware + */ + public void putXZ(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + j * nx; + for (int i = 0; i < leni; i++, offset++) { + ((short[]) data[z])[offset] = (short) (buffer[i][j]); + } + } + } + catch (Exception e) { + throw_put("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 2D array to put into the imageware + */ + public void putYZ(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) + for (int i = 0; i < leni; i++, offset += nx) { + ((short[]) data[z])[offset] = (short) (buffer[i][j] & 0xFF); + } + } + catch (Exception e) { + throw_put("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 2D array to put into the imageware + */ + public void putYZ(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) + for (int i = 0; i < leni; i++, offset += nx) { + ((short[]) data[z])[offset] = (short) (buffer[i][j] & 0xFFFF); + } + } + catch (Exception e) { + throw_put("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 2D array to put into the imageware + */ + public void putYZ(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) + for (int i = 0; i < leni; i++, offset += nx) { + ((short[]) data[z])[offset] = (short) (buffer[i][j]); + } + } + catch (Exception e) { + throw_put("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 2D array to put into the imageware + */ + public void putYZ(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) + for (int i = 0; i < leni; i++, offset += nx) { + ((short[]) data[z])[offset] = (short) (buffer[i][j]); + } + } + catch (Exception e) { + throw_put("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * byte 3D array to put into the imageware + */ + public void putXYZ(int x, int y, int z, byte[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (short) (buffer[i][j][k] & 0xFF); + } + } + } + } + catch (Exception e) { + throw_put("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * short 3D array to put into the imageware + */ + public void putXYZ(int x, int y, int z, short[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (short) (buffer[i][j][k] & 0xFFFF); + } + } + } + } + catch (Exception e) { + throw_put("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * float 3D array to put into the imageware + */ + public void putXYZ(int x, int y, int z, float[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (short) (buffer[i][j][k]); + } + } + } + } + catch (Exception e) { + throw_put("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Put an array into the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to put the buffer + * @param y + * Y starting position to put the buffer + * @param z + * Z starting position to put the buffer + * @param buffer + * double 3D array to put into the imageware + */ + public void putXYZ(int x, int y, int z, double[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + tmp[offset] = (short) (buffer[i][j][k]); + } + } + } + } + catch (Exception e) { + throw_put("XYZ", "No check", buffer, x, y, z); + } + } + + // ------------------------------------------------------------------ + // + // get Section + // + // ------------------------------------------------------------------ + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getX(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + double buf[] = new double[bnx]; + getX(x, y, z, buf); + buffer.putX(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getY(int x, int y, int z, ImageWare buffer) { + int bny = buffer.getSizeY(); + double buf[] = new double[bny]; + getY(x, y, z, buf); + buffer.putY(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getZ(int x, int y, int z, ImageWare buffer) { + int bnz = buffer.getSizeZ(); + double buf[] = new double[bnz]; + getZ(x, y, z, buf); + buffer.putZ(0, 0, 0, buf); + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getXY(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bny = buffer.getSizeY(); + double buf[][] = new double[bnx][bny]; + getXY(x, y, z, buf); + buffer.putXY(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getXZ(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bnz = buffer.getSizeZ(); + double buf[][] = new double[bnx][bnz]; + getXZ(x, y, z, buf); + buffer.putXZ(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the datase + */ + public void getYZ(int x, int y, int z, ImageWare buffer) { + int bny = buffer.getSizeY(); + int bnz = buffer.getSizeZ(); + double buf[][] = new double[bny][bnz]; + getYZ(x, y, z, buf); + buffer.putYZ(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * ImageWare object to get into the imageware + */ + public void getXYZ(int x, int y, int z, ImageWare buffer) { + int bnx = buffer.getSizeX(); + int bny = buffer.getSizeY(); + int bnz = buffer.getSizeZ(); + double buf[][][] = new double[bnx][bny][bnz]; + getXYZ(x, y, z, buf); + buffer.putXYZ(0, 0, 0, buf); + } + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 1D array to get into the imageware + */ + public void getX(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + + for (int i = 0; i < leni; i++) { + buffer[i] = (byte) (tmp[offset] & 0xffff); + offset++; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 1D array to get into the imageware + */ + public void getX(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + + System.arraycopy(tmp, offset, buffer, 0, leni); + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 1D array to get into the imageware + */ + public void getX(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + + for (int i = 0; i < leni; i++) { + buffer[i] = (float) (tmp[offset] & 0xffff); + offset++; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in X axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 1D array to get into the imageware + */ + public void getX(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + + for (int i = 0; i < leni; i++) { + buffer[i] = (double) (tmp[offset] & 0xffff); + offset++; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 1D array to get into the imageware + */ + public void getY(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + for (int i = 0; i < leni; i++) { + buffer[i] = (byte) (tmp[offset] & 0xFFFF); + offset += nx; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 1D array to get into the imageware + */ + public void getY(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + for (int i = 0; i < leni; i++) { + buffer[i] = (short) (tmp[offset] & 0xFFFF); + offset += nx; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 1D array to get into the imageware + */ + public void getY(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + for (int i = 0; i < leni; i++) { + buffer[i] = (float) (tmp[offset] & 0xFFFF); + offset += nx; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Y axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 1D array to get into the imageware + */ + public void getY(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + short[] tmp = (short[]) data[z]; + for (int i = 0; i < leni; i++) { + buffer[i] = (double) (tmp[offset] & 0xFFFF); + offset += nx; + } + } + catch (Exception e) { + throw_get("X", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 1D array to get into the imageware + */ + public void getZ(int x, int y, int z, byte[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + buffer[i] = (byte) (((short[]) data[z])[offset] & 0xFFFF); + z++; + } + } + catch (Exception e) { + throw_get("Y", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 1D array to get into the imageware + */ + public void getZ(int x, int y, int z, short[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + buffer[i] = (short) (((short[]) data[z])[offset] & 0xFFFF); + z++; + } + } + catch (Exception e) { + throw_get("Y", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 1D array to get into the imageware + */ + public void getZ(int x, int y, int z, float[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + buffer[i] = (float) (((short[]) data[z])[offset] & 0xFFFF); + z++; + } + } + catch (Exception e) { + throw_get("Y", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in Z axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 1D array to get into the imageware + */ + public void getZ(int x, int y, int z, double[] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + for (int i = 0; i < leni; i++) { + buffer[i] = (double) (((short[]) data[z])[offset] & 0xFFFF); + z++; + } + } + catch (Exception e) { + throw_get("Y", "No check", buffer, x, y, z); + } + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 2D array to get into the imageware + */ + public void getXY(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (byte) (tmp[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("XY", "No check", buffer, x, y, z); + } + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 2D array to get into the imageware + */ + public void getXY(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (short) (tmp[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("XY", "No check", buffer, x, y, z); + } + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 2D array to get into the imageware + */ + public void getXY(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (float) (tmp[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("XY", "No check", buffer, x, y, z); + } + } + + /** + * get an array into the imageware at the position (x,y,z) in XY axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 2D array to get into the imageware + */ + public void getXY(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (y + j) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (double) (tmp[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("XY", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 2D array to get into the imageware + */ + public void getXZ(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + y * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (byte) (((short[]) data[z])[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 2D array to get into the imageware + */ + public void getXZ(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + y * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (short) (((short[]) data[z])[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 2D array to get into the imageware + */ + public void getXZ(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + y * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (float) (((short[]) data[z])[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 2D array to get into the imageware + */ + public void getXZ(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++) { + offset = x + y * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j] = (double) (((short[]) data[z])[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("XZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 2D array to get into the datase + */ + public void getYZ(int x, int y, int z, byte[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { + for (int i = 0; i < leni; i++, offset += nx) { + buffer[i][j] = (byte) (((short[]) data[z])[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 2D array to get into the datase + */ + public void getYZ(int x, int y, int z, short[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { + for (int i = 0; i < leni; i++, offset += nx) { + buffer[i][j] = (short) (((short[]) data[z])[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 2D array to get into the datase + */ + public void getYZ(int x, int y, int z, float[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { + for (int i = 0; i < leni; i++, offset += nx) { + buffer[i][j] = (float) (((short[]) data[z])[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in YZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 2D array to get into the datase + */ + public void getYZ(int x, int y, int z, double[][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + for (int j = 0; j < lenj; j++, z++, offset = (x + nx * y)) { + for (int i = 0; i < leni; i++, offset += nx) { + buffer[i][j] = (double) (((short[]) data[z])[offset] & 0xFFFF); + } + } + } + catch (Exception e) { + throw_get("YZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * byte 3D array to get into the imageware + */ + public void getXYZ(int x, int y, int z, byte[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j][k] = (byte) (tmp[offset] & 0xFFFF); + } + } + } + } + catch (Exception e) { + throw_get("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * short 3D array to get into the imageware + */ + public void getXYZ(int x, int y, int z, short[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j][k] = (short) (tmp[offset] & 0xFFFF); + } + } + } + } + catch (Exception e) { + throw_get("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * float 3D array to get into the imageware + */ + public void getXYZ(int x, int y, int z, float[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j][k] = (float) (tmp[offset] & 0xFFFF); + } + } + } + } + catch (Exception e) { + throw_get("XYZ", "No check", buffer, x, y, z); + } + } + + /** + * Get an array from the imageware at the position (x,y,z) in XYZ axis. No + * check are performed if the array is outside of the imageware. + * + * @param x + * X starting position to get the buffer + * @param y + * Y starting position to get the buffer + * @param z + * Z starting position to get the buffer + * @param buffer + * double 3D array to get into the imageware + */ + public void getXYZ(int x, int y, int z, double[][][] buffer) { + try { + int offset = x + y * nx; + int leni = buffer.length; + int lenj = buffer[0].length; + int lenk = buffer[0][0].length; + for (int k = 0; k < lenk; k++, z++) { + short[] tmp = (short[]) data[z]; + for (int j = 0; j < lenj; j++) { + offset = x + (j + y) * nx; + for (int i = 0; i < leni; i++, offset++) { + buffer[i][j][k] = (double) (tmp[offset] & 0xFFFF); + } + } + } + } + catch (Exception e) { + throw_get("XYZ", "No check", buffer, x, y, z); + } + } + + // ------------------------------------------------------------------ + // + // Private Section + // + // ------------------------------------------------------------------ + + /** + * Prepare a complete error message from the errors coming the constructors. + */ + protected void throw_constructor() { + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a short imageware.\n" + + "-------------------------------------------------------\n"); + } + + /** + * Prepare a complete error message from the errors coming the constructors. + */ + protected void throw_constructor(int nx, int ny, int nz) { + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to create a short imageware " + nx + "," + ny + + "," + nz + "].\n" + "-------------------------------------------------------\n"); + } + + /** + * Prepare a complete error message from the errors coming the get routines. + */ + protected void throw_get(String direction, String border, Object buffer, int x, int y, int z) { + int leni = 0; + int lenj = 0; + int lenk = 0; + String type = " unknown type"; + if (buffer instanceof byte[]) { + leni = ((byte[]) buffer).length; + type = " 1D byte"; + } + else if (buffer instanceof short[]) { + leni = ((short[]) buffer).length; + type = " 1D short"; + } + else if (buffer instanceof float[]) { + leni = ((float[]) buffer).length; + type = " 1D float"; + } + else if (buffer instanceof double[]) { + leni = ((double[]) buffer).length; + type = " 1D double"; + } + else if (buffer instanceof byte[][]) { + leni = ((byte[][]) buffer).length; + lenj = ((byte[][]) buffer)[0].length; + type = " 2D byte"; + } + else if (buffer instanceof short[][]) { + leni = ((short[][]) buffer).length; + lenj = ((short[][]) buffer)[0].length; + type = " 2D short"; + } + else if (buffer instanceof float[][]) { + leni = ((float[][]) buffer).length; + lenj = ((float[][]) buffer)[0].length; + type = " 2D float"; + } + else if (buffer instanceof double[][]) { + leni = ((double[][]) buffer).length; + lenj = ((double[][]) buffer)[0].length; + type = " 2D double"; + } + else if (buffer instanceof byte[][][]) { + leni = ((byte[][][]) buffer).length; + lenj = ((byte[][][]) buffer)[0].length; + lenk = ((byte[][][]) buffer)[0][0].length; + type = " 3D byte"; + } + else if (buffer instanceof short[][][]) { + leni = ((short[][][]) buffer).length; + lenj = ((short[][][]) buffer)[0].length; + lenk = ((short[][][]) buffer)[0][0].length; + type = " 3D short"; + } + else if (buffer instanceof float[][][]) { + leni = ((float[][][]) buffer).length; + lenj = ((float[][][]) buffer)[0].length; + lenk = ((float[][][]) buffer)[0][0].length; + type = " 3D float"; + } + else if (buffer instanceof double[][][]) { + leni = ((double[][][]) buffer).length; + lenj = ((double[][][]) buffer)[0].length; + lenk = ((double[][][]) buffer)[0][0].length; + type = " 3D double"; + } + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get a" + type + " buffer [" + + (leni == 0 ? "" : ("" + leni)) + (lenj == 0 ? "" : ("," + lenj)) + (lenk == 0 ? "" : ("," + lenk)) + "] \n" + "from the short imageware [" + nx + "," + ny + "," + nz + "]\n" + + "at the position (" + x + "," + y + "," + z + ") in direction " + direction + "\n" + "using " + border + ".\n" + "-------------------------------------------------------\n"); + } + + /** + * Prepare a complete error message from the errors coming the put routines. + */ + protected void throw_put(String direction, String border, Object buffer, int x, int y, int z) { + int leni = 0; + int lenj = 0; + int lenk = 0; + String type = " unknown type"; + if (buffer instanceof byte[]) { + leni = ((byte[]) buffer).length; + type = " 1D byte"; + } + else if (buffer instanceof short[]) { + leni = ((short[]) buffer).length; + type = " 1D short"; + } + else if (buffer instanceof float[]) { + leni = ((float[]) buffer).length; + type = " 1D float"; + } + else if (buffer instanceof double[]) { + leni = ((double[]) buffer).length; + type = " 1D double"; + } + else if (buffer instanceof byte[][]) { + leni = ((byte[][]) buffer).length; + lenj = ((byte[][]) buffer)[0].length; + type = " 2D byte"; + } + else if (buffer instanceof short[][]) { + leni = ((short[][]) buffer).length; + lenj = ((short[][]) buffer)[0].length; + type = " 2D short"; + } + else if (buffer instanceof float[][]) { + leni = ((float[][]) buffer).length; + lenj = ((float[][]) buffer)[0].length; + type = " 2D float"; + } + else if (buffer instanceof double[][]) { + leni = ((double[][]) buffer).length; + lenj = ((double[][]) buffer)[0].length; + type = " 2D double"; + } + else if (buffer instanceof byte[][][]) { + leni = ((byte[][][]) buffer).length; + lenj = ((byte[][][]) buffer)[0].length; + lenk = ((byte[][][]) buffer)[0][0].length; + type = " 3D byte"; + } + else if (buffer instanceof short[][][]) { + leni = ((short[][][]) buffer).length; + lenj = ((short[][][]) buffer)[0].length; + lenk = ((short[][][]) buffer)[0][0].length; + type = " 3D short"; + } + else if (buffer instanceof float[][][]) { + leni = ((float[][][]) buffer).length; + lenj = ((float[][][]) buffer)[0].length; + lenk = ((float[][][]) buffer)[0][0].length; + type = " 3D float"; + } + else if (buffer instanceof double[][][]) { + leni = ((double[][][]) buffer).length; + lenj = ((double[][][]) buffer)[0].length; + lenk = ((double[][][]) buffer)[0][0].length; + type = " 3D double"; + } + throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to put a" + type + " buffer [" + + (leni == 0 ? "" : ("" + leni)) + (lenj == 0 ? "" : ("," + lenj)) + (lenk == 0 ? "" : ("," + lenk)) + "] \n" + "into the short imageware [" + nx + "," + ny + "," + nz + "]\n" + + "at the position (" + x + "," + y + "," + z + ") in direction " + direction + "\n" + "using " + border + ".\n" + "-------------------------------------------------------\n"); + } + + // ------------------------------------------------------------------ + // + // Get slice fast and direct access Section + // + // ------------------------------------------------------------------ + + /** + * Get a reference of the whole volume data. + * + * @return a reference of the data of this imageware + */ + public Object[] getVolume() { + return data; + } + + /** + * Get a specific slice, fast and direct access, but only for byte + * imageware. + * + * @param z + * number of the requested slice + * @return a reference of the data of one slice of this imageware + */ + public byte[] getSliceByte(int z) { + return null; + } + + /** + * Get a specific slice, fast and direct access, but only for short + * imageware. + * + * @param z + * number of the requested slice + * @return a reference of the data of one slice of this imageware + */ + public short[] getSliceShort(int z) { + return (short[]) data[z]; + } + + /** + * Get a specific slice, fast and direct access, but only for float + * imageware. + * + * @param z + * number of the requested slice + * @return a reference of the data of one slice of this imageware + */ + public float[] getSliceFloat(int z) { + return null; + } + + /** + * Get a specific slice, fast and direct access, but only for double + * imageware. + * + * @param z + * number of the requested slice + * @return a reference of the data of one slice of this imageware + */ + public double[] getSliceDouble(int z) { + return null; + } + + /** + * Allocate a buffer of size [nx,ny,nz]. + */ + private void allocate() { + try { + this.data = new Object[nz]; + this.nxy = nx * ny; + for (int z = 0; z < nz; z++) + this.data[z] = new short[nxy]; + } + catch (Exception e) { + throw_constructor(nx, ny, nz); + } + } + +} // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/ShortPointwise.java b/src/bilib/src/imageware/ShortPointwise.java new file mode 100644 index 0000000000000000000000000000000000000000..8b6da121721170c2945ecef13078eb62546e2456 --- /dev/null +++ b/src/bilib/src/imageware/ShortPointwise.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import ij.process.ShortProcessor; import java.awt.Image; import java.util.Random; /** * Class ShortPointwise. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class ShortPointwise extends ShortAccess implements Pointwise { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected ShortPointwise(int nx, int ny, int nz) { super(nx, ny, nz); } protected ShortPointwise(Image image, int mode) { super(image, mode); } protected ShortPointwise(ImageStack stack, int mode) { super(stack, mode); } protected ShortPointwise(ImageStack stack, byte chan) { super(stack, chan); } protected ShortPointwise(byte[] array, int mode) { super(array, mode); } protected ShortPointwise(byte[][] array, int mode) { super(array, mode); } protected ShortPointwise(byte[][][] array, int mode) { super(array, mode); } protected ShortPointwise(short[] array, int mode) { super(array, mode); } protected ShortPointwise(short[][] array, int mode) { super(array, mode); } protected ShortPointwise(short[][][] array, int mode) { super(array, mode); } protected ShortPointwise(float[] array, int mode) { super(array, mode); } protected ShortPointwise(float[][] array, int mode) { super(array, mode); } protected ShortPointwise(float[][][] array, int mode) { super(array, mode); } protected ShortPointwise(double[] array, int mode) { super(array, mode); } protected ShortPointwise(double[][] array, int mode) { super(array, mode); } protected ShortPointwise(double[][][] array, int mode) { super(array, mode); } /** * Fill this imageware with a constant value. * * @param value * the constant value */ public void fillConstant(double value) { short typedValue = (short) value; short[] slice = null; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) slice[k] = typedValue; } } /** * Fill this imageware with ramp. */ public void fillRamp() { int off = 0; short[] slice = null; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) slice[k] = (short) (off + k); off += nxy; } } /** * Generate a gaussian noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void fillGaussianNoise(double amplitude) { Random rnd = new Random(); short[] slice = null; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) ((rnd.nextGaussian()) * amplitude); } } } /** * Generate a uniform noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void fillUniformNoise(double amplitude) { Random rnd = new Random(); short[] slice = null; amplitude *= 2.0; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) ((rnd.nextDouble() - 0.5) * amplitude); } } } /** * Generate a salt and pepper noise. * * @param amplitudeSalt * amplitude of the salt noise * @param amplitudePepper * amplitude of the pepper noise * @param percentageSalt * percentage of the salt noise * @param percentagePepper * percentage of the pepper noise */ public void fillSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper) { Random rnd = new Random(); int index, z; if (percentageSalt > 0) { double nbSalt = nxy * nz / percentageSalt; for (int k = 0; k < nbSalt; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((short[]) data[z])[index] = (short) (rnd.nextDouble() * amplitudeSalt); } } if (percentagePepper > 0) { double nbPepper = nxy * nz / percentagePepper; for (int k = 0; k < nbPepper; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((short[]) data[z])[index] = (short) (-rnd.nextDouble() * amplitudeSalt); } } } /** * Build an ImageStack of ImageJ. */ public ImageStack buildImageStack() { ImageStack imagestack = new ImageStack(nx, ny); for (int z = 0; z < nz; z++) { ShortProcessor ip = new ShortProcessor(nx, ny); short pix[] = (short[]) ip.getPixels(); for (int k = 0; k < nxy; k++) pix[k] = (short) (((short[]) data[z])[k]); imagestack.addSlice("" + z, ip); } return imagestack; } /** * Invert the pixel intensity. */ public void invert() { double max = -Double.MAX_VALUE; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFFFF) > max) max = slice[k] & 0xFFFF; } } for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) (max - ((double) (slice[k] & 0xFFFF))); } } } /** * Negate the pixel intensity. */ public void negate() { short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) (-((double) (slice[k] & 0xFFFF))); } } } /** * Clip the pixel intensity into [0..255]. */ public void clip() { clip(0.0, 255.0); } /** * Clip the pixel intensity into [minLevel..maxLevel]. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void clip(double minLevel, double maxLevel) { short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; short value; short min = (short) minLevel; short max = (short) maxLevel; for (int k = 0; k < nxy; k++) { value = (short) (slice[k] & 0xFFFF); if (value < min) slice[k] = min; if (value > max) slice[k] = max; } } } /** * Rescale the pixel intensity into [0..255]. */ public void rescale() { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFFFF) > maxImage) maxImage = slice[k] & 0xFFFF; if ((slice[k] & 0xFFFF) < minImage) minImage = slice[k] & 0xFFFF; } } double a; if (minImage - maxImage == 0) { a = 1.0; minImage = 128.0; } else { a = 255.0 / (maxImage - minImage); } for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) (a * (((double) (slice[k] & 0xFFFF)) - minImage)); } } } /** * Rescale the pixel intensity into [minLevel..maxLevel]. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void rescale(double minLevel, double maxLevel) { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFFFF) > maxImage) maxImage = slice[k] & 0xFFFF; if ((slice[k] & 0xFFFF) < minImage) minImage = slice[k] & 0xFFFF; } } double a; if (minImage - maxImage == 0) { a = 1.0; minImage = (maxLevel - minLevel) / 2.0; } else { a = (maxLevel - minLevel) / (maxImage - minImage); } for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) (a * (((double) (slice[k] & 0xFFFF)) - minImage) + minLevel); } } } /** * Rescale the pixel intensity with a linear curve passing through * (maxLevel-minLevel)/2 at the 0 input intensity. * * @param minLevel * double value given the threshold * @param maxLevel * double value given the threshold */ public void rescaleCenter(double minLevel, double maxLevel) { double maxImage = -Double.MAX_VALUE; double minImage = Double.MAX_VALUE; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFFFF) > maxImage) maxImage = slice[k] & 0xFFFF; if ((slice[k] & 0xFFFF) < minImage) minImage = slice[k] & 0xFFFF; } } double center = (maxLevel + minLevel) / 2.0; double a; if (minImage - maxImage == 0) { a = 1.0; minImage = (maxLevel - minLevel) / 2.0; } else { if (Math.abs(maxImage) > Math.abs(minImage)) a = (maxLevel - center) / Math.abs(maxImage); else a = (center - minLevel) / Math.abs(minImage); } for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) (a * (((double) (slice[k] & 0xFFFF)) - minImage) + center); } } } /** * Compute the absolute value of this imageware. */ public void abs() { } /** * Compute the log of this imageware. */ public void log() { short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) Math.log(slice[k]); } } } /** * Compute the exponential of this imageware. */ public void exp() { short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) Math.exp(slice[k]); } } } /** * Compute the square root of this imageware. */ public void sqrt() { short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) Math.sqrt(slice[k]); } } } /** * Compute the square of this imageware. */ public void sqr() { short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] *= slice[k]; } } } /** * Compute the power of a of this imageware. * * @param a * exponent */ public void pow(double a) { short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = (short) Math.pow(slice[k], a); } } } /** * Add a constant value to this imageware. */ public void add(double constant) { short cst = (short) constant; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += cst; } } } /** * Multiply a constant value to this imageware. * * @param constant * the constant value */ public void multiply(double constant) { short cst = (short) constant; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] *= cst; } } } /** * Subtract a constant value to this imageware. * * @param constant * the constant value */ public void subtract(double constant) { short cst = (short) constant; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] -= cst; } } } /** * Divide by a constant value to this imageware. * * @param constant * the constant value */ public void divide(double constant) { if (constant == 0.0) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to divide because the constant is 0.\n" + "-------------------------------------------------------\n"); short cst = (short) constant; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] /= cst; } } } /** * Threshold a imageware in two levels 0 and 255. * * All the pixels values strictly greater than 'thresholdValue' and are set * to 0. The remaining values are set to 255. * * @param thresholdValue * double value given the threshold */ public void threshold(double thresholdValue) { threshold(thresholdValue, 0.0, 255.0); } /** * Threshold a imageware in two levels minLevel and maxLevel. * * All the pixels values strictly greater than 'thresholdValue' and are set * to maxLevel. The remaining values are set to minLevel. * * @param thresholdValue * double value given the threshold * @param minLevel * double value given the minimum level * @param maxLevel * double value given the maximum level */ public void threshold(double thresholdValue, double minLevel, double maxLevel) { short low = (short) (minLevel); short high = (short) (maxLevel); short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] = ((double) (slice[k] & 0xFFFF) > thresholdValue ? high : low); } } } /** * Apply a soft thresholding. * * All the pixels values strictly greater than '-thresholdValue' and stricty * lower than 'thresholdValue' set to 0. The remaining positive values are * reduced by 'thresholdvalue'; the remaining negative values are augmented * by 'thresholdValue'. * * @param thresholdValue * double value given the threshold */ public void thresholdSoft(double thresholdValue) { short zero = (short) (0.0); double pixel; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { pixel = (double) (slice[k] & 0xFFFF); slice[k] = (pixel <= -thresholdValue ? (short) (pixel + thresholdValue) : (pixel > thresholdValue ? (short) (pixel - thresholdValue) : zero)); } } } /** * Apply a hard thresholding. * * All the pixels values strictly greater than '-thresholdValue' and stricty * lower than 'thresholdValue' are set to 0. The remaining values are * unchanged. * * @param thresholdValue * double value given the threshold */ public void thresholdHard(double thresholdValue) { short zero = (short) (0.0); double pixel; short[] slice; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { pixel = (double) (slice[k] & 0xFFFF); if (pixel > -thresholdValue && pixel < thresholdValue) slice[k] = zero; } } } /** * Add a gaussian noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void addGaussianNoise(double amplitude) { Random rnd = new Random(); short[] slice = null; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += (short) ((rnd.nextGaussian()) * amplitude); } } } /** * Add a uniform noise with a range [-amplitude..amplitude]. * * @param amplitude * amplitude of the noise */ public void addUniformNoise(double amplitude) { Random rnd = new Random(); short[] slice = null; amplitude *= 2.0; for (int z = 0; z < nz; z++) { slice = (short[]) data[z]; for (int k = 0; k < nxy; k++) { slice[k] += (short) ((rnd.nextDouble() - 0.5) * amplitude); } } } /** * Add a salt and pepper noise. * * @param amplitudeSalt * amplitude of the salt noise * @param amplitudePepper * amplitude of the pepper noise * @param percentageSalt * percentage of the salt noise * @param percentagePepper * percentage of the pepper noise */ public void addSaltPepper(double amplitudeSalt, double amplitudePepper, double percentageSalt, double percentagePepper) { Random rnd = new Random(); int index, z; if (percentageSalt > 0) { double nbSalt = nxy * nz / percentageSalt; for (int k = 0; k < nbSalt; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((short[]) data[z])[index] += (short) (rnd.nextDouble() * amplitudeSalt); } } if (percentagePepper > 0) { double nbPepper = nxy * nz / percentagePepper; for (int k = 0; k < nbPepper; k++) { index = (int) (rnd.nextDouble() * nxy); z = (int) (rnd.nextDouble() * nz); ((short[]) data[z])[index] -= (short) (rnd.nextDouble() * amplitudeSalt); } } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/ShortProcess.java b/src/bilib/src/imageware/ShortProcess.java new file mode 100644 index 0000000000000000000000000000000000000000..1a627c5b8b518385649cbe8630094c7dc7441e26 --- /dev/null +++ b/src/bilib/src/imageware/ShortProcess.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class ShortProcess. * * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class ShortProcess extends ShortPointwise implements Process { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected ShortProcess(int nx, int ny, int nz) { super(nx, ny, nz); } protected ShortProcess(Image image, int mode) { super(image, mode); } protected ShortProcess(ImageStack stack, int mode) { super(stack, mode); } protected ShortProcess(ImageStack stack, byte chan) { super(stack, chan); } protected ShortProcess(byte[] array, int mode) { super(array, mode); } protected ShortProcess(byte[][] array, int mode) { super(array, mode); } protected ShortProcess(byte[][][] array, int mode) { super(array, mode); } protected ShortProcess(short[] array, int mode) { super(array, mode); } protected ShortProcess(short[][] array, int mode) { super(array, mode); } protected ShortProcess(short[][][] array, int mode) { super(array, mode); } protected ShortProcess(float[] array, int mode) { super(array, mode); } protected ShortProcess(float[][] array, int mode) { super(array, mode); } protected ShortProcess(float[][][] array, int mode) { super(array, mode); } protected ShortProcess(double[] array, int mode) { super(array, mode); } protected ShortProcess(double[][] array, int mode) { super(array, mode); } protected ShortProcess(double[][][] array, int mode) { super(array, mode); } /** * Apply a separable gaussian smoothing over the image with the same * strengthness in all directions. To have a smmothing effect the * strengthness should be strictly greater than 0 and the size in the * considered directions should be greater strictly than 1. * * @param sigma * Strengthness of the smoothing */ public void smoothGaussian(double sigma) { smoothGaussian(sigma, sigma, sigma); } /** * Apply a separablegaussian smoothing over the image with an independant * strengthness in the different directions. To have a smmothing effect the * strengthness should be strictly greater than 0 and the size in the * considered directions should be greater strictly than 1. * * @param sigmaX * Strengthness of the smoothing in X axis * @param sigmaY * Strengthness of the smoothing in X axis * @param sigmaZ * Strengthness of the smoothing in X axis */ public void smoothGaussian(double sigmaX, double sigmaY, double sigmaZ) { int n = 3; double N = (double) n; double poles[] = new double[n]; if (nx > 1 && sigmaX > 0.0) { double s2 = sigmaX * sigmaX; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[nx]; for (int z = 0; z < nz; z++) { for (int y = 0; y < ny; y++) { getX(0, y, z, line); putX(0, y, z, Convolver.convolveIIR(line, poles)); } } } if (ny > 1 && sigmaY > 0.0) { double s2 = sigmaY * sigmaY; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[ny]; for (int x = 0; x < nx; x++) { for (int z = 0; z < nz; z++) { getY(x, 0, z, line); putY(x, 0, z, Convolver.convolveIIR(line, poles)); } } } if (nz > 1 && sigmaZ > 0.0) { double s2 = sigmaZ * sigmaZ; double alpha = 1.0 + (N / s2) - (Math.sqrt(N * N + 2 * N * s2) / s2); poles[0] = poles[1] = poles[2] = alpha; double line[] = new double[nz]; for (int y = 0; y < ny; y++) { for (int x = 0; x < nx; x++) { getZ(x, y, 0, line); putZ(x, y, 0, Convolver.convolveIIR(line, poles)); } } } } /** * Get the maximum of this imageware and a imageware. * * @param imageware * imageware to max */ public void max(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get the maximum because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { if (((short[]) data[z])[k] < (short) tmp[k]) ((short[]) data[z])[k] = (short) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { if (((short[]) data[z])[k] < (short) tmp[k]) ((short[]) data[z])[k] = (short) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { if (((short[]) data[z])[k] < (short) tmp[k]) ((short[]) data[z])[k] = (short) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { if (((short[]) data[z])[k] < (short) tmp[k]) ((short[]) data[z])[k] = (short) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Get the minimum of this imageware and a imageware. * * @param imageware * imageware to min */ public void min(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to get the minimum because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { if (((short[]) data[z])[k] > (short) tmp[k]) ((short[]) data[z])[k] = (short) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { if (((short[]) data[z])[k] > (short) tmp[k]) ((short[]) data[z])[k] = (short) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { if (((short[]) data[z])[k] > (short) tmp[k]) ((short[]) data[z])[k] = (short) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { if (((short[]) data[z])[k] > (short) tmp[k]) ((short[]) data[z])[k] = (short) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Add a imageware to the current imageware. * * @param imageware * imageware to add */ public void add(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to add because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] += (short) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] += (short) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] += (short) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] += (short) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Multiply a imageware to the current imageware. * * @param imageware * imageware to multiply */ public void multiply(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to multiply because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] *= (short) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] *= (short) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] *= (short) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] *= (short) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Subtract a imageware to the current imageware. * * @param imageware * imageware to subtract */ public void subtract(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to subtract because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] -= (short) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] -= (short) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] -= (short) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] -= (short) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } /** * Divide a imageware to the current imageware. * * @param imageware * imageware to divide */ public void divide(ImageWare imageware) { if (!isSameSize(imageware)) { throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to divide because the two operands are not the same size.\n" + "[" + nx + "," + ny + "," + "," + nz + "] != " + "[" + imageware.getSizeX() + "," + imageware.getSizeY() + "," + imageware.getSizeZ() + "].\n" + "-------------------------------------------------------\n"); } switch (imageware.getType()) { case ImageWare.BYTE: for (int z = 0; z < nz; z++) { byte[] tmp = ((ByteSet) imageware).getSliceByte(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] /= (short) tmp[k]; } } break; case ImageWare.SHORT: for (int z = 0; z < nz; z++) { short[] tmp = ((ShortSet) imageware).getSliceShort(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] /= (short) tmp[k]; } } break; case ImageWare.FLOAT: for (int z = 0; z < nz; z++) { float[] tmp = ((FloatSet) imageware).getSliceFloat(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] /= (short) tmp[k]; } } break; case ImageWare.DOUBLE: for (int z = 0; z < nz; z++) { double[] tmp = ((DoubleSet) imageware).getSliceDouble(z); for (int k = 0; k < nxy; k++) { ((short[]) data[z])[k] /= (short) tmp[k]; } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + imageware.getType() + "].\n" + "-------------------------------------------------------\n"); } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/imageware/ShortSet.java b/src/bilib/src/imageware/ShortSet.java new file mode 100644 index 0000000000000000000000000000000000000000..9e6012218e165a730d2ba859e3b5aaaa3bf98f7d --- /dev/null +++ b/src/bilib/src/imageware/ShortSet.java @@ -0,0 +1 @@ +package imageware; import ij.ImageStack; import java.awt.Image; /** * Class ShortSet. * * @author Daniel Sage Biomedical Imaging Group Ecole Polytechnique Federale de * Lausanne, Lausanne, Switzerland */ public class ShortSet extends ShortProcess implements ImageWare { // ------------------------------------------------------------------ // // Constructors section // // ------------------------------------------------------------------ protected ShortSet(int nx, int ny, int nz) { super(nx, ny, nz); } protected ShortSet(Image image, int mode) { super(image, mode); } protected ShortSet(ImageStack stack, int mode) { super(stack, mode); } protected ShortSet(ImageStack stack, byte chan) { super(stack, chan); } protected ShortSet(byte[] array, int mode) { super(array, mode); } protected ShortSet(byte[][] array, int mode) { super(array, mode); } protected ShortSet(byte[][][] array, int mode) { super(array, mode); } protected ShortSet(short[] array, int mode) { super(array, mode); } protected ShortSet(short[][] array, int mode) { super(array, mode); } protected ShortSet(short[][][] array, int mode) { super(array, mode); } protected ShortSet(float[] array, int mode) { super(array, mode); } protected ShortSet(float[][] array, int mode) { super(array, mode); } protected ShortSet(float[][][] array, int mode) { super(array, mode); } protected ShortSet(double[] array, int mode) { super(array, mode); } protected ShortSet(double[][] array, int mode) { super(array, mode); } protected ShortSet(double[][][] array, int mode) { super(array, mode); } /** * Duplicate the imageware. * * Create a new imageware with the same size, same type and same data than * the calling one. * * @return a duplicated version of this imageware */ public ImageWare duplicate() { ImageWare out = new ShortSet(nx, ny, nz); short[] outdata; for (int z = 0; z < nz; z++) { outdata = (short[]) (((ShortSet) out).data[z]); System.arraycopy(data[z], 0, outdata, 0, nxy); } return out; } /** * Replicate the imageware. * * Create a new imageware with the same size, same type than the calling * one. The data are not copied. * * @return a replicated version of this imageware */ public ImageWare replicate() { return new ShortSet(nx, ny, nz); } /** * Replicate the imageware. * * Create a new imageware with the same size and a specified type than the * calling one. The data are not copied. * * @param type * requested type * @return a replicated version of this imageware */ public ImageWare replicate(int type) { switch (type) { case ImageWare.BYTE: return new ByteSet(nx, ny, nz); case ImageWare.SHORT: return new ShortSet(nx, ny, nz); case ImageWare.FLOAT: return new FloatSet(nx, ny, nz); case ImageWare.DOUBLE: return new DoubleSet(nx, ny, nz); default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + "].\n" + "-------------------------------------------------------\n"); } } /** * Copy all the data of source in the current imageware. The source should * have the same size and same type than the calling one. * * @param source * a source imageware */ public void copy(ImageWare source) { if (nx != source.getSizeX()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + nx + " != " + source.getSizeX() + ").\n" + "-------------------------------------------------------\n"); if (ny != source.getSizeY()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + ny + " != " + source.getSizeY() + ").\n" + "-------------------------------------------------------\n"); if (nz != source.getSizeZ()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same size (" + nz + " != " + source.getSizeZ() + ").\n" + "-------------------------------------------------------\n"); if (getType() != source.getType()) throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unable to copy because it is not the same type (" + getType() + " != " + source.getType() + ").\n" + "-------------------------------------------------------\n"); short[] src; for (int z = 0; z < nz; z++) { src = (short[]) (((ShortSet) source).data[z]); System.arraycopy(src, 0, data[z], 0, nxy); } } /** * convert the imageware in a specified type. * * Create a new imageware with the same size and converted data than the * calling one. * * @param type * indicates the type of the output * @return a converted version of this imageware */ public ImageWare convert(int type) { if (type == ImageWare.SHORT) return duplicate(); ImageWare out = null; switch (type) { case ImageWare.BYTE: { short[] slice; out = new ByteSet(nx, ny, nz); byte[] outslice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); outslice = ((byte[]) ((ByteSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (byte) (slice[k] & 0xFFFF); } } } break; case ImageWare.SHORT: { short[] slice; out = new ShortSet(nx, ny, nz); short[] outslice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); outslice = ((short[]) ((ShortSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (short) (slice[k] & 0xFFFF); } } } break; case ImageWare.FLOAT: { short[] slice; out = new FloatSet(nx, ny, nz); float[] outslice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); outslice = ((float[]) ((FloatSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (float) (slice[k] & 0xFFFF); } } } break; case ImageWare.DOUBLE: { short[] slice; out = new DoubleSet(nx, ny, nz); double[] outslice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); outslice = ((double[]) ((DoubleSet) out).data[z]); for (int k = 0; k < nxy; k++) { outslice[k] = (double) (slice[k] & 0xFFFF); } } } break; default: throw new ArrayStoreException("\n-------------------------------------------------------\n" + "Error in imageware package\n" + "Unknown type " + type + "].\n" + "-------------------------------------------------------\n"); } return out; } /** * Print information of this ImageWare object. */ public void printInfo() { System.out.println("ImageWare object information"); System.out.println("Dimension: " + getDimension()); System.out.println("Size: [" + nx + ", " + ny + ", " + nz + "]"); System.out.println("TotalSize: " + getTotalSize()); System.out.println("Type: " + getTypeToString()); System.out.println("Maximun: " + getMaximum()); System.out.println("Minimun: " + getMinimum()); System.out.println("Mean: " + getMean()); System.out.println("Norm1: " + getNorm1()); System.out.println("Norm2: " + getNorm2()); System.out.println("Total: " + getTotal()); System.out.println(""); } /** * Show this ImageWare object. */ public void show() { String title = getTypeToString(); switch (getDimension()) { case 1: title += " line"; break; case 2: title += " image"; break; case 3: title += " volume"; break; } Display.show(title, this); // ImagePlus imp = new ImagePlus(title, buildImageStack()); // imp.show(); } /** * Show the data in ImagePlus object with a specify title. * * @param title * a string given the title of the window */ public void show(String title) { Display.show(title, this); // ImagePlus imp = new ImagePlus(title, buildImageStack()); // imp.show(); } /** * Return the minimum value of this imageware. * * @return the min value of this imageware */ public double getMinimum() { double min = Double.MAX_VALUE; short[] slice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); for (int k = 0; k < nxy; k++) if ((slice[k] & 0xFFFF) < min) min = slice[k] & 0xFFFF; } return min; } /** * Return the maximum value of this imageware. * * @return the max value of this imageware */ public double getMaximum() { double max = -Double.MAX_VALUE; short[] slice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); for (int k = 0; k < nxy; k++) if ((slice[k] & 0xFFFF) > max) max = slice[k] & 0xFFFF; } return max; } /** * Return the mean value of this imageware. * * @return the mean value of this imageware */ public double getMean() { return getTotal() / (nz * nxy); } /** * Return the norm value of order 1. * * @return the norm value of this imageware in L1 sense */ public double getNorm1() { double norm = 0.0; double value = 0; short[] slice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); for (int k = 0; k < nxy; k++) { value = (double) (slice[k] & 0xFFFF); norm += (value > 0.0 ? value : -value); } } return norm; } /** * Return the norm value of order 2. * * @return the norm value of this imageware in L2 sense */ public double getNorm2() { double norm = 0.0; short[] slice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); for (int k = 0; k < nxy; k++) norm += (slice[k] & 0xFFFF) * (slice[k] & 0xFFFF); } return norm; } /** * Return the sum of all pixel in this imageware. * * @return the total sum of all pixel in this imageware */ public double getTotal() { double total = 0.0; short[] slice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); for (int k = 0; k < nxy; k++) total += slice[k] & 0xFFFF; } return total; } /** * Return the the minumum [0] and the maximum [1] value of this imageware. * Faster routine than call one getMinimum() and then one getMaximum(). * * @return an array of two values, the min and the max values of the images */ public double[] getMinMax() { double max = -Double.MAX_VALUE; double min = Double.MAX_VALUE; short[] slice; for (int z = 0; z < nz; z++) { slice = ((short[]) data[z]); for (int k = 0; k < nxy; k++) { if ((slice[k] & 0xFFFF) > max) max = slice[k] & 0xFFFF; if ((slice[k] & 0xFFFF) < min) min = slice[k] & 0xFFFF; } } double minmax[] = { min, max }; return minmax; } } // end of class \ No newline at end of file diff --git a/src/bilib/src/jama/CholeskyDecomposition.java b/src/bilib/src/jama/CholeskyDecomposition.java new file mode 100644 index 0000000000000000000000000000000000000000..a9befbe2a5893aed7356e360f8760595554ea0dc --- /dev/null +++ b/src/bilib/src/jama/CholeskyDecomposition.java @@ -0,0 +1,195 @@ +package jama; + +/** + * Cholesky Decomposition. + * <P> + * For a symmetric, positive definite matrix A, the Cholesky decomposition is an + * lower triangular matrix L so that A = L*L'. + * <P> + * If the matrix is not symmetric or positive definite, the constructor returns + * a partial decomposition and sets an internal flag that may be queried by the + * isSPD() method. + */ + +public class CholeskyDecomposition implements java.io.Serializable { + + /* + * ------------------------ Class variables ------------------------ + */ + + /** + * Array for internal storage of decomposition. + * + * @serial internal array storage. + */ + private double[][] L; + + /** + * Row and column dimension (square matrix). + * + * @serial matrix dimension. + */ + private int n; + + /** + * Symmetric and positive definite flag. + * + * @serial is symmetric and positive definite flag. + */ + private boolean isspd; + + /* + * ------------------------ Constructor ------------------------ + */ + + /** + * Cholesky algorithm for symmetric and positive definite matrix. + * + * @param Arg + * Square, symmetric matrix. + */ + + public CholeskyDecomposition(Matrix Arg) { + + // Initialize. + double[][] A = Arg.getArray(); + n = Arg.getRowDimension(); + L = new double[n][n]; + isspd = (Arg.getColumnDimension() == n); + // Main loop. + for (int j = 0; j < n; j++) { + double[] Lrowj = L[j]; + double d = 0.0; + for (int k = 0; k < j; k++) { + double[] Lrowk = L[k]; + double s = 0.0; + for (int i = 0; i < k; i++) { + s += Lrowk[i] * Lrowj[i]; + } + Lrowj[k] = s = (A[j][k] - s) / L[k][k]; + d = d + s * s; + isspd = isspd & (A[k][j] == A[j][k]); + } + d = A[j][j] - d; + isspd = isspd & (d > 0.0); + L[j][j] = Math.sqrt(Math.max(d, 0.0)); + for (int k = j + 1; k < n; k++) { + L[j][k] = 0.0; + } + } + } + + /* + * ------------------------ Temporary, experimental code. + * ------------------------ *\ + * + * \** Right Triangular Cholesky Decomposition. <P> For a symmetric, + * positive definite matrix A, the Right Cholesky decomposition is an upper + * triangular matrix R so that A = R'*R. This constructor computes R with + * the Fortran inspired column oriented algorithm used in LINPACK and + * MATLAB. In Java, we suspect a row oriented, lower triangular + * decomposition is faster. We have temporarily included this constructor + * here until timing experiments confirm this suspicion.\ + * + * \** Array for internal storage of right triangular decomposition. **\ + * private transient double[][] R; + * + * \** Cholesky algorithm for symmetric and positive definite matrix. + * + * @param A Square, symmetric matrix. + * + * @param rightflag Actual value ignored. + * + * @return Structure to access R and isspd flag.\ + * + * public CholeskyDecomposition (Matrix Arg, int rightflag) { // Initialize. + * double[][] A = Arg.getArray(); n = Arg.getColumnDimension(); R = new + * double[n][n]; isspd = (Arg.getColumnDimension() == n); // Main loop. for + * (int j = 0; j < n; j++) { double d = 0.0; for (int k = 0; k < j; k++) { + * double s = A[k][j]; for (int i = 0; i < k; i++) { s = s - + * R[i][k]*R[i][j]; } R[k][j] = s = s/R[k][k]; d = d + s*s; isspd = isspd & + * (A[k][j] == A[j][k]); } d = A[j][j] - d; isspd = isspd & (d > 0.0); + * R[j][j] = Math.sqrt(Math.max(d,0.0)); for (int k = j+1; k < n; k++) { + * R[k][j] = 0.0; } } } + * + * \** Return upper triangular factor. + * + * @return R\ + * + * public Matrix getR () { return new Matrix(R,n,n); } + * + * \* ------------------------ End of temporary code. + * ------------------------ + */ + + /* + * ------------------------ Public Methods ------------------------ + */ + + /** + * Is the matrix symmetric and positive definite? + * + * @return true if A is symmetric and positive definite. + */ + + public boolean isSPD() { + return isspd; + } + + /** + * Return triangular factor. + * + * @return L + */ + + public Matrix getL() { + return new Matrix(L, n, n); + } + + /** + * Solve A*X = B + * + * @param B + * A Matrix with as many rows as A and any number of columns. + * @return X so that L*L'*X = B + * @exception IllegalArgumentException + * Matrix row dimensions must agree. + * @exception RuntimeException + * Matrix is not symmetric positive definite. + */ + + public Matrix solve(Matrix B) { + if (B.getRowDimension() != n) { + throw new IllegalArgumentException("Matrix row dimensions must agree."); + } + if (!isspd) { + throw new RuntimeException("Matrix is not symmetric positive definite."); + } + + // Copy right hand side. + double[][] X = B.getArrayCopy(); + int nx = B.getColumnDimension(); + + // Solve L*Y = B; + for (int k = 0; k < n; k++) { + for (int j = 0; j < nx; j++) { + for (int i = 0; i < k; i++) { + X[k][j] -= X[i][j] * L[k][i]; + } + X[k][j] /= L[k][k]; + } + } + + // Solve L'*X = Y; + for (int k = n - 1; k >= 0; k--) { + for (int j = 0; j < nx; j++) { + for (int i = k + 1; i < n; i++) { + X[k][j] -= X[i][j] * L[i][k]; + } + X[k][j] /= L[k][k]; + } + } + + return new Matrix(X, n, nx); + } +} diff --git a/src/bilib/src/jama/EigenvalueDecomposition.java b/src/bilib/src/jama/EigenvalueDecomposition.java new file mode 100644 index 0000000000000000000000000000000000000000..8f5dff00f920caac461a2c088e90f93498ae2a3a --- /dev/null +++ b/src/bilib/src/jama/EigenvalueDecomposition.java @@ -0,0 +1,990 @@ +package jama; + +/** + * Eigenvalues and eigenvectors of a real matrix. + * <P> + * If A is symmetric, then A = V*D*V' where the eigenvalue matrix D is diagonal + * and the eigenvector matrix V is orthogonal. I.e. A = + * V.times(D.times(V.transpose())) and V.times(V.transpose()) equals the + * identity matrix. + * <P> + * If A is not symmetric, then the eigenvalue matrix D is block diagonal with + * the real eigenvalues in 1-by-1 blocks and any complex eigenvalues, lambda + + * i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The columns of V represent + * the eigenvectors in the sense that A*V = V*D, i.e. A.times(V) equals + * V.times(D). The matrix V may be badly conditioned, or even singular, so the + * validity of the equation A = V*D*inverse(V) depends upon V.cond(). + **/ + +public class EigenvalueDecomposition implements java.io.Serializable { + + /* + * ------------------------ Class variables ------------------------ + */ + + /** + * Row and column dimension (square matrix). + * + * @serial matrix dimension. + */ + private int n; + + /** + * Symmetry flag. + * + * @serial internal symmetry flag. + */ + private boolean issymmetric; + + /** + * Arrays for internal storage of eigenvalues. + * + * @serial internal storage of eigenvalues. + */ + private double[] d, e; + + /** + * Array for internal storage of eigenvectors. + * + * @serial internal storage of eigenvectors. + */ + private double[][] V; + + /** + * Array for internal storage of nonsymmetric Hessenberg form. + * + * @serial internal storage of nonsymmetric Hessenberg form. + */ + private double[][] H; + + /** + * Working storage for nonsymmetric algorithm. + * + * @serial working storage for nonsymmetric algorithm. + */ + private double[] ort; + + /* + * ------------------------ Private Methods ------------------------ + */ + + // Symmetric Householder reduction to tridiagonal form. + + private void tred2() { + + // This is derived from the Algol procedures tred2 by + // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for + // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding + // Fortran subroutine in EISPACK. + + for (int j = 0; j < n; j++) { + d[j] = V[n - 1][j]; + } + + // Householder reduction to tridiagonal form. + + for (int i = n - 1; i > 0; i--) { + + // Scale to avoid under/overflow. + + double scale = 0.0; + double h = 0.0; + for (int k = 0; k < i; k++) { + scale = scale + Math.abs(d[k]); + } + if (scale == 0.0) { + e[i] = d[i - 1]; + for (int j = 0; j < i; j++) { + d[j] = V[i - 1][j]; + V[i][j] = 0.0; + V[j][i] = 0.0; + } + } + else { + + // Generate Householder vector. + + for (int k = 0; k < i; k++) { + d[k] /= scale; + h += d[k] * d[k]; + } + double f = d[i - 1]; + double g = Math.sqrt(h); + if (f > 0) { + g = -g; + } + e[i] = scale * g; + h = h - f * g; + d[i - 1] = f - g; + for (int j = 0; j < i; j++) { + e[j] = 0.0; + } + + // Apply similarity transformation to remaining columns. + + for (int j = 0; j < i; j++) { + f = d[j]; + V[j][i] = f; + g = e[j] + V[j][j] * f; + for (int k = j + 1; k <= i - 1; k++) { + g += V[k][j] * d[k]; + e[k] += V[k][j] * f; + } + e[j] = g; + } + f = 0.0; + for (int j = 0; j < i; j++) { + e[j] /= h; + f += e[j] * d[j]; + } + double hh = f / (h + h); + for (int j = 0; j < i; j++) { + e[j] -= hh * d[j]; + } + for (int j = 0; j < i; j++) { + f = d[j]; + g = e[j]; + for (int k = j; k <= i - 1; k++) { + V[k][j] -= (f * e[k] + g * d[k]); + } + d[j] = V[i - 1][j]; + V[i][j] = 0.0; + } + } + d[i] = h; + } + + // Accumulate transformations. + + for (int i = 0; i < n - 1; i++) { + V[n - 1][i] = V[i][i]; + V[i][i] = 1.0; + double h = d[i + 1]; + if (h != 0.0) { + for (int k = 0; k <= i; k++) { + d[k] = V[k][i + 1] / h; + } + for (int j = 0; j <= i; j++) { + double g = 0.0; + for (int k = 0; k <= i; k++) { + g += V[k][i + 1] * V[k][j]; + } + for (int k = 0; k <= i; k++) { + V[k][j] -= g * d[k]; + } + } + } + for (int k = 0; k <= i; k++) { + V[k][i + 1] = 0.0; + } + } + for (int j = 0; j < n; j++) { + d[j] = V[n - 1][j]; + V[n - 1][j] = 0.0; + } + V[n - 1][n - 1] = 1.0; + e[0] = 0.0; + } + + // Symmetric tridiagonal QL algorithm. + + private void tql2() { + + // This is derived from the Algol procedures tql2, by + // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for + // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding + // Fortran subroutine in EISPACK. + + for (int i = 1; i < n; i++) { + e[i - 1] = e[i]; + } + e[n - 1] = 0.0; + + double f = 0.0; + double tst1 = 0.0; + double eps = Math.pow(2.0, -52.0); + for (int l = 0; l < n; l++) { + + // Find small subdiagonal element + + tst1 = Math.max(tst1, Math.abs(d[l]) + Math.abs(e[l])); + int m = l; + while (m < n) { + if (Math.abs(e[m]) <= eps * tst1) { + break; + } + m++; + } + + // If m == l, d[l] is an eigenvalue, + // otherwise, iterate. + + if (m > l) { + int iter = 0; + do { + iter = iter + 1; // (Could check iteration count here.) + + // Compute implicit shift + + double g = d[l]; + double p = (d[l + 1] - g) / (2.0 * e[l]); + double r = Maths.hypot(p, 1.0); + if (p < 0) { + r = -r; + } + d[l] = e[l] / (p + r); + d[l + 1] = e[l] * (p + r); + double dl1 = d[l + 1]; + double h = g - d[l]; + for (int i = l + 2; i < n; i++) { + d[i] -= h; + } + f = f + h; + + // Implicit QL transformation. + + p = d[m]; + double c = 1.0; + double c2 = c; + double c3 = c; + double el1 = e[l + 1]; + double s = 0.0; + double s2 = 0.0; + for (int i = m - 1; i >= l; i--) { + c3 = c2; + c2 = c; + s2 = s; + g = c * e[i]; + h = c * p; + r = Maths.hypot(p, e[i]); + e[i + 1] = s * r; + s = e[i] / r; + c = p / r; + p = c * d[i] - s * g; + d[i + 1] = h + s * (c * g + s * d[i]); + + // Accumulate transformation. + + for (int k = 0; k < n; k++) { + h = V[k][i + 1]; + V[k][i + 1] = s * V[k][i] + c * h; + V[k][i] = c * V[k][i] - s * h; + } + } + p = -s * s2 * c3 * el1 * e[l] / dl1; + e[l] = s * p; + d[l] = c * p; + + // Check for convergence. + + } + while (Math.abs(e[l]) > eps * tst1); + } + d[l] = d[l] + f; + e[l] = 0.0; + } + + // Sort eigenvalues and corresponding vectors. + + for (int i = 0; i < n - 1; i++) { + int k = i; + double p = d[i]; + for (int j = i + 1; j < n; j++) { + if (d[j] < p) { + k = j; + p = d[j]; + } + } + if (k != i) { + d[k] = d[i]; + d[i] = p; + for (int j = 0; j < n; j++) { + p = V[j][i]; + V[j][i] = V[j][k]; + V[j][k] = p; + } + } + } + } + + // Nonsymmetric reduction to Hessenberg form. + + private void orthes() { + + // This is derived from the Algol procedures orthes and ortran, + // by Martin and Wilkinson, Handbook for Auto. Comp., + // Vol.ii-Linear Algebra, and the corresponding + // Fortran subroutines in EISPACK. + + int low = 0; + int high = n - 1; + + for (int m = low + 1; m <= high - 1; m++) { + + // Scale column. + + double scale = 0.0; + for (int i = m; i <= high; i++) { + scale = scale + Math.abs(H[i][m - 1]); + } + if (scale != 0.0) { + + // Compute Householder transformation. + + double h = 0.0; + for (int i = high; i >= m; i--) { + ort[i] = H[i][m - 1] / scale; + h += ort[i] * ort[i]; + } + double g = Math.sqrt(h); + if (ort[m] > 0) { + g = -g; + } + h = h - ort[m] * g; + ort[m] = ort[m] - g; + + // Apply Householder similarity transformation + // H = (I-u*u'/h)*H*(I-u*u')/h) + + for (int j = m; j < n; j++) { + double f = 0.0; + for (int i = high; i >= m; i--) { + f += ort[i] * H[i][j]; + } + f = f / h; + for (int i = m; i <= high; i++) { + H[i][j] -= f * ort[i]; + } + } + + for (int i = 0; i <= high; i++) { + double f = 0.0; + for (int j = high; j >= m; j--) { + f += ort[j] * H[i][j]; + } + f = f / h; + for (int j = m; j <= high; j++) { + H[i][j] -= f * ort[j]; + } + } + ort[m] = scale * ort[m]; + H[m][m - 1] = scale * g; + } + } + + // Accumulate transformations (Algol's ortran). + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + V[i][j] = (i == j ? 1.0 : 0.0); + } + } + + for (int m = high - 1; m >= low + 1; m--) { + if (H[m][m - 1] != 0.0) { + for (int i = m + 1; i <= high; i++) { + ort[i] = H[i][m - 1]; + } + for (int j = m; j <= high; j++) { + double g = 0.0; + for (int i = m; i <= high; i++) { + g += ort[i] * V[i][j]; + } + // Double division avoids possible underflow + g = (g / ort[m]) / H[m][m - 1]; + for (int i = m; i <= high; i++) { + V[i][j] += g * ort[i]; + } + } + } + } + } + + // Complex scalar division. + + private transient double cdivr, cdivi; + + private void cdiv(double xr, double xi, double yr, double yi) { + double r, d; + if (Math.abs(yr) > Math.abs(yi)) { + r = yi / yr; + d = yr + r * yi; + cdivr = (xr + r * xi) / d; + cdivi = (xi - r * xr) / d; + } + else { + r = yr / yi; + d = yi + r * yr; + cdivr = (r * xr + xi) / d; + cdivi = (r * xi - xr) / d; + } + } + + // Nonsymmetric reduction from Hessenberg to real Schur form. + + private void hqr2() { + + // This is derived from the Algol procedure hqr2, + // by Martin and Wilkinson, Handbook for Auto. Comp., + // Vol.ii-Linear Algebra, and the corresponding + // Fortran subroutine in EISPACK. + + // Initialize + + int nn = this.n; + int n = nn - 1; + int low = 0; + int high = nn - 1; + double eps = Math.pow(2.0, -52.0); + double exshift = 0.0; + double p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y; + + // Store roots isolated by balanc and compute matrix norm + + double norm = 0.0; + for (int i = 0; i < nn; i++) { + if (i < low | i > high) { + d[i] = H[i][i]; + e[i] = 0.0; + } + for (int j = Math.max(i - 1, 0); j < nn; j++) { + norm = norm + Math.abs(H[i][j]); + } + } + + // Outer loop over eigenvalue index + + int iter = 0; + while (n >= low) { + + // Look for single small sub-diagonal element + + int l = n; + while (l > low) { + s = Math.abs(H[l - 1][l - 1]) + Math.abs(H[l][l]); + if (s == 0.0) { + s = norm; + } + if (Math.abs(H[l][l - 1]) < eps * s) { + break; + } + l--; + } + + // Check for convergence + // One root found + + if (l == n) { + H[n][n] = H[n][n] + exshift; + d[n] = H[n][n]; + e[n] = 0.0; + n--; + iter = 0; + + // Two roots found + + } + else if (l == n - 1) { + w = H[n][n - 1] * H[n - 1][n]; + p = (H[n - 1][n - 1] - H[n][n]) / 2.0; + q = p * p + w; + z = Math.sqrt(Math.abs(q)); + H[n][n] = H[n][n] + exshift; + H[n - 1][n - 1] = H[n - 1][n - 1] + exshift; + x = H[n][n]; + + // Real pair + + if (q >= 0) { + if (p >= 0) { + z = p + z; + } + else { + z = p - z; + } + d[n - 1] = x + z; + d[n] = d[n - 1]; + if (z != 0.0) { + d[n] = x - w / z; + } + e[n - 1] = 0.0; + e[n] = 0.0; + x = H[n][n - 1]; + s = Math.abs(x) + Math.abs(z); + p = x / s; + q = z / s; + r = Math.sqrt(p * p + q * q); + p = p / r; + q = q / r; + + // Row modification + + for (int j = n - 1; j < nn; j++) { + z = H[n - 1][j]; + H[n - 1][j] = q * z + p * H[n][j]; + H[n][j] = q * H[n][j] - p * z; + } + + // Column modification + + for (int i = 0; i <= n; i++) { + z = H[i][n - 1]; + H[i][n - 1] = q * z + p * H[i][n]; + H[i][n] = q * H[i][n] - p * z; + } + + // Accumulate transformations + + for (int i = low; i <= high; i++) { + z = V[i][n - 1]; + V[i][n - 1] = q * z + p * V[i][n]; + V[i][n] = q * V[i][n] - p * z; + } + + // Complex pair + + } + else { + d[n - 1] = x + p; + d[n] = x + p; + e[n - 1] = z; + e[n] = -z; + } + n = n - 2; + iter = 0; + + // No convergence yet + + } + else { + + // Form shift + + x = H[n][n]; + y = 0.0; + w = 0.0; + if (l < n) { + y = H[n - 1][n - 1]; + w = H[n][n - 1] * H[n - 1][n]; + } + + // Wilkinson's original ad hoc shift + + if (iter == 10) { + exshift += x; + for (int i = low; i <= n; i++) { + H[i][i] -= x; + } + s = Math.abs(H[n][n - 1]) + Math.abs(H[n - 1][n - 2]); + x = y = 0.75 * s; + w = -0.4375 * s * s; + } + + // MATLAB's new ad hoc shift + + if (iter == 30) { + s = (y - x) / 2.0; + s = s * s + w; + if (s > 0) { + s = Math.sqrt(s); + if (y < x) { + s = -s; + } + s = x - w / ((y - x) / 2.0 + s); + for (int i = low; i <= n; i++) { + H[i][i] -= s; + } + exshift += s; + x = y = w = 0.964; + } + } + + iter = iter + 1; // (Could check iteration count here.) + + // Look for two consecutive small sub-diagonal elements + + int m = n - 2; + while (m >= l) { + z = H[m][m]; + r = x - z; + s = y - z; + p = (r * s - w) / H[m + 1][m] + H[m][m + 1]; + q = H[m + 1][m + 1] - z - r - s; + r = H[m + 2][m + 1]; + s = Math.abs(p) + Math.abs(q) + Math.abs(r); + p = p / s; + q = q / s; + r = r / s; + if (m == l) { + break; + } + if (Math.abs(H[m][m - 1]) * (Math.abs(q) + Math.abs(r)) < eps * (Math.abs(p) * (Math.abs(H[m - 1][m - 1]) + Math.abs(z) + Math.abs(H[m + 1][m + 1])))) { + break; + } + m--; + } + + for (int i = m + 2; i <= n; i++) { + H[i][i - 2] = 0.0; + if (i > m + 2) { + H[i][i - 3] = 0.0; + } + } + + // Double QR step involving rows l:n and columns m:n + + for (int k = m; k <= n - 1; k++) { + boolean notlast = (k != n - 1); + if (k != m) { + p = H[k][k - 1]; + q = H[k + 1][k - 1]; + r = (notlast ? H[k + 2][k - 1] : 0.0); + x = Math.abs(p) + Math.abs(q) + Math.abs(r); + if (x != 0.0) { + p = p / x; + q = q / x; + r = r / x; + } + } + if (x == 0.0) { + break; + } + s = Math.sqrt(p * p + q * q + r * r); + if (p < 0) { + s = -s; + } + if (s != 0) { + if (k != m) { + H[k][k - 1] = -s * x; + } + else if (l != m) { + H[k][k - 1] = -H[k][k - 1]; + } + p = p + s; + x = p / s; + y = q / s; + z = r / s; + q = q / p; + r = r / p; + + // Row modification + + for (int j = k; j < nn; j++) { + p = H[k][j] + q * H[k + 1][j]; + if (notlast) { + p = p + r * H[k + 2][j]; + H[k + 2][j] = H[k + 2][j] - p * z; + } + H[k][j] = H[k][j] - p * x; + H[k + 1][j] = H[k + 1][j] - p * y; + } + + // Column modification + + for (int i = 0; i <= Math.min(n, k + 3); i++) { + p = x * H[i][k] + y * H[i][k + 1]; + if (notlast) { + p = p + z * H[i][k + 2]; + H[i][k + 2] = H[i][k + 2] - p * r; + } + H[i][k] = H[i][k] - p; + H[i][k + 1] = H[i][k + 1] - p * q; + } + + // Accumulate transformations + + for (int i = low; i <= high; i++) { + p = x * V[i][k] + y * V[i][k + 1]; + if (notlast) { + p = p + z * V[i][k + 2]; + V[i][k + 2] = V[i][k + 2] - p * r; + } + V[i][k] = V[i][k] - p; + V[i][k + 1] = V[i][k + 1] - p * q; + } + } // (s != 0) + } // k loop + } // check convergence + } // while (n >= low) + + // Backsubstitute to find vectors of upper triangular form + + if (norm == 0.0) { + return; + } + + for (n = nn - 1; n >= 0; n--) { + p = d[n]; + q = e[n]; + + // Real vector + + if (q == 0) { + int l = n; + H[n][n] = 1.0; + for (int i = n - 1; i >= 0; i--) { + w = H[i][i] - p; + r = 0.0; + for (int j = l; j <= n; j++) { + r = r + H[i][j] * H[j][n]; + } + if (e[i] < 0.0) { + z = w; + s = r; + } + else { + l = i; + if (e[i] == 0.0) { + if (w != 0.0) { + H[i][n] = -r / w; + } + else { + H[i][n] = -r / (eps * norm); + } + + // Solve real equations + + } + else { + x = H[i][i + 1]; + y = H[i + 1][i]; + q = (d[i] - p) * (d[i] - p) + e[i] * e[i]; + t = (x * s - z * r) / q; + H[i][n] = t; + if (Math.abs(x) > Math.abs(z)) { + H[i + 1][n] = (-r - w * t) / x; + } + else { + H[i + 1][n] = (-s - y * t) / z; + } + } + + // Overflow control + + t = Math.abs(H[i][n]); + if ((eps * t) * t > 1) { + for (int j = i; j <= n; j++) { + H[j][n] = H[j][n] / t; + } + } + } + } + + // Complex vector + + } + else if (q < 0) { + int l = n - 1; + + // Last vector component imaginary so matrix is triangular + + if (Math.abs(H[n][n - 1]) > Math.abs(H[n - 1][n])) { + H[n - 1][n - 1] = q / H[n][n - 1]; + H[n - 1][n] = -(H[n][n] - p) / H[n][n - 1]; + } + else { + cdiv(0.0, -H[n - 1][n], H[n - 1][n - 1] - p, q); + H[n - 1][n - 1] = cdivr; + H[n - 1][n] = cdivi; + } + H[n][n - 1] = 0.0; + H[n][n] = 1.0; + for (int i = n - 2; i >= 0; i--) { + double ra, sa, vr, vi; + ra = 0.0; + sa = 0.0; + for (int j = l; j <= n; j++) { + ra = ra + H[i][j] * H[j][n - 1]; + sa = sa + H[i][j] * H[j][n]; + } + w = H[i][i] - p; + + if (e[i] < 0.0) { + z = w; + r = ra; + s = sa; + } + else { + l = i; + if (e[i] == 0) { + cdiv(-ra, -sa, w, q); + H[i][n - 1] = cdivr; + H[i][n] = cdivi; + } + else { + + // Solve complex equations + + x = H[i][i + 1]; + y = H[i + 1][i]; + vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q; + vi = (d[i] - p) * 2.0 * q; + if (vr == 0.0 & vi == 0.0) { + vr = eps * norm * (Math.abs(w) + Math.abs(q) + Math.abs(x) + Math.abs(y) + Math.abs(z)); + } + cdiv(x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi); + H[i][n - 1] = cdivr; + H[i][n] = cdivi; + if (Math.abs(x) > (Math.abs(z) + Math.abs(q))) { + H[i + 1][n - 1] = (-ra - w * H[i][n - 1] + q * H[i][n]) / x; + H[i + 1][n] = (-sa - w * H[i][n] - q * H[i][n - 1]) / x; + } + else { + cdiv(-r - y * H[i][n - 1], -s - y * H[i][n], z, q); + H[i + 1][n - 1] = cdivr; + H[i + 1][n] = cdivi; + } + } + + // Overflow control + + t = Math.max(Math.abs(H[i][n - 1]), Math.abs(H[i][n])); + if ((eps * t) * t > 1) { + for (int j = i; j <= n; j++) { + H[j][n - 1] = H[j][n - 1] / t; + H[j][n] = H[j][n] / t; + } + } + } + } + } + } + + // Vectors of isolated roots + + for (int i = 0; i < nn; i++) { + if (i < low | i > high) { + for (int j = i; j < nn; j++) { + V[i][j] = H[i][j]; + } + } + } + + // Back transformation to get eigenvectors of original matrix + + for (int j = nn - 1; j >= low; j--) { + for (int i = low; i <= high; i++) { + z = 0.0; + for (int k = low; k <= Math.min(j, high); k++) { + z = z + V[i][k] * H[k][j]; + } + V[i][j] = z; + } + } + } + + /* + * ------------------------ Constructor ------------------------ + */ + + /** + * Check for symmetry, then construct the eigenvalue decomposition + * + * @param Arg + * Square matrix + */ + + public EigenvalueDecomposition(Matrix Arg) { + double[][] A = Arg.getArray(); + n = Arg.getColumnDimension(); + V = new double[n][n]; + d = new double[n]; + e = new double[n]; + + issymmetric = true; + for (int j = 0; (j < n) & issymmetric; j++) { + for (int i = 0; (i < n) & issymmetric; i++) { + issymmetric = (A[i][j] == A[j][i]); + } + } + + if (issymmetric) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + V[i][j] = A[i][j]; + } + } + + // Tridiagonalize. + tred2(); + + // Diagonalize. + tql2(); + + } + else { + H = new double[n][n]; + ort = new double[n]; + + for (int j = 0; j < n; j++) { + for (int i = 0; i < n; i++) { + H[i][j] = A[i][j]; + } + } + + // Reduce to Hessenberg form. + orthes(); + + // Reduce Hessenberg to real Schur form. + hqr2(); + } + } + + /* + * ------------------------ Public Methods ------------------------ + */ + + /** + * Return the eigenvector matrix + * + * @return V + */ + + public Matrix getV() { + return new Matrix(V, n, n); + } + + /** + * Return the real parts of the eigenvalues + * + * @return real(diag(D)) + */ + + public double[] getRealEigenvalues() { + return d; + } + + /** + * Return the imaginary parts of the eigenvalues + * + * @return imag(diag(D)) + */ + + public double[] getImagEigenvalues() { + return e; + } + + /** + * Return the block diagonal eigenvalue matrix + * + * @return D + */ + + public Matrix getD() { + Matrix X = new Matrix(n, n); + double[][] D = X.getArray(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + D[i][j] = 0.0; + } + D[i][i] = d[i]; + if (e[i] > 0) { + D[i][i + 1] = e[i]; + } + else if (e[i] < 0) { + D[i][i - 1] = e[i]; + } + } + return X; + } +} diff --git a/src/bilib/src/jama/LUDecomposition.java b/src/bilib/src/jama/LUDecomposition.java new file mode 100644 index 0000000000000000000000000000000000000000..cc18e7bb28e845909f5e48bf6858d9ec11f7da4f --- /dev/null +++ b/src/bilib/src/jama/LUDecomposition.java @@ -0,0 +1,318 @@ +package jama; + +/** + * LU Decomposition. + * <P> + * For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n unit + * lower triangular matrix L, an n-by-n upper triangular matrix U, and a + * permutation vector piv of length m so that A(piv,:) = L*U. If m < n, then L + * is m-by-m and U is m-by-n. + * <P> + * The LU decompostion with pivoting always exists, even if the matrix is + * singular, so the constructor will never fail. The primary use of the LU + * decomposition is in the solution of square systems of simultaneous linear + * equations. This will fail if isNonsingular() returns false. + */ + +public class LUDecomposition implements java.io.Serializable { + + /* + * ------------------------ Class variables ------------------------ + */ + + /** + * Array for internal storage of decomposition. + * + * @serial internal array storage. + */ + private double[][] LU; + + /** + * Row and column dimensions, and pivot sign. + * + * @serial column dimension. + * @serial row dimension. + * @serial pivot sign. + */ + private int m, n, pivsign; + + /** + * Internal storage of pivot vector. + * + * @serial pivot vector. + */ + private int[] piv; + + /* + * ------------------------ Constructor ------------------------ + */ + + /** + * LU Decomposition + * + * @param A + * Rectangular matrix + */ + + public LUDecomposition(Matrix A) { + + // Use a "left-looking", dot-product, Crout/Doolittle algorithm. + + LU = A.getArrayCopy(); + m = A.getRowDimension(); + n = A.getColumnDimension(); + piv = new int[m]; + for (int i = 0; i < m; i++) { + piv[i] = i; + } + pivsign = 1; + double[] LUrowi; + double[] LUcolj = new double[m]; + + // Outer loop. + + for (int j = 0; j < n; j++) { + + // Make a copy of the j-th column to localize references. + + for (int i = 0; i < m; i++) { + LUcolj[i] = LU[i][j]; + } + + // Apply previous transformations. + + for (int i = 0; i < m; i++) { + LUrowi = LU[i]; + + // Most of the time is spent in the following dot product. + + int kmax = Math.min(i, j); + double s = 0.0; + for (int k = 0; k < kmax; k++) { + s += LUrowi[k] * LUcolj[k]; + } + + LUrowi[j] = LUcolj[i] -= s; + } + + // Find pivot and exchange if necessary. + + int p = j; + for (int i = j + 1; i < m; i++) { + if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) { + p = i; + } + } + if (p != j) { + for (int k = 0; k < n; k++) { + double t = LU[p][k]; + LU[p][k] = LU[j][k]; + LU[j][k] = t; + } + int k = piv[p]; + piv[p] = piv[j]; + piv[j] = k; + pivsign = -pivsign; + } + + // Compute multipliers. + + if (j < m & LU[j][j] != 0.0) { + for (int i = j + 1; i < m; i++) { + LU[i][j] /= LU[j][j]; + } + } + } + } + + /* + * ------------------------ Temporary, experimental code. + * ------------------------ *\ + * + * \** LU Decomposition, computed by Gaussian elimination. <P> This + * constructor computes L and U with the "daxpy"-based elimination algorithm + * used in LINPACK and MATLAB. In Java, we suspect the dot-product, Crout + * algorithm will be faster. We have temporarily included this constructor + * until timing experiments confirm this suspicion. <P> + * + * @param A Rectangular matrix + * + * @param linpackflag Use Gaussian elimination. Actual value ignored. + * + * @return Structure to access L, U and piv.\ + * + * public LUDecomposition (Matrix A, int linpackflag) { // Initialize. LU = + * A.getArrayCopy(); m = A.getRowDimension(); n = A.getColumnDimension(); + * piv = new int[m]; for (int i = 0; i < m; i++) { piv[i] = i; } pivsign = + * 1; // Main loop. for (int k = 0; k < n; k++) { // Find pivot. int p = k; + * for (int i = k+1; i < m; i++) { if (Math.abs(LU[i][k]) > + * Math.abs(LU[p][k])) { p = i; } } // Exchange if necessary. if (p != k) { + * for (int j = 0; j < n; j++) { double t = LU[p][j]; LU[p][j] = LU[k][j]; + * LU[k][j] = t; } int t = piv[p]; piv[p] = piv[k]; piv[k] = t; pivsign = + * -pivsign; } // Compute multipliers and eliminate k-th column. if + * (LU[k][k] != 0.0) { for (int i = k+1; i < m; i++) { LU[i][k] /= LU[k][k]; + * for (int j = k+1; j < n; j++) { LU[i][j] -= LU[i][k]*LU[k][j]; } } } } } + * + * \* ------------------------ End of temporary code. + * ------------------------ + */ + + /* + * ------------------------ Public Methods ------------------------ + */ + + /** + * Is the matrix nonsingular? + * + * @return true if U, and hence A, is nonsingular. + */ + + public boolean isNonsingular() { + for (int j = 0; j < n; j++) { + if (LU[j][j] == 0) + return false; + } + return true; + } + + /** + * Return lower triangular factor + * + * @return L + */ + + public Matrix getL() { + Matrix X = new Matrix(m, n); + double[][] L = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (i > j) { + L[i][j] = LU[i][j]; + } + else if (i == j) { + L[i][j] = 1.0; + } + else { + L[i][j] = 0.0; + } + } + } + return X; + } + + /** + * Return upper triangular factor + * + * @return U + */ + + public Matrix getU() { + Matrix X = new Matrix(n, n); + double[][] U = X.getArray(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (i <= j) { + U[i][j] = LU[i][j]; + } + else { + U[i][j] = 0.0; + } + } + } + return X; + } + + /** + * Return pivot permutation vector + * + * @return piv + */ + + public int[] getPivot() { + int[] p = new int[m]; + for (int i = 0; i < m; i++) { + p[i] = piv[i]; + } + return p; + } + + /** + * Return pivot permutation vector as a one-dimensional double array + * + * @return (double) piv + */ + + public double[] getDoublePivot() { + double[] vals = new double[m]; + for (int i = 0; i < m; i++) { + vals[i] = (double) piv[i]; + } + return vals; + } + + /** + * Determinant + * + * @return det(A) + * @exception IllegalArgumentException + * Matrix must be square + */ + + public double det() { + if (m != n) { + throw new IllegalArgumentException("Matrix must be square."); + } + double d = (double) pivsign; + for (int j = 0; j < n; j++) { + d *= LU[j][j]; + } + return d; + } + + /** + * Solve A*X = B + * + * @param B + * A Matrix with as many rows as A and any number of columns. + * @return X so that L*U*X = B(piv,:) + * @exception IllegalArgumentException + * Matrix row dimensions must agree. + * @exception RuntimeException + * Matrix is singular. + */ + + public Matrix solve(Matrix B) { + if (B.getRowDimension() != m) { + throw new IllegalArgumentException("Matrix row dimensions must agree."); + } + if (!this.isNonsingular()) { + throw new RuntimeException("Matrix is singular."); + } + + // Copy right hand side with pivoting + int nx = B.getColumnDimension(); + Matrix Xmat = B.getMatrix(piv, 0, nx - 1); + double[][] X = Xmat.getArray(); + + // Solve L*Y = B(piv,:) + for (int k = 0; k < n; k++) { + for (int i = k + 1; i < n; i++) { + for (int j = 0; j < nx; j++) { + X[i][j] -= X[k][j] * LU[i][k]; + } + } + } + // Solve U*X = Y; + for (int k = n - 1; k >= 0; k--) { + for (int j = 0; j < nx; j++) { + X[k][j] /= LU[k][k]; + } + for (int i = 0; i < k; i++) { + for (int j = 0; j < nx; j++) { + X[i][j] -= X[k][j] * LU[i][k]; + } + } + } + return Xmat; + } +} diff --git a/src/bilib/src/jama/Maths.java b/src/bilib/src/jama/Maths.java new file mode 100644 index 0000000000000000000000000000000000000000..f58071da8485d23e199f0c873ecba58bb1a39e46 --- /dev/null +++ b/src/bilib/src/jama/Maths.java @@ -0,0 +1 @@ +package jama; public class Maths { /** sqrt(a^2 + b^2) without under/overflow. **/ public static double hypot(double a, double b) { double r; if (Math.abs(a) > Math.abs(b)) { r = b / a; r = Math.abs(a) * Math.sqrt(1 + r * r); } else if (b != 0) { r = a / b; r = Math.abs(b) * Math.sqrt(1 + r * r); } else { r = 0.0; } return r; } } \ No newline at end of file diff --git a/src/bilib/src/jama/Matrix.java b/src/bilib/src/jama/Matrix.java new file mode 100644 index 0000000000000000000000000000000000000000..c42f4ff518fc65cd27efb50ce7561a0d049a9af5 --- /dev/null +++ b/src/bilib/src/jama/Matrix.java @@ -0,0 +1,1276 @@ +package jama; + +import java.io.BufferedReader; +import java.io.PrintWriter; +import java.io.StreamTokenizer; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.util.Locale; + +/** + * Jama = Java Matrix class. + * <P> + * The Java Matrix Class provides the fundamental operations of numerical linear + * algebra. Various constructors create Matrices from two dimensional arrays of + * double precision floating point numbers. Various "gets" and "sets" provide + * access to submatrices and matrix elements. Several methods implement basic + * matrix arithmetic, including matrix addition and multiplication, matrix + * norms, and element-by-element array operations. Methods for reading and + * printing matrices are also included. All the operations in this version of + * the Matrix Class involve real matrices. Complex matrices may be handled in a + * future version. + * <P> + * Five fundamental matrix decompositions, which consist of pairs or triples of + * matrices, permutation vectors, and the like, produce results in five + * decomposition classes. These decompositions are accessed by the Matrix class + * to compute solutions of simultaneous linear equations, determinants, inverses + * and other matrix functions. The five decompositions are: + * <P> + * <UL> + * <LI>Cholesky Decomposition of symmetric, positive definite matrices. + * <LI>LU Decomposition of rectangular matrices. + * <LI>QR Decomposition of rectangular matrices. + * <LI>Singular Value Decomposition of rectangular matrices. + * <LI>Eigenvalue Decomposition of both symmetric and nonsymmetric square + * matrices. + * </UL> + * <DL> + * <DT><B>Example of use:</B></DT> + * <P> + * <DD>Solve a linear system A x = b and compute the residual norm, ||b - A x||. + * <P> + * + * <PRE> + * double[][] vals = { { 1., 2., 3 }, { 4., 5., 6. }, { 7., 8., 10. } }; + * Matrix A = new Matrix(vals); + * Matrix b = Matrix.random(3, 1); + * Matrix x = A.solve(b); + * Matrix r = A.times( + * x) + * .minus(b); + * double rnorm = r.normInf(); + * </PRE> + * + * </DD> + * </DL> + * + * @author The MathWorks, Inc. and the National Institute of Standards and + * Technology. + * @version 5 August 1998 + */ + +public class Matrix implements Cloneable, java.io.Serializable { + + /* + * ------------------------ Class variables ------------------------ + */ + + /** + * Array for internal storage of elements. + * + * @serial internal array storage. + */ + private double[][] A; + + /** + * Row and column dimensions. + * + * @serial row dimension. + * @serial column dimension. + */ + private int m, n; + + /* + * ------------------------ Constructors ------------------------ + */ + + /** + * Construct an m-by-n matrix of zeros. + * + * @param m + * Number of rows. + * @param n + * Number of colums. + */ + + public Matrix(int m, int n) { + this.m = m; + this.n = n; + A = new double[m][n]; + } + + /** + * Construct an m-by-n constant matrix. + * + * @param m + * Number of rows. + * @param n + * Number of colums. + * @param s + * Fill the matrix with this scalar value. + */ + + public Matrix(int m, int n, double s) { + this.m = m; + this.n = n; + A = new double[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = s; + } + } + } + + /** + * Construct a matrix from a 2-D array. + * + * @param A + * Two-dimensional array of doubles. + * @exception IllegalArgumentException + * All rows must have the same length + * @see #constructWithCopy + */ + + public Matrix(double[][] A) { + m = A.length; + n = A[0].length; + for (int i = 0; i < m; i++) { + if (A[i].length != n) { + throw new IllegalArgumentException("All rows must have the same length."); + } + } + this.A = A; + } + + /** + * Construct a matrix quickly without checking arguments. + * + * @param A + * Two-dimensional array of doubles. + * @param m + * Number of rows. + * @param n + * Number of colums. + */ + + public Matrix(double[][] A, int m, int n) { + this.A = A; + this.m = m; + this.n = n; + } + + /** + * Construct a matrix from a one-dimensional packed array + * + * @param vals + * One-dimensional array of doubles, packed by columns (ala + * Fortran). + * @param m + * Number of rows. + * @exception IllegalArgumentException + * Array length must be a multiple of m. + */ + + public Matrix(double vals[], int m) { + this.m = m; + n = (m != 0 ? vals.length / m : 0); + if (m * n != vals.length) { + throw new IllegalArgumentException("Array length must be a multiple of m."); + } + A = new double[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = vals[i + j * m]; + } + } + } + + /* + * ------------------------ Public Methods ------------------------ + */ + + /** + * Construct a matrix from a copy of a 2-D array. + * + * @param A + * Two-dimensional array of doubles. + * @exception IllegalArgumentException + * All rows must have the same length + */ + + public static Matrix constructWithCopy(double[][] A) { + int m = A.length; + int n = A[0].length; + Matrix X = new Matrix(m, n); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + if (A[i].length != n) { + throw new IllegalArgumentException("All rows must have the same length."); + } + for (int j = 0; j < n; j++) { + C[i][j] = A[i][j]; + } + } + return X; + } + + /** + * Make a deep copy of a matrix + */ + + public Matrix copy() { + Matrix X = new Matrix(m, n); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[i][j] = A[i][j]; + } + } + return X; + } + + /** + * Clone the Matrix object. + */ + + public Object clone() { + return this.copy(); + } + + /** + * Access the internal two-dimensional array. + * + * @return Pointer to the two-dimensional array of matrix elements. + */ + + public double[][] getArray() { + return A; + } + + /** + * Copy the internal two-dimensional array. + * + * @return Two-dimensional array copy of matrix elements. + */ + + public double[][] getArrayCopy() { + double[][] C = new double[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[i][j] = A[i][j]; + } + } + return C; + } + + /** + * Make a one-dimensional column packed copy of the internal array. + * + * @return Matrix elements packed in a one-dimensional array by columns. + */ + + public double[] getColumnPackedCopy() { + double[] vals = new double[m * n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + vals[i + j * m] = A[i][j]; + } + } + return vals; + } + + /** + * Make a one-dimensional row packed copy of the internal array. + * + * @return Matrix elements packed in a one-dimensional array by rows. + */ + + public double[] getRowPackedCopy() { + double[] vals = new double[m * n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + vals[i * n + j] = A[i][j]; + } + } + return vals; + } + + /** + * Get row dimension. + * + * @return m, the number of rows. + */ + + public int getRowDimension() { + return m; + } + + /** + * Get column dimension. + * + * @return n, the number of columns. + */ + + public int getColumnDimension() { + return n; + } + + /** + * Get a single element. + * + * @param i + * Row index. + * @param j + * Column index. + * @return A(i,j) + * @exception ArrayIndexOutOfBoundsException + */ + + public double get(int i, int j) { + return A[i][j]; + } + + /** + * Get a submatrix. + * + * @param i0 + * Initial row index + * @param i1 + * Final row index + * @param j0 + * Initial column index + * @param j1 + * Final column index + * @return A(i0:i1,j0:j1) + * @exception ArrayIndexOutOfBoundsException + * Submatrix indices + */ + + public Matrix getMatrix(int i0, int i1, int j0, int j1) { + Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1); + double[][] B = X.getArray(); + try { + for (int i = i0; i <= i1; i++) { + for (int j = j0; j <= j1; j++) { + B[i - i0][j - j0] = A[i][j]; + } + } + } + catch (ArrayIndexOutOfBoundsException e) { + throw new ArrayIndexOutOfBoundsException("Submatrix indices"); + } + return X; + } + + /** + * Get a submatrix. + * + * @param r + * Array of row indices. + * @param c + * Array of column indices. + * @return A(r(:),c(:)) + * @exception ArrayIndexOutOfBoundsException + * Submatrix indices + */ + + public Matrix getMatrix(int[] r, int[] c) { + Matrix X = new Matrix(r.length, c.length); + double[][] B = X.getArray(); + try { + for (int i = 0; i < r.length; i++) { + for (int j = 0; j < c.length; j++) { + B[i][j] = A[r[i]][c[j]]; + } + } + } + catch (ArrayIndexOutOfBoundsException e) { + throw new ArrayIndexOutOfBoundsException("Submatrix indices"); + } + return X; + } + + /** + * Get a submatrix. + * + * @param i0 + * Initial row index + * @param i1 + * Final row index + * @param c + * Array of column indices. + * @return A(i0:i1,c(:)) + * @exception ArrayIndexOutOfBoundsException + * Submatrix indices + */ + + public Matrix getMatrix(int i0, int i1, int[] c) { + Matrix X = new Matrix(i1 - i0 + 1, c.length); + double[][] B = X.getArray(); + try { + for (int i = i0; i <= i1; i++) { + for (int j = 0; j < c.length; j++) { + B[i - i0][j] = A[i][c[j]]; + } + } + } + catch (ArrayIndexOutOfBoundsException e) { + throw new ArrayIndexOutOfBoundsException("Submatrix indices"); + } + return X; + } + + /** + * Get a submatrix. + * + * @param r + * Array of row indices. + * @param j0 + * Initial column index + * @param j1 + * Final column index + * @return A(r(:),j0:j1) + * @exception ArrayIndexOutOfBoundsException + * Submatrix indices + */ + + public Matrix getMatrix(int[] r, int j0, int j1) { + Matrix X = new Matrix(r.length, j1 - j0 + 1); + double[][] B = X.getArray(); + try { + for (int i = 0; i < r.length; i++) { + for (int j = j0; j <= j1; j++) { + B[i][j - j0] = A[r[i]][j]; + } + } + } + catch (ArrayIndexOutOfBoundsException e) { + throw new ArrayIndexOutOfBoundsException("Submatrix indices"); + } + return X; + } + + /** + * Set a single element. + * + * @param i + * Row index. + * @param j + * Column index. + * @param s + * A(i,j). + * @exception ArrayIndexOutOfBoundsException + */ + + public void set(int i, int j, double s) { + A[i][j] = s; + } + + /** + * Set a submatrix. + * + * @param i0 + * Initial row index + * @param i1 + * Final row index + * @param j0 + * Initial column index + * @param j1 + * Final column index + * @param X + * A(i0:i1,j0:j1) + * @exception ArrayIndexOutOfBoundsException + * Submatrix indices + */ + + public void setMatrix(int i0, int i1, int j0, int j1, Matrix X) { + try { + for (int i = i0; i <= i1; i++) { + for (int j = j0; j <= j1; j++) { + A[i][j] = X.get(i - i0, j - j0); + } + } + } + catch (ArrayIndexOutOfBoundsException e) { + throw new ArrayIndexOutOfBoundsException("Submatrix indices"); + } + } + + /** + * Set a submatrix. + * + * @param r + * Array of row indices. + * @param c + * Array of column indices. + * @param X + * A(r(:),c(:)) + * @exception ArrayIndexOutOfBoundsException + * Submatrix indices + */ + + public void setMatrix(int[] r, int[] c, Matrix X) { + try { + for (int i = 0; i < r.length; i++) { + for (int j = 0; j < c.length; j++) { + A[r[i]][c[j]] = X.get(i, j); + } + } + } + catch (ArrayIndexOutOfBoundsException e) { + throw new ArrayIndexOutOfBoundsException("Submatrix indices"); + } + } + + /** + * Set a submatrix. + * + * @param r + * Array of row indices. + * @param j0 + * Initial column index + * @param j1 + * Final column index + * @param X + * A(r(:),j0:j1) + * @exception ArrayIndexOutOfBoundsException + * Submatrix indices + */ + + public void setMatrix(int[] r, int j0, int j1, Matrix X) { + try { + for (int i = 0; i < r.length; i++) { + for (int j = j0; j <= j1; j++) { + A[r[i]][j] = X.get(i, j - j0); + } + } + } + catch (ArrayIndexOutOfBoundsException e) { + throw new ArrayIndexOutOfBoundsException("Submatrix indices"); + } + } + + /** + * Set a submatrix. + * + * @param i0 + * Initial row index + * @param i1 + * Final row index + * @param c + * Array of column indices. + * @param X + * A(i0:i1,c(:)) + * @exception ArrayIndexOutOfBoundsException + * Submatrix indices + */ + + public void setMatrix(int i0, int i1, int[] c, Matrix X) { + try { + for (int i = i0; i <= i1; i++) { + for (int j = 0; j < c.length; j++) { + A[i][c[j]] = X.get(i - i0, j); + } + } + } + catch (ArrayIndexOutOfBoundsException e) { + throw new ArrayIndexOutOfBoundsException("Submatrix indices"); + } + } + + /** + * Matrix transpose. + * + * @return A' + */ + + public Matrix transpose() { + Matrix X = new Matrix(n, m); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[j][i] = A[i][j]; + } + } + return X; + } + + /** + * One norm + * + * @return maximum column sum. + */ + + public double norm1() { + double f = 0; + for (int j = 0; j < n; j++) { + double s = 0; + for (int i = 0; i < m; i++) { + s += Math.abs(A[i][j]); + } + f = Math.max(f, s); + } + return f; + } + + /** + * Two norm + * + * @return maximum singular value. + */ + + public double norm2() { + return (new SingularValueDecomposition(this).norm2()); + } + + /** + * Infinity norm + * + * @return maximum row sum. + */ + + public double normInf() { + double f = 0; + for (int i = 0; i < m; i++) { + double s = 0; + for (int j = 0; j < n; j++) { + s += Math.abs(A[i][j]); + } + f = Math.max(f, s); + } + return f; + } + + /** + * Frobenius norm + * + * @return sqrt of sum of squares of all elements. + */ + + public double normF() { + double f = 0; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + f = Maths.hypot(f, A[i][j]); + } + } + return f; + } + + /** + * Unary minus + * + * @return -A + */ + + public Matrix uminus() { + Matrix X = new Matrix(m, n); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[i][j] = -A[i][j]; + } + } + return X; + } + + /** + * C = A + B + * + * @param B + * another matrix + * @return A + B + */ + + public Matrix plus(Matrix B) { + checkMatrixDimensions(B); + Matrix X = new Matrix(m, n); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[i][j] = A[i][j] + B.A[i][j]; + } + } + return X; + } + + /** + * A = A + B + * + * @param B + * another matrix + * @return A + B + */ + + public Matrix plusEquals(Matrix B) { + checkMatrixDimensions(B); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = A[i][j] + B.A[i][j]; + } + } + return this; + } + + /** + * C = A - B + * + * @param B + * another matrix + * @return A - B + */ + + public Matrix minus(Matrix B) { + checkMatrixDimensions(B); + Matrix X = new Matrix(m, n); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[i][j] = A[i][j] - B.A[i][j]; + } + } + return X; + } + + /** + * A = A - B + * + * @param B + * another matrix + * @return A - B + */ + + public Matrix minusEquals(Matrix B) { + checkMatrixDimensions(B); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = A[i][j] - B.A[i][j]; + } + } + return this; + } + + /** + * Element-by-element multiplication, C = A.*B + * + * @param B + * another matrix + * @return A.*B + */ + + public Matrix arrayTimes(Matrix B) { + checkMatrixDimensions(B); + Matrix X = new Matrix(m, n); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[i][j] = A[i][j] * B.A[i][j]; + } + } + return X; + } + + /** + * Element-by-element multiplication in place, A = A.*B + * + * @param B + * another matrix + * @return A.*B + */ + + public Matrix arrayTimesEquals(Matrix B) { + checkMatrixDimensions(B); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = A[i][j] * B.A[i][j]; + } + } + return this; + } + + /** + * Element-by-element right division, C = A./B + * + * @param B + * another matrix + * @return A./B + */ + + public Matrix arrayRightDivide(Matrix B) { + checkMatrixDimensions(B); + Matrix X = new Matrix(m, n); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[i][j] = A[i][j] / B.A[i][j]; + } + } + return X; + } + + /** + * Element-by-element right division in place, A = A./B + * + * @param B + * another matrix + * @return A./B + */ + + public Matrix arrayRightDivideEquals(Matrix B) { + checkMatrixDimensions(B); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = A[i][j] / B.A[i][j]; + } + } + return this; + } + + /** + * Element-by-element left division, C = A.\B + * + * @param B + * another matrix + * @return A.\B + */ + + public Matrix arrayLeftDivide(Matrix B) { + checkMatrixDimensions(B); + Matrix X = new Matrix(m, n); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[i][j] = B.A[i][j] / A[i][j]; + } + } + return X; + } + + /** + * Element-by-element left division in place, A = A.\B + * + * @param B + * another matrix + * @return A.\B + */ + + public Matrix arrayLeftDivideEquals(Matrix B) { + checkMatrixDimensions(B); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = B.A[i][j] / A[i][j]; + } + } + return this; + } + + /** + * Multiply a matrix by a scalar, C = s*A + * + * @param s + * scalar + * @return s*A + */ + + public Matrix times(double s) { + Matrix X = new Matrix(m, n); + double[][] C = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + C[i][j] = s * A[i][j]; + } + } + return X; + } + + /** + * Multiply a matrix by a scalar in place, A = s*A + * + * @param s + * scalar + * @return replace A by s*A + */ + + public Matrix timesEquals(double s) { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = s * A[i][j]; + } + } + return this; + } + + /** + * Linear algebraic matrix multiplication, A * B + * + * @param B + * another matrix + * @return Matrix product, A * B + * @exception IllegalArgumentException + * Matrix inner dimensions must agree. + */ + + public Matrix times(Matrix B) { + if (B.m != n) { + throw new IllegalArgumentException("Matrix inner dimensions must agree."); + } + Matrix X = new Matrix(m, B.n); + double[][] C = X.getArray(); + double[] Bcolj = new double[n]; + for (int j = 0; j < B.n; j++) { + for (int k = 0; k < n; k++) { + Bcolj[k] = B.A[k][j]; + } + for (int i = 0; i < m; i++) { + double[] Arowi = A[i]; + double s = 0; + for (int k = 0; k < n; k++) { + s += Arowi[k] * Bcolj[k]; + } + C[i][j] = s; + } + } + return X; + } + + /** + * LU Decomposition + * + * @return LUDecomposition + * @see LUDecomposition + */ + + public LUDecomposition lu() { + return new LUDecomposition(this); + } + + /** + * QR Decomposition + * + * @return QRDecomposition + * @see QRDecomposition + */ + + public QRDecomposition qr() { + return new QRDecomposition(this); + } + + /** + * Cholesky Decomposition + * + * @return CholeskyDecomposition + * @see CholeskyDecomposition + */ + + public CholeskyDecomposition chol() { + return new CholeskyDecomposition(this); + } + + /** + * Singular Value Decomposition + * + * @return SingularValueDecomposition + * @see SingularValueDecomposition + */ + + public SingularValueDecomposition svd() { + return new SingularValueDecomposition(this); + } + + /** + * Eigenvalue Decomposition + * + * @return EigenvalueDecomposition + * @see EigenvalueDecomposition + */ + + public EigenvalueDecomposition eig() { + return new EigenvalueDecomposition(this); + } + + /** + * Solve A*X = B + * + * @param B + * right hand side + * @return solution if A is square, least squares solution otherwise + */ + + public Matrix solve(Matrix B) { + return (m == n ? (new LUDecomposition(this)).solve(B) : (new QRDecomposition(this)).solve(B)); + } + + /** + * Solve X*A = B, which is also A'*X' = B' + * + * @param B + * right hand side + * @return solution if A is square, least squares solution otherwise. + */ + + public Matrix solveTranspose(Matrix B) { + return transpose().solve(B.transpose()); + } + + /** + * Matrix inverse or pseudoinverse + * + * @return inverse(A) if A is square, pseudoinverse otherwise. + */ + + public Matrix inverse() { + return solve(identity(m, m)); + } + + /** + * Matrix determinant + * + * @return determinant + */ + + public double det() { + return new LUDecomposition(this).det(); + } + + /** + * Matrix rank + * + * @return effective numerical rank, obtained from SVD. + */ + + public int rank() { + return new SingularValueDecomposition(this).rank(); + } + + /** + * Matrix condition (2 norm) + * + * @return ratio of largest to smallest singular value. + */ + + public double cond() { + return new SingularValueDecomposition(this).cond(); + } + + /** + * Matrix trace. + * + * @return sum of the diagonal elements. + */ + + public double trace() { + double t = 0; + for (int i = 0; i < Math.min(m, n); i++) { + t += A[i][i]; + } + return t; + } + + /** + * Generate matrix with random elements + * + * @param m + * Number of rows. + * @param n + * Number of colums. + * @return An m-by-n matrix with uniformly distributed random elements. + */ + + public static Matrix random(int m, int n) { + Matrix A = new Matrix(m, n); + double[][] X = A.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + X[i][j] = Math.random(); + } + } + return A; + } + + /** + * Generate identity matrix + * + * @param m + * Number of rows. + * @param n + * Number of colums. + * @return An m-by-n matrix with ones on the diagonal and zeros elsewhere. + */ + + public static Matrix identity(int m, int n) { + Matrix A = new Matrix(m, n); + double[][] X = A.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + X[i][j] = (i == j ? 1.0 : 0.0); + } + } + return A; + } + + /** + * Print the matrix to stdout. Line the elements up in columns with a + * Fortran-like 'Fw.d' style format. + * + * @param w + * Column width. + * @param d + * Number of digits after the decimal. + */ + + public void print(int w, int d) { + print(new PrintWriter(System.out, true), w, d); + } + + /** + * Print the matrix to the output stream. Line the elements up in columns + * with a Fortran-like 'Fw.d' style format. + * + * @param output + * Output stream. + * @param w + * Column width. + * @param d + * Number of digits after the decimal. + */ + + public void print(PrintWriter output, int w, int d) { + DecimalFormat format = new DecimalFormat(); + format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US)); + format.setMinimumIntegerDigits(1); + format.setMaximumFractionDigits(d); + format.setMinimumFractionDigits(d); + format.setGroupingUsed(false); + print(output, format, w + 2); + } + + /** + * Print the matrix to stdout. Line the elements up in columns. Use the + * format object, and right justify within columns of width characters. Note + * that is the matrix is to be read back in, you probably will want to use a + * NumberFormat that is set to US Locale. + * + * @param format + * A Formatting object for individual elements. + * @param width + * Field width for each column. + * @see java.text.DecimalFormat#setDecimalFormatSymbols + */ + + public void print(NumberFormat format, int width) { + print(new PrintWriter(System.out, true), format, width); + } + + // DecimalFormat is a little disappointing coming from Fortran or C's + // printf. + // Since it doesn't pad on the left, the elements will come out different + // widths. Consequently, we'll pass the desired column width in as an + // argument and do the extra padding ourselves. + + /** + * Print the matrix to the output stream. Line the elements up in columns. + * Use the format object, and right justify within columns of width + * characters. Note that is the matrix is to be read back in, you probably + * will want to use a NumberFormat that is set to US Locale. + * + * @param output + * the output stream. + * @param format + * A formatting object to format the matrix elements + * @param width + * Column width. + * @see java.text.DecimalFormat#setDecimalFormatSymbols + */ + + public void print(PrintWriter output, NumberFormat format, int width) { + output.println(); // start on new line. + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + String s = format.format(A[i][j]); // format the number + int padding = Math.max(1, width - s.length()); // At _least_ 1 + // space + for (int k = 0; k < padding; k++) + output.print(' '); + output.print(s); + } + output.println(); + } + output.println(); // end with blank line. + } + + /** + * Read a matrix from a stream. The format is the same the print method, so + * printed matrices can be read back in (provided they were printed using US + * Locale). Elements are separated by whitespace, all the elements for each + * row appear on a single line, the last row is followed by a blank line. + * + * @param input + * the input stream. + */ + + public static Matrix read(BufferedReader input) throws java.io.IOException { + StreamTokenizer tokenizer = new StreamTokenizer(input); + + // Although StreamTokenizer will parse numbers, it doesn't recognize + // scientific notation (E or D); however, Double.valueOf does. + // The strategy here is to disable StreamTokenizer's number parsing. + // We'll only get whitespace delimited words, EOL's and EOF's. + // These words should all be numbers, for Double.valueOf to parse. + + tokenizer.resetSyntax(); + tokenizer.wordChars(0, 255); + tokenizer.whitespaceChars(0, ' '); + tokenizer.eolIsSignificant(true); + java.util.Vector v = new java.util.Vector(); + + // Ignore initial empty lines + while (tokenizer.nextToken() == StreamTokenizer.TT_EOL) + ; + if (tokenizer.ttype == StreamTokenizer.TT_EOF) + throw new java.io.IOException("Unexpected EOF on matrix read."); + do { + v.addElement(Double.valueOf(tokenizer.sval)); // Read & store 1st + // row. + } + while (tokenizer.nextToken() == StreamTokenizer.TT_WORD); + + int n = v.size(); // Now we've got the number of columns! + double row[] = new double[n]; + for (int j = 0; j < n; j++) + // extract the elements of the 1st row. + row[j] = ((Double) v.elementAt(j)).doubleValue(); + v.removeAllElements(); + v.addElement(row); // Start storing rows instead of columns. + while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) { + // While non-empty lines + v.addElement(row = new double[n]); + int j = 0; + do { + if (j >= n) + throw new java.io.IOException("Row " + v.size() + " is too long."); + row[j++] = Double.valueOf(tokenizer.sval).doubleValue(); + } + while (tokenizer.nextToken() == StreamTokenizer.TT_WORD); + if (j < n) + throw new java.io.IOException("Row " + v.size() + " is too short."); + } + int m = v.size(); // Now we've got the number of rows. + double[][] A = new double[m][]; + v.copyInto(A); // copy the rows out of the vector + return new Matrix(A); + } + + /* + * ------------------------ Private Methods ------------------------ + */ + + /** Check if size(A) == size(B) **/ + + private void checkMatrixDimensions(Matrix B) { + if (B.m != m || B.n != n) { + throw new IllegalArgumentException("Matrix dimensions must agree."); + } + } + +} diff --git a/src/bilib/src/jama/QRDecomposition.java b/src/bilib/src/jama/QRDecomposition.java new file mode 100644 index 0000000000000000000000000000000000000000..bfa3ef5b5db33a380861e81d56c1e32f6ffd9b95 --- /dev/null +++ b/src/bilib/src/jama/QRDecomposition.java @@ -0,0 +1,240 @@ +package jama; + +/** + * QR Decomposition. + * <P> + * For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n + * orthogonal matrix Q and an n-by-n upper triangular matrix R so that A = Q*R. + * <P> + * The QR decompostion always exists, even if the matrix does not have full + * rank, so the constructor will never fail. The primary use of the QR + * decomposition is in the least squares solution of nonsquare systems of + * simultaneous linear equations. This will fail if isFullRank() returns false. + */ + +public class QRDecomposition implements java.io.Serializable { + + /* + * ------------------------ Class variables ------------------------ + */ + + /** + * Array for internal storage of decomposition. + * + * @serial internal array storage. + */ + private double[][] QR; + + /** + * Row and column dimensions. + * + * @serial column dimension. + * @serial row dimension. + */ + private int m, n; + + /** + * Array for internal storage of diagonal of R. + * + * @serial diagonal of R. + */ + private double[] Rdiag; + + /* + * ------------------------ Constructor ------------------------ + */ + + /** + * QR Decomposition, computed by Householder reflections. + * + * @param A + * Rectangular matrix + */ + + public QRDecomposition(Matrix A) { + // Initialize. + QR = A.getArrayCopy(); + m = A.getRowDimension(); + n = A.getColumnDimension(); + Rdiag = new double[n]; + + // Main loop. + for (int k = 0; k < n; k++) { + // Compute 2-norm of k-th column without under/overflow. + double nrm = 0; + for (int i = k; i < m; i++) { + nrm = Maths.hypot(nrm, QR[i][k]); + } + + if (nrm != 0.0) { + // Form k-th Householder vector. + if (QR[k][k] < 0) { + nrm = -nrm; + } + for (int i = k; i < m; i++) { + QR[i][k] /= nrm; + } + QR[k][k] += 1.0; + + // Apply transformation to remaining columns. + for (int j = k + 1; j < n; j++) { + double s = 0.0; + for (int i = k; i < m; i++) { + s += QR[i][k] * QR[i][j]; + } + s = -s / QR[k][k]; + for (int i = k; i < m; i++) { + QR[i][j] += s * QR[i][k]; + } + } + } + Rdiag[k] = -nrm; + } + } + + /* + * ------------------------ Public Methods ------------------------ + */ + + /** + * Is the matrix full rank? + * + * @return true if R, and hence A, has full rank. + */ + + public boolean isFullRank() { + for (int j = 0; j < n; j++) { + if (Rdiag[j] == 0) + return false; + } + return true; + } + + /** + * Return the Householder vectors + * + * @return Lower trapezoidal matrix whose columns define the reflections + */ + + public Matrix getH() { + Matrix X = new Matrix(m, n); + double[][] H = X.getArray(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (i >= j) { + H[i][j] = QR[i][j]; + } + else { + H[i][j] = 0.0; + } + } + } + return X; + } + + /** + * Return the upper triangular factor + * + * @return R + */ + + public Matrix getR() { + Matrix X = new Matrix(n, n); + double[][] R = X.getArray(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (i < j) { + R[i][j] = QR[i][j]; + } + else if (i == j) { + R[i][j] = Rdiag[i]; + } + else { + R[i][j] = 0.0; + } + } + } + return X; + } + + /** + * Generate and return the (economy-sized) orthogonal factor + * + * @return Q + */ + + public Matrix getQ() { + Matrix X = new Matrix(m, n); + double[][] Q = X.getArray(); + for (int k = n - 1; k >= 0; k--) { + for (int i = 0; i < m; i++) { + Q[i][k] = 0.0; + } + Q[k][k] = 1.0; + for (int j = k; j < n; j++) { + if (QR[k][k] != 0) { + double s = 0.0; + for (int i = k; i < m; i++) { + s += QR[i][k] * Q[i][j]; + } + s = -s / QR[k][k]; + for (int i = k; i < m; i++) { + Q[i][j] += s * QR[i][k]; + } + } + } + } + return X; + } + + /** + * Least squares solution of A*X = B + * + * @param B + * A Matrix with as many rows as A and any number of columns. + * @return X that minimizes the two norm of Q*R*X-B. + * @exception IllegalArgumentException + * Matrix row dimensions must agree. + * @exception RuntimeException + * Matrix is rank deficient. + */ + + public Matrix solve(Matrix B) { + if (B.getRowDimension() != m) { + throw new IllegalArgumentException("Matrix row dimensions must agree."); + } + if (!this.isFullRank()) { + throw new RuntimeException("Matrix is rank deficient."); + } + + // Copy right hand side + int nx = B.getColumnDimension(); + double[][] X = B.getArrayCopy(); + + // Compute Y = transpose(Q)*B + for (int k = 0; k < n; k++) { + for (int j = 0; j < nx; j++) { + double s = 0.0; + for (int i = k; i < m; i++) { + s += QR[i][k] * X[i][j]; + } + s = -s / QR[k][k]; + for (int i = k; i < m; i++) { + X[i][j] += s * QR[i][k]; + } + } + } + // Solve R*X = Y; + for (int k = n - 1; k >= 0; k--) { + for (int j = 0; j < nx; j++) { + X[k][j] /= Rdiag[k]; + } + for (int i = 0; i < k; i++) { + for (int j = 0; j < nx; j++) { + X[i][j] -= X[k][j] * QR[i][k]; + } + } + } + return (new Matrix(X, n, nx).getMatrix(0, n - 1, 0, nx - 1)); + } +} diff --git a/src/bilib/src/jama/SingularValueDecomposition.java b/src/bilib/src/jama/SingularValueDecomposition.java new file mode 100644 index 0000000000000000000000000000000000000000..267c123e7d702da773be4e9322b4bd1ce40dc52e --- /dev/null +++ b/src/bilib/src/jama/SingularValueDecomposition.java @@ -0,0 +1,573 @@ +package jama; + +/** + * Singular Value Decomposition. + * <P> + * For an m-by-n matrix A with m >= n, the singular value decomposition is an + * m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and an n-by-n + * orthogonal matrix V so that A = U*S*V'. + * <P> + * The singular values, sigma[k] = S[k][k], are ordered so that sigma[0] >= + * sigma[1] >= ... >= sigma[n-1]. + * <P> + * The singular value decompostion always exists, so the constructor will never + * fail. The matrix condition number and the effective numerical rank can be + * computed from this decomposition. + */ + +public class SingularValueDecomposition implements java.io.Serializable { + + /* + * ------------------------ Class variables ------------------------ + */ + + /** + * Arrays for internal storage of U and V. + * + * @serial internal storage of U. + * @serial internal storage of V. + */ + private double[][] U, V; + + /** + * Array for internal storage of singular values. + * + * @serial internal storage of singular values. + */ + private double[] s; + + /** + * Row and column dimensions. + * + * @serial row dimension. + * @serial column dimension. + */ + private int m, n; + + /* + * ------------------------ Constructor ------------------------ + */ + + /** + * Construct the singular value decomposition + * + * @param Arg + * Rectangular matrix + */ + + public SingularValueDecomposition(Matrix Arg) { + + // Derived from LINPACK code. + // Initialize. + double[][] A = Arg.getArrayCopy(); + m = Arg.getRowDimension(); + n = Arg.getColumnDimension(); + + /* + * Apparently the failing cases are only a proper subset of (m<n), so + * let's not throw error. Correct fix to come later? if (m<n) { throw + * new IllegalArgumentException("Jama SVD only works for m >= n"); } + */ + int nu = Math.min(m, n); + s = new double[Math.min(m + 1, n)]; + U = new double[m][nu]; + V = new double[n][n]; + double[] e = new double[n]; + double[] work = new double[m]; + boolean wantu = true; + boolean wantv = true; + + // Reduce A to bidiagonal form, storing the diagonal elements + // in s and the super-diagonal elements in e. + + int nct = Math.min(m - 1, n); + int nrt = Math.max(0, Math.min(n - 2, m)); + for (int k = 0; k < Math.max(nct, nrt); k++) { + if (k < nct) { + + // Compute the transformation for the k-th column and + // place the k-th diagonal in s[k]. + // Compute 2-norm of k-th column without under/overflow. + s[k] = 0; + for (int i = k; i < m; i++) { + s[k] = Maths.hypot(s[k], A[i][k]); + } + if (s[k] != 0.0) { + if (A[k][k] < 0.0) { + s[k] = -s[k]; + } + for (int i = k; i < m; i++) { + A[i][k] /= s[k]; + } + A[k][k] += 1.0; + } + s[k] = -s[k]; + } + for (int j = k + 1; j < n; j++) { + if ((k < nct) & (s[k] != 0.0)) { + + // Apply the transformation. + + double t = 0; + for (int i = k; i < m; i++) { + t += A[i][k] * A[i][j]; + } + t = -t / A[k][k]; + for (int i = k; i < m; i++) { + A[i][j] += t * A[i][k]; + } + } + + // Place the k-th row of A into e for the + // subsequent calculation of the row transformation. + + e[j] = A[k][j]; + } + if (wantu & (k < nct)) { + + // Place the transformation in U for subsequent back + // multiplication. + + for (int i = k; i < m; i++) { + U[i][k] = A[i][k]; + } + } + if (k < nrt) { + + // Compute the k-th row transformation and place the + // k-th super-diagonal in e[k]. + // Compute 2-norm without under/overflow. + e[k] = 0; + for (int i = k + 1; i < n; i++) { + e[k] = Maths.hypot(e[k], e[i]); + } + if (e[k] != 0.0) { + if (e[k + 1] < 0.0) { + e[k] = -e[k]; + } + for (int i = k + 1; i < n; i++) { + e[i] /= e[k]; + } + e[k + 1] += 1.0; + } + e[k] = -e[k]; + if ((k + 1 < m) & (e[k] != 0.0)) { + + // Apply the transformation. + + for (int i = k + 1; i < m; i++) { + work[i] = 0.0; + } + for (int j = k + 1; j < n; j++) { + for (int i = k + 1; i < m; i++) { + work[i] += e[j] * A[i][j]; + } + } + for (int j = k + 1; j < n; j++) { + double t = -e[j] / e[k + 1]; + for (int i = k + 1; i < m; i++) { + A[i][j] += t * work[i]; + } + } + } + if (wantv) { + + // Place the transformation in V for subsequent + // back multiplication. + + for (int i = k + 1; i < n; i++) { + V[i][k] = e[i]; + } + } + } + } + + // Set up the final bidiagonal matrix or order p. + + int p = Math.min(n, m + 1); + if (nct < n) { + s[nct] = A[nct][nct]; + } + if (m < p) { + s[p - 1] = 0.0; + } + if (nrt + 1 < p) { + e[nrt] = A[nrt][p - 1]; + } + e[p - 1] = 0.0; + + // If required, generate U. + + if (wantu) { + for (int j = nct; j < nu; j++) { + for (int i = 0; i < m; i++) { + U[i][j] = 0.0; + } + U[j][j] = 1.0; + } + for (int k = nct - 1; k >= 0; k--) { + if (s[k] != 0.0) { + for (int j = k + 1; j < nu; j++) { + double t = 0; + for (int i = k; i < m; i++) { + t += U[i][k] * U[i][j]; + } + t = -t / U[k][k]; + for (int i = k; i < m; i++) { + U[i][j] += t * U[i][k]; + } + } + for (int i = k; i < m; i++) { + U[i][k] = -U[i][k]; + } + U[k][k] = 1.0 + U[k][k]; + for (int i = 0; i < k - 1; i++) { + U[i][k] = 0.0; + } + } + else { + for (int i = 0; i < m; i++) { + U[i][k] = 0.0; + } + U[k][k] = 1.0; + } + } + } + + // If required, generate V. + + if (wantv) { + for (int k = n - 1; k >= 0; k--) { + if ((k < nrt) & (e[k] != 0.0)) { + for (int j = k + 1; j < nu; j++) { + double t = 0; + for (int i = k + 1; i < n; i++) { + t += V[i][k] * V[i][j]; + } + t = -t / V[k + 1][k]; + for (int i = k + 1; i < n; i++) { + V[i][j] += t * V[i][k]; + } + } + } + for (int i = 0; i < n; i++) { + V[i][k] = 0.0; + } + V[k][k] = 1.0; + } + } + + // Main iteration loop for the singular values. + + int pp = p - 1; + int iter = 0; + double eps = Math.pow(2.0, -52.0); + double tiny = Math.pow(2.0, -966.0); + while (p > 0) { + int k, kase; + + // Here is where a test for too many iterations would go. + + // This section of the program inspects for + // negligible elements in the s and e arrays. On + // completion the variables kase and k are set as follows. + + // kase = 1 if s(p) and e[k-1] are negligible and k<p + // kase = 2 if s(k) is negligible and k<p + // kase = 3 if e[k-1] is negligible, k<p, and + // s(k), ..., s(p) are not negligible (qr step). + // kase = 4 if e(p-1) is negligible (convergence). + + for (k = p - 2; k >= -1; k--) { + if (k == -1) { + break; + } + if (Math.abs(e[k]) <= tiny + eps * (Math.abs(s[k]) + Math.abs(s[k + 1]))) { + e[k] = 0.0; + break; + } + } + if (k == p - 2) { + kase = 4; + } + else { + int ks; + for (ks = p - 1; ks >= k; ks--) { + if (ks == k) { + break; + } + double t = (ks != p ? Math.abs(e[ks]) : 0.) + (ks != k + 1 ? Math.abs(e[ks - 1]) : 0.); + if (Math.abs(s[ks]) <= tiny + eps * t) { + s[ks] = 0.0; + break; + } + } + if (ks == k) { + kase = 3; + } + else if (ks == p - 1) { + kase = 1; + } + else { + kase = 2; + k = ks; + } + } + k++; + + // Perform the task indicated by kase. + + switch (kase) { + + // Deflate negligible s(p). + + case 1: { + double f = e[p - 2]; + e[p - 2] = 0.0; + for (int j = p - 2; j >= k; j--) { + double t = Maths.hypot(s[j], f); + double cs = s[j] / t; + double sn = f / t; + s[j] = t; + if (j != k) { + f = -sn * e[j - 1]; + e[j - 1] = cs * e[j - 1]; + } + if (wantv) { + for (int i = 0; i < n; i++) { + t = cs * V[i][j] + sn * V[i][p - 1]; + V[i][p - 1] = -sn * V[i][j] + cs * V[i][p - 1]; + V[i][j] = t; + } + } + } + } + break; + + // Split at negligible s(k). + + case 2: { + double f = e[k - 1]; + e[k - 1] = 0.0; + for (int j = k; j < p; j++) { + double t = Maths.hypot(s[j], f); + double cs = s[j] / t; + double sn = f / t; + s[j] = t; + f = -sn * e[j]; + e[j] = cs * e[j]; + if (wantu) { + for (int i = 0; i < m; i++) { + t = cs * U[i][j] + sn * U[i][k - 1]; + U[i][k - 1] = -sn * U[i][j] + cs * U[i][k - 1]; + U[i][j] = t; + } + } + } + } + break; + + // Perform one qr step. + + case 3: { + + // Calculate the shift. + + double scale = Math.max(Math.max(Math.max(Math.max(Math.abs(s[p - 1]), Math.abs(s[p - 2])), Math.abs(e[p - 2])), Math.abs(s[k])), Math.abs(e[k])); + double sp = s[p - 1] / scale; + double spm1 = s[p - 2] / scale; + double epm1 = e[p - 2] / scale; + double sk = s[k] / scale; + double ek = e[k] / scale; + double b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2.0; + double c = (sp * epm1) * (sp * epm1); + double shift = 0.0; + if ((b != 0.0) | (c != 0.0)) { + shift = Math.sqrt(b * b + c); + if (b < 0.0) { + shift = -shift; + } + shift = c / (b + shift); + } + double f = (sk + sp) * (sk - sp) + shift; + double g = sk * ek; + + // Chase zeros. + + for (int j = k; j < p - 1; j++) { + double t = Maths.hypot(f, g); + double cs = f / t; + double sn = g / t; + if (j != k) { + e[j - 1] = t; + } + f = cs * s[j] + sn * e[j]; + e[j] = cs * e[j] - sn * s[j]; + g = sn * s[j + 1]; + s[j + 1] = cs * s[j + 1]; + if (wantv) { + for (int i = 0; i < n; i++) { + t = cs * V[i][j] + sn * V[i][j + 1]; + V[i][j + 1] = -sn * V[i][j] + cs * V[i][j + 1]; + V[i][j] = t; + } + } + t = Maths.hypot(f, g); + cs = f / t; + sn = g / t; + s[j] = t; + f = cs * e[j] + sn * s[j + 1]; + s[j + 1] = -sn * e[j] + cs * s[j + 1]; + g = sn * e[j + 1]; + e[j + 1] = cs * e[j + 1]; + if (wantu && (j < m - 1)) { + for (int i = 0; i < m; i++) { + t = cs * U[i][j] + sn * U[i][j + 1]; + U[i][j + 1] = -sn * U[i][j] + cs * U[i][j + 1]; + U[i][j] = t; + } + } + } + e[p - 2] = f; + iter = iter + 1; + } + break; + + // Convergence. + + case 4: { + + // Make the singular values positive. + + if (s[k] <= 0.0) { + s[k] = (s[k] < 0.0 ? -s[k] : 0.0); + if (wantv) { + for (int i = 0; i <= pp; i++) { + V[i][k] = -V[i][k]; + } + } + } + + // Order the singular values. + + while (k < pp) { + if (s[k] >= s[k + 1]) { + break; + } + double t = s[k]; + s[k] = s[k + 1]; + s[k + 1] = t; + if (wantv && (k < n - 1)) { + for (int i = 0; i < n; i++) { + t = V[i][k + 1]; + V[i][k + 1] = V[i][k]; + V[i][k] = t; + } + } + if (wantu && (k < m - 1)) { + for (int i = 0; i < m; i++) { + t = U[i][k + 1]; + U[i][k + 1] = U[i][k]; + U[i][k] = t; + } + } + k++; + } + iter = 0; + p--; + } + break; + } + } + } + + /* + * ------------------------ Public Methods ------------------------ + */ + + /** + * Return the left singular vectors + * + * @return U + */ + + public Matrix getU() { + return new Matrix(U, m, Math.min(m + 1, n)); + } + + /** + * Return the right singular vectors + * + * @return V + */ + + public Matrix getV() { + return new Matrix(V, n, n); + } + + /** + * Return the one-dimensional array of singular values + * + * @return diagonal of S. + */ + + public double[] getSingularValues() { + return s; + } + + /** + * Return the diagonal matrix of singular values + * + * @return S + */ + + public Matrix getS() { + Matrix X = new Matrix(n, n); + double[][] S = X.getArray(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + S[i][j] = 0.0; + } + S[i][i] = this.s[i]; + } + return X; + } + + /** + * Two norm + * + * @return max(S) + */ + + public double norm2() { + return s[0]; + } + + /** + * Two norm condition number + * + * @return max(S)/min(S) + */ + + public double cond() { + return s[0] / s[Math.min(m, n) - 1]; + } + + /** + * Effective numerical matrix rank + * + * @return Number of nonnegligible singular values. + */ + + public int rank() { + double eps = Math.pow(2.0, -52.0); + double tol = Math.max(m, n) * s[0] * eps; + int r = 0; + for (int i = 0; i < s.length; i++) { + if (s[i] > tol) { + r++; + } + } + return r; + } +} diff --git a/src/bilib/src/levenbergmarquardt/Cholesky.java b/src/bilib/src/levenbergmarquardt/Cholesky.java new file mode 100644 index 0000000000000000000000000000000000000000..79ed3c31b248b464744a316636c8c2ee3970136e --- /dev/null +++ b/src/bilib/src/levenbergmarquardt/Cholesky.java @@ -0,0 +1,111 @@ +package levenbergmarquardt; + +/** + * + * <p> + * Title: Cholesky Decomposition + * </p> + * <p> + * Description: Performs a Cholesky decomposition of a matrix and solve a linear + * system using this decomposition. Ported to Java from the Numerical Recipes in + * C. Press, Teukolsky, Vetterling,and Flannery. 2nd edition. Cambridge + * University Press, 1992. + * </p> + */ + +public class Cholesky { + + /** + * Given a positive-definite symmetric matrix A[1..n][1..n], this method + * constructs its Cholesky decomposition, A = L � L' . On input, only the + * upper triangle of a need be given; it is not modified. The Cholesky + * factor L is returned in the lower triangle of a, except for its diagonal + * elements which are returned in p[1..n]. + * + * @param A + * double[][] Input matrix. + * @param p + * double[] + * @return boolean Returns false if the decomposition is not possible. + */ + public static boolean decomp(double[][] A, double[] p) { + int n = A.length; + int i, j, k; + double sum; + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + sum = A[i][j]; + for (k = i - 1; k >= 0; k--) { + sum -= (A[i][k] * A[j][k]); + } + if (i == j) { + if (sum <= 0.) { + return false; // not positive definite + } + p[i] = Math.sqrt(sum); + } + else { + A[j][i] = sum / p[i]; + } + } + } + return true; + } // decomp + + /** + * Solves a the linear system Ax=b. + * + * @param A + * double[][] Is the result of decomp(A) + * @param p + * double[] The resulting diagonal vector. + * @param b + * double[] + * @param x + * double[] + */ + private static void solve(double[][] A, double[] p, double[] b, double[] x) { + int n = A.length; + int i, k; + double sum; + // Solve L � y = b, storing y in x. + for (i = 0; i < n; i++) { + sum = b[i]; + for (k = i - 1; k >= 0; k--) { + sum -= (A[i][k] * x[k]); + } + x[i] = sum / p[i]; + } + + // Solve L' � x = y. + for (i = n - 1; i >= 0; i--) { + sum = x[i]; + for (k = i + 1; k < n; k++) { + sum -= (A[k][i] * x[k]); + } + x[i] = sum / p[i]; + } + } // solve + + /** + * Solves the linear system Ax=b. + * + * @param A + * double[][] + * @param x + * double[] + * @param b + * double[] + * @return boolean returns false if the system can not be solved using + * Cholesky decomposition. + */ + public static boolean solve(double[][] A, double[] x, double[] b) { + double[] p = new double[A.length]; + if (!decomp(A, p)) { + return false; + } + solve(A, p, b, x); + return true; + } // solve + +} // Cholesky diff --git a/src/bilib/src/levenbergmarquardt/Function.java b/src/bilib/src/levenbergmarquardt/Function.java new file mode 100644 index 0000000000000000000000000000000000000000..1ade3c6e4c7505c2ea8a88f07751062b09f4bf2a --- /dev/null +++ b/src/bilib/src/levenbergmarquardt/Function.java @@ -0,0 +1,32 @@ +package levenbergmarquardt; + +/** + */ +public interface Function { + + /** + * Evaluates the model at point x (may be mulidimensional). + * + * @param x + * double[] Point where we evaluate the model function. + * @param a + * double[] Model estimators. + * @return double + */ + public abstract double eval(double[] x, double[] a); + + /** + * Returns the kth component of the gradient df(x,a)/da_k + * + * @param x + * double[] + * @param a + * double[] + * @param ak + * int + * @return double + */ + public abstract double grad(double[] x, double[] a, int ak); + + public abstract void setDebug(boolean debug); +} diff --git a/src/bilib/src/levenbergmarquardt/LevenbergMarquardt.java b/src/bilib/src/levenbergmarquardt/LevenbergMarquardt.java new file mode 100644 index 0000000000000000000000000000000000000000..3d32bab26a929919dbae0dde1119958b35aff405 --- /dev/null +++ b/src/bilib/src/levenbergmarquardt/LevenbergMarquardt.java @@ -0,0 +1,297 @@ +package levenbergmarquardt; + +/** + * + * <p> + * Title: Levenberg-Marquardt + * </p> + * <p> + * Description: Perfoms data fitting to a non linear model using the + * Levenberg-Marquadrt method. Ported to Java from the Numerical Recipes in C. + * Press, Teukolsky, Vetterling,and Flannery. 2nd edition. Cambridge University + * Press, 1992. + * </p> + */ + +public class LevenbergMarquardt { + + private Function f; + private double lambdaInitial = 0.0001; + private int itmax = 1000; + private boolean print = false; + private int iter; + private double tolerance = 0.001; + + /** + * Levenberg-Marquardt constructor. Supply a Function object, f, that + * evaluates the fitting function y, and its derivatives dyda[1..ma] with + * respect to the fitting parameters a at x. On the first call provide an + * initial guess for the parameters a, and set alamda to some small value, + * e.g. alambda=0.001. If a step succeeds chisq becomes smaller and alamda + * decreases by a factor of 10. If a step fails alamda grows by a factor of + * 10. + * + * @param f + * Function + * @param lambdaInitial + * double + * @param itmax + * int + */ + public LevenbergMarquardt(Function f, double lambdaInitial, int itmax, boolean print) { + this.f = f; + this.lambdaInitial = lambdaInitial; + this.itmax = itmax; + this.print = print; + if (print) { + System.out.print("CONSTRUCTOR \tlambda:" + lambdaInitial + " max iterations: " + itmax); + } + } + + public LevenbergMarquardt(Function f, int itmax, double tolerance) { + this.f = f; + this.itmax = itmax; + this.tolerance = tolerance; + } + + public LevenbergMarquardt(Function f, int itmax) { + this.f = f; + this.itmax = itmax; + } + + public LevenbergMarquardt(Function f, boolean print) { + this.f = f; + this.print = print; + } + + public LevenbergMarquardt(Function f) { + this.f = f; + } + + public void setPrint(boolean print) { + this.print = print; + } + + /** + * Levenberg-Marquardt method, attempting to reduce the value chi2 of a fit + * between a set of data points x[1..ndata], y[1..ndata] with individual + * standard deviations sig[1..ndata], and a nonlinear function dependent on + * ma coefficients a[1..ma]. The input array ia[1..ma] indicates by true, + * entries those components of a that should be fitted for, and by false, + * entries those components that should be held fixed at their input values. + * The program returns current best-fit values for the parameters a[1..ma], + * and chi2 = chisq. + * + * @param x + * double[] + * @param y + * double[] + * @param sig + * double[] + * @param a + * double[] + * @return double + * + */ + public double minimize(double x[], double y[], double sig[], double a[]) { + iter = 0; + double lambda = lambdaInitial; + + boolean ia[] = new boolean[a.length]; + for (int i = 0; i < a.length; i++) + ia[i] = true; + + int rep = 0; + boolean done = false; + double eps = 0; + int mfit = 0; + int j, k, l; + int ma = a.length; + double ochisq = 0, chisq; + + double[][] covar = new double[ma][ma]; + double[][] alpha = new double[ma][ma]; + double[] beta = new double[ma]; + double[] atry = new double[ma]; + double[] da = new double[ma]; + + double[] oneda; + + // initialization + for (mfit = 0, j = 0; j < ma; j++) { + if (ia[j]) { + mfit++; + } + } + oneda = new double[mfit]; + + chisq = mrqcof(x, y, sig, a, ia, alpha, beta); + ochisq = chisq; + for (j = 0; j < ma; j++) { + atry[j] = a[j]; + } + + do { + // Alter linearized fitting matrix, by augmenting diagonal elements. + for (j = 0; j < mfit; j++) { + for (k = 0; k < mfit; k++) { + covar[j][k] = alpha[j][k]; + } + covar[j][j] = alpha[j][j] * (1.0 + lambda); + oneda[j] = beta[j]; + } + + Cholesky.solve(covar, oneda, oneda); // Matrix solution. + + for (j = 0; j < mfit; j++) { + da[j] = oneda[j]; + } + + for (j = 0, l = 0; l < ma; l++) { + if (ia[l]) { + atry[l] = a[l] + da[j++]; + } + } + chisq = mrqcof(x, y, sig, atry, ia, covar, da); + eps = Math.abs(chisq - ochisq); + if (print) { + System.out.print("#" + iter + "\t chi:" + Math.round(Math.sqrt(chisq) * 1000) / 1000.0 + " \tlambda:" + lambda + " eps:" + eps); + for (int i = 0; i < a.length; i++) + System.out.print("\t a[" + i + "]=" + atry[i]); + System.out.println(";"); + } + if (chisq < ochisq) { + // Success, accept the new solution. + lambda *= 0.1; + ochisq = chisq; + for (j = 0; j < mfit; j++) { + for (k = 0; k < mfit; k++) { + alpha[j][k] = covar[j][k]; + } + beta[j] = da[j]; + } + for (l = 0; l < ma; l++) { + a[l] = atry[l]; + } + } + else { + // Failure, increase alamda and return. + lambda *= 10.0; + chisq = ochisq; + } + iter++; + if (eps > tolerance) { + rep = 0; + } + else { + rep++; + if (rep == 4) { + done = true; + } + } + + } + while (iter < itmax && !done); + if (print) + System.out.println("Final iter" + iter + "\t rep:" + rep + " \tdone:" + done + " eps:" + eps + " tolerance:" + tolerance); + + return Math.sqrt(chisq); + } + + /** + * Return the number of iterations after minimization. + * + * @return number of iteration + */ + public int getIteration() { + return iter; + } + + /** + * Used by mrqmin to evaluate the linearized fitting matrix alpha, and + * vector beta as in "NR in C"(15.5.8), and calculate chi2. + * + * @param x + * double[] + * @param y + * double[] + * @param sig + * double[] + * @param a + * double[] + * @param ia + * boolean[] + * @param alpha + * double[][] + * @param beta + * double[] + * @param f + * LMfunc + * @return double + */ + private double mrqcof(double x[], double y[], double sig[], double a[], boolean ia[], double alpha[][], double beta[]) { + + int ndata = x.length; + int ma = a.length; + double chisq; + int i, j, k, l, m, mfit = 0; + double ymod, wt, sig2i, dy; + double[] dyda = new double[ma]; + + for (j = 0; j < ma; j++) { + if (ia[j]) { + mfit++; + } + } + + // Initialize(symmetric) alpha, beta. + for (j = 0; j < mfit; j++) { + for (k = 0; k <= j; k++) { + alpha[j][k] = 0; + } + beta[j] = 0; + } + + chisq = 0; + + // Summation loop over all data. + for (i = 0; i < ndata; i++) { + double[] xi = new double[1]; + xi[0] = x[i]; + ymod = f.eval(xi, a); + for (k = 0; k < a.length; k++) { + dyda[k] = f.grad(xi, a, k); + } + + /* + * if (print) { System.out.print("D" + iter); for(int p=0; + * p<dyda.length; p++) System.out.print("\t da["+p+"]=" + dyda[p]); + * System.out.println(";"); } + */ + sig2i = 1.0 / (sig[i] * sig[i]); + dy = y[i] - ymod; + for (j = 0, l = 0; l < ma; l++) { + if (ia[l]) { + wt = dyda[l] * sig2i; + for (k = 0, m = 0; m <= l; m++) { + if (ia[m]) { + alpha[j][k++] += wt * dyda[m]; + } + } + beta[j] += dy * wt; + j++; + } + } + chisq += dy * dy * sig2i; // And find chi2. + } + + // Fill in the symmetric side of alpha + for (j = 1; j < mfit; j++) { + for (k = 0; k < j; k++) { + alpha[k][j] = alpha[j][k]; + } + } + return chisq; + } + +} diff --git a/src/bilib/src/polyharmonicwavelets/Autocorrelation.java b/src/bilib/src/polyharmonicwavelets/Autocorrelation.java new file mode 100644 index 0000000000000000000000000000000000000000..2bbedf25ef80c5b5519714ed1e5992574d9ecbfa --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/Autocorrelation.java @@ -0,0 +1,291 @@ +package polyharmonicwavelets; + +// +// Autocorrelation.java +// PolyharmonicWavelets +// +// Created by Biomedical Imaging Group on 2/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +import java.util.*; +import java.text.DecimalFormat; + +/** + * This class computes the autocorrelation of the polyharmonic B-spline + * function. Two methods can be used, the Gamma function method [1] or the + * iterative algorithm [2]. <br> + * References: <br> + * [1] Yan Barbotin semmester project <br> + * [2] T. Blu, D. Van De Ville, M. Unser, ''Numerical methods for the + * computation of wavelet correlation sequences,'' SIAM Numerical Analysis. <br> + * [3] Matlab documentation + * + * @author Katarina Balac, EPFL. + */ + +public class Autocorrelation { + + /** + * Returns the Fourier domain autocorrelation of any scaling function given + * the squared modulus of the refinement filter. <br> + * Reference: T. Blu, D. Van De Ville, M. Unser, ''Numerical methods for the + * computation of wavelet correlation sequences,'' SIAM Numerical Analysis. + * + * @param HH + * the squared modulus of the refinement filter. + * @return the autocorreltion of scaling function. + */ + + public static ComplexImage autocorrIterative(ComplexImage HH) { + int nx = HH.nx; + int ny = HH.ny; + int lx = nx / 2; + int ly = ny / 2; + int lyx = ly * lx; + ComplexImage A0 = new ComplexImage(lx, ly, true); + ComplexImage Af = new ComplexImage(lx, ly); + ComplexImage Afe = new ComplexImage(lx + 1, ly + 1); + ComplexImage Ad = new ComplexImage(lx, ly, true); + ComplexImage Aq = new ComplexImage(lx, ly, true); + ComplexImage A1 = new ComplexImage(lx, ly, true); + ComplexImage At = new ComplexImage(nx, ny, true); // Does not change + // size + ComplexImage Ai = new ComplexImage(nx, ny); + for (int i = 0; i < lx * ly; i++) { + A0.real[i] = 1.0; + } + final double crit = 0.00000001; // stop criterion + double improvement; + int lx2 = lx / 2; + int lx231 = 3 * lx2 - 1; + int ly2 = ly / 2; + int ly231 = 3 * ly2 - 1; + int ly32 = 3 * ly / 2; + int k1 = nx * 3 * ly / 2 + lx / 2; + int k3 = nx * ly / 2 + 3 * lx / 2; + int k2 = k3 - 1; + int k4 = nx * (ly32 - 1) + lx / 2; + int count = 0; + int maxit = 100; + do { + count++; + Af.copyImageContent(A0); + Af.iFFT2D(); + Af.shift(); + for (int x = 0; x < lx; x++) { + Af.real[x] /= 2.0; + Af.imag[x] /= 2.0; + } + for (int y = 0; y < lyx; y += lx) { + Af.real[y] /= 2.0; + Af.imag[y] /= 2.0; + } + Afe.extend(Af); + Ai.putZeros(); + Ai.putSubimage(lx2, ly2, Afe); + Ai.shift(); + Ai.FFT2D(); // Ai is real + // recursion + A1.putZeros(); + At.copyImageContent(HH); + At.multiply(Ai); + Aq.getSubimageContent(0, Aq.nx - 1, 0, Aq.ny - 1, At); + A1.add(Aq); + Aq.getSubimageContent(0, Aq.nx - 1, ly, ly + Aq.ny - 1, At); + A1.add(Aq); + Aq.getSubimageContent(lx, lx + Aq.nx - 1, 0, Aq.ny - 1, At); + A1.add(Aq); + Aq.getSubimageContent(lx, lx + Aq.nx - 1, ly, ly + Aq.ny - 1, At); + A1.add(Aq); + Ad.copyImageContent(A1); + Ad.subtract(A0); + improvement = Ad.meanModulus(); + A0 = A1.copyImage(); + } + while ((improvement > crit) && (count < maxit)); + System.out.println("The autocoorelation has been computed in " + count + " iterations."); + if (count == maxit) { + System.out.println("The autocorrelation does not converge!"); + } + return A0; + } + + /** + * Returns the autocorrelation of the polyharmonic B-spline function given + * the squared modulus of its localisation. <br> + * Reference: Yan Barbotin semmester project + * + * @param loc + * the polyharmonic B-spline localisation + * @param order + * the order of polyharmonic B-spline + * @return the polyharmonic B-spline autocorrelation + */ + + public static ComplexImage autocorrGamma(ComplexImage loc, double order) { + final double PI = Math.PI; + final double PI2 = 2.0 * PI; + double[][] d = { { 0.0, 1.0 }, { 0.0, 2.0 }, { 1.0, 0.0 }, { 1.0, 1.0 }, { 1.0, 2.0 }, { 2.0, 0.0 }, { 2.0, 1.0 }, { -1.0, 0.0 }, { -1.0, 1.0 }, { -1.0, 2.0 }, { -2.0, 0.0 }, + { -2.0, 1.0 }, { 0.0, -1.0 }, { 0.0, -2.0 }, { 1.0, -1.0 }, { 1.0, -2.0 }, { 2.0, -1.0 }, { -1.0, -1.0 }, { -1.0, -2.0 }, { -2.0, -1.0 }, { 0.0, 0.0 } }; // 21 + // pair + int nx = loc.nx; + int ny = loc.ny; + int nxy = nx * ny; + ComplexImage ac = new ComplexImage(nx, ny, true); + GammaFunction gm = new GammaFunction(); + double gammanorm = Math.exp(gm.lnGamma(order)); + for (int kx = 0, nx2 = nx / 2; kx <= nx2; kx++) { + for (int ky = 0, ny2 = ny / 2; ky <= ny2; ky++) { + int kynx = ky * nx; + if (ac.real[kynx + kx] == 0.0) { + int kxny = kx * ny; + double x = (double) kx / (double) nx; + double y = (double) ky / (double) ny; + double res = 1.0 / (order - 1.0); + for (int i = 0; i < 21; i++) { + double sqn = PI * ((x - d[i][0]) * (x - d[i][0]) + (y - d[i][1]) * (y - d[i][1])); + res += gm.incompleteGammaQ(order, sqn) * gammanorm / Math.pow(sqn, order); + sqn = PI * (d[i][0] * d[i][0] + d[i][1] * d[i][1]); + if (sqn > 0.0) { + res += incompleteGammaGeneral(sqn, 1.0 - order) * Math.cos(PI2 * (d[i][0] * x + d[i][1] * y)) / Math.pow(sqn, 1.0 - order); + } + } + ac.real[kynx + kx] = res; + if (kx > 0) { + ac.real[kynx + nx - kx] = res; + } + if (ky > 0) { + ac.real[nxy - kynx + kx] = res; + } + if ((kx > 0) && (ky > 0)) { + ac.real[nxy - kynx + nx - kx] = res; + } + if ((((kynx / ny) * ny) == kynx) && (((kxny / nx) * nx) == kxny)) { + int kx1 = ky * nx / ny; + int ky1 = kx * ny / nx; + kynx = ky1 * nx; + kxny = kx1 * ny; + ac.real[kynx + kx1] = res; + if (kx1 > 0) { + ac.real[kynx + nx - kx1] = res; + } + if (ky1 > 0) { + ac.real[nxy - kynx + kx1] = res; + } + if ((kx1 > 0) && (ky1 > 0)) { + ac.real[nxy - kynx + nx - kx1] = res; + } + } + } + } + } + ac.multiply(Math.pow(PI, order) / (gammanorm * Math.pow(PI2, 2.0 * order))); + ac.multiply(loc); + ac.real[0] = 1.0; + return ac; + } + + /* + * Solves the incomplete gamma function even for negative a, regularised + * integral from x to infinity. Not normalised. x has to be positive. + * Reference: Yan Barbotin semmester project + */ + + private static double incompleteGammaGeneral(double x, double a) { + double res = 0; + GammaFunction gm = new GammaFunction(); + if (a < 0) { + double a0 = a; + int iter = 0; + while (a < 0) { + a += 1.0; + iter++; + } + if (a == 0.0) { + res = expInt(x); + } + else { + res = gm.incompleteGammaQ(a, x) * Math.exp(gm.lnGamma(a)); + } + res *= Math.exp(x - a * Math.log(x)); + for (int k = 1; k <= iter; k++) { + res = (x * res - 1.0) / (a - (double) k); + } + res *= Math.exp(a0 * Math.log(x) - x); + } + else { + if (a == 0.0) { + res = expInt(x); + } + else { + res = gm.incompleteGammaQ(a, x) * Math.exp(gm.lnGamma(a)); + } + } + return res; + } + + /* + * Computes the exponential integral for a real positive argument x. Copied + * from Matlab. + */ + + private static double expInt(double x) { + double[] p = { -3.602693626336023e-09, -4.819538452140960e-07, -2.569498322115933e-05, -6.973790859534190e-04, -1.019573529845792e-02, -7.811863559248197e-02, -3.012432892762715e-01, + -7.773807325735529e-01, 8.267661952366478e+00 }; + double d = 0.0; + double y = 0.0; + for (int j = 0; j < 9; j++) { + d *= x; + d += p[j]; + } + if (d > 0.0) { + double egamma = 0.57721566490153286061; + y = -egamma - Math.log(x); + double term = x; + double pterm = x; + double eps = 0.00000000000000000000000000001; + for (double j = 2.0; Math.abs(term) > eps; j += 1.0) { + y += term; + pterm = -x * pterm / j; + term = pterm / j; + } + } + else { + double n = 1.0; + double am2 = 0.0; + double bm2 = 1.0; + double am1 = 1.0; + double bm1 = x; + double f = am1 / bm1; + double oldf = f + 100.0; + double j = 2.0; + double eps = 0.000000000000000000000000001; + while (Math.abs(f - oldf) > eps) { + double alpha = n - 1.0 + j / 2.0; + double a = am1 + alpha * am2; + double b = bm1 + alpha * bm2; + am2 = am1 / b; + bm2 = bm1 / b; + am1 = a / b; + bm1 = 1.0; + oldf = f; + f = am1; + j += 1.0; + alpha = (j - 1.0) / 2.0; + double beta = x; + a = beta * am1 + alpha * am2; + b = beta * bm1 + alpha * bm2; + am2 = am1 / b; + bm2 = bm1 / b; + am1 = a / b; + bm1 = 1.0; + oldf = f; + f = am1; + j += 1.0; + } + y = Math.exp(-x) * f; + } + return y; + } +} diff --git a/src/bilib/src/polyharmonicwavelets/CoeffProcessing.java b/src/bilib/src/polyharmonicwavelets/CoeffProcessing.java new file mode 100644 index 0000000000000000000000000000000000000000..3229509f8650fedd4b40814c63c9370e6aed13b0 --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/CoeffProcessing.java @@ -0,0 +1,371 @@ +package polyharmonicwavelets; + +// +// CoeffProcessing.java +// PolyharmonicWavelets +// +// Created by Biomedical Imaging Group on 2/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +import java.util.*; +import ij.*; +import java.text.DecimalFormat; +import ij.text.*; + +/** + * This class is used to proccess the wavelet transform coefficients. + * + * @author Katarina Balac, EPFL. + */ + +final public class CoeffProcessing { + + /** + * Do your own processing. + * + * @param param + * the transform parameters + * @param transform + * the array of transform coefficients + */ + + static final public void doMyProcessing(Parameters param, ComplexImage[] transform) { + if (param.redundancy == param.PYRAMID) { + for (int j = 0; j < param.J; j++) { + // ................... + // process highpass transform[j] + // .................... + } + // ................... + // process lowpass transform[J] + // .................... + } + else { // nonredundant + if (param.lattice == param.DYADIC) { + int dx = transform[0].nx; + int dy = transform[0].ny; + dx /= 2; + dy /= 2; + for (int j = 0; j < param.J; j++) { + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + // ................... + // process highpass subband + // .................... + transform[0].putSubimage(0, dy, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + // ................... + // process highpass subband + // .................... + transform[0].putSubimage(dx, 0, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, dy, 2 * dy - 1); + // ................... + // process highpass subband + // .................... + transform[0].putSubimage(dx, dy, subband); + dx /= 2; + dy /= 2; + } + ComplexImage subband = transform[0].getSubimage(0, dx - 1, 0, dy - 1); + // ................... + // process lowpass subband + // .................... + transform[0].putSubimage(0, 0, subband); + } + else { // quincunx + int dx = transform[0].nx; + int dy = transform[0].ny; + dx /= 2; + for (int j = 0; j < param.J; j++) { + if (j % 2 == 0) { + ComplexImage subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + // ................... + // process highpass subband + // .................... + transform[0].putSubimage(dx, 0, subband); + dy /= 2; + } + else { + dy /= 2; + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + // ................... + // process highpass subband + // .................... + transform[0].putSubimage(0, dy, subband); + dx /= 2; + } + ComplexImage subband = transform[0].getSubimage(0, dx - 1, 0, dy - 1); + // ................... + // process lowpass subband + // .................... + transform[0].putSubimage(0, 0, subband); + } + } + } + } + + /** + * Implements hard threshold on transform coefficients. + * + * @param param + * the transform parameters + * @param transform + * the array of transform coefficients + * @param t + * the threshold + */ + + static final public void doHardThreshold(Parameters param, ComplexImage[] transform, double t) { + if (param.redundancy == param.PYRAMID) { + for (int j = 0; j < param.J; j++) { + transform[j].hardThreshold(t); + } + } + else { // nonredundant + if (param.lattice == param.DYADIC) { + int dx = transform[0].nx; + int dy = transform[0].ny; + dx /= 2; + dy /= 2; + for (int j = 0; j < param.J; j++) { + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + subband.hardThreshold(t); + transform[0].putSubimage(0, dy, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + subband.hardThreshold(t); + transform[0].putSubimage(dx, 0, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, dy, 2 * dy - 1); + subband.hardThreshold(t); + transform[0].putSubimage(dx, dy, subband); + dx /= 2; + dy /= 2; + } + } + else { // quincunx + int dx = transform[0].nx; + int dy = transform[0].ny; + for (int j = 0; j < param.J; j++) { + if (j % 2 == 0) { + dx /= 2; + ComplexImage subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + subband.hardThreshold(t); + transform[0].putSubimage(dx, 0, subband); + } + else { + dy /= 2; + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + subband.hardThreshold(t); + transform[0].putSubimage(0, dy, subband); + } + } + } + } + } + + /** + * Implements soft threshold on transform coefficients. + * + * @param param + * the transform parameters + * @param transform + * the array of transform coefficients + * @param t + * the threshold + */ + + static final public void doSoftThreshold(Parameters param, ComplexImage[] transform, double t) { + if (param.redundancy == param.PYRAMID) { + for (int j = 0; j < param.J; j++) { + transform[j].softThreshold(t); + } + } + else { // nonredundant + if (param.lattice == param.DYADIC) { + int dx = transform[0].nx; + int dy = transform[0].ny; + dx /= 2; + dy /= 2; + for (int j = 0; j < param.J; j++) { + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + subband.softThreshold(t); + transform[0].putSubimage(0, dy, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + subband.softThreshold(t); + transform[0].putSubimage(dx, 0, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, dy, 2 * dy - 1); + subband.softThreshold(t); + transform[0].putSubimage(dx, dy, subband); + dx /= 2; + dy /= 2; + } + } + else { // quincunx + int dx = transform[0].nx; + int dy = transform[0].ny; + for (int j = 0; j < param.J; j++) { + if (j % 2 == 0) { + dx /= 2; + ComplexImage subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + subband.softThreshold(t); + transform[0].putSubimage(dx, 0, subband); + } + else { + dy /= 2; + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + subband.softThreshold(t); + transform[0].putSubimage(0, dy, subband); + } + } + } + } + } + + /** + * Applies the soft threshold to each subband where threshold is computed + * from the image features. + * + * @param param + * the transform parameters + * @param transform + * the array of transform coefficients. + */ + + static final public void softThresholdAdaptive(Parameters param, ComplexImage[] transform) { // take + // care + // of + // redundant! + int J = param.J; + double[] scale = { 1.0, 0.6, 0.34, 0.26, 0.23, 0.21, 0.20, 0.20 }; + double[] threshold = new double[J]; + double coef = 1.0; + double c = 0.1 * coef; + ComplexImage firstsubband = transform[0].copyImage(); + int nx = firstsubband.nx; + int ny = firstsubband.ny; + if (param.redundancy == param.BASIS) { + if (param.lattice == param.DYADIC) { + firstsubband = firstsubband.getSubimage(nx / 2, nx - 1, ny / 2, ny - 1); + } + else { + firstsubband = firstsubband.getSubimage(nx / 2, nx - 1, 0, ny - 1); + } + } + threshold[0] = firstsubband.deviation() * c; + if (J > 8) { + for (int k = 1; k < 8; k++) { + threshold[k] = threshold[0] * scale[k]; + } + for (int k = 8; k < J; k++) { + threshold[k] = threshold[8]; + } + } + else { + for (int k = 1; k < J; k++) { + threshold[k] = threshold[0] * scale[k]; + } + } + if (param.redundancy == param.PYRAMID) { + for (int j = 0; j < param.J; j++) { + transform[j].softThreshold(threshold[j]); + } + } + else { // nonredundant + if (param.lattice == param.DYADIC) { + int dx = transform[0].nx; + int dy = transform[0].ny; + dx /= 2; + dy /= 2; + for (int j = 0; j < param.J; j++) { + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + subband.softThreshold(threshold[j]); + transform[0].putSubimage(0, dy, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + subband.softThreshold(threshold[j]); + transform[0].putSubimage(dx, 0, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, dy, 2 * dy - 1); + subband.softThreshold(threshold[j]); + transform[0].putSubimage(dx, dy, subband); + dx /= 2; + dy /= 2; + } + } + else { // quincunx + int dx = transform[0].nx; + int dy = transform[0].ny; + for (int j = 0; j < param.J; j++) { + if (j % 2 == 0) { + dx /= 2; + ComplexImage subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + subband.softThreshold(threshold[j]); + transform[0].putSubimage(dx, 0, subband); + } + else { + dy /= 2; + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + subband.softThreshold(threshold[j]); + transform[0].putSubimage(0, dy, subband); + } + } + } + } + } + + /** + * Multiplies the coefficients in all highpass subbands with the given + * enhancement parameter. + * + * @param param + * the transform parameters + * @param transform + * the array of transform coefficients + * @param t + * the enhancement parameter + */ + + static final public void doEnhancement(Parameters param, ComplexImage[] transform, double t) { + if (param.redundancy == param.PYRAMID) { + for (int j = 0; j < param.J; j++) { + transform[j].multiply(t); + } + } + else { // nonredundant + if (param.lattice == param.DYADIC) { + int dx = transform[0].nx; + int dy = transform[0].ny; + dx /= 2; + dy /= 2; + for (int j = 0; j < param.J; j++) { + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + subband.multiply(t); + transform[0].putSubimage(0, dy, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + subband.multiply(t); + transform[0].putSubimage(dx, 0, subband); + subband = transform[0].getSubimage(dx, 2 * dx - 1, dy, 2 * dy - 1); + subband.multiply(t); + transform[0].putSubimage(dx, dy, subband); + dx /= 2; + dy /= 2; + } + } + else { // quincunx + int dx = transform[0].nx; + int dy = transform[0].ny; + for (int j = 0; j < param.J; j++) { + if (j % 2 == 0) { + dx /= 2; + ComplexImage subband = transform[0].getSubimage(dx, 2 * dx - 1, 0, dy - 1); + subband.multiply(t); + transform[0].putSubimage(dx, 0, subband); + } + else { + dy /= 2; + ComplexImage subband = transform[0].getSubimage(0, dx - 1, dy, 2 * dy - 1); + subband.multiply(t); + transform[0].putSubimage(0, dy, subband); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/bilib/src/polyharmonicwavelets/ComplexImage.java b/src/bilib/src/polyharmonicwavelets/ComplexImage.java new file mode 100644 index 0000000000000000000000000000000000000000..a33473bed1465bd7deb5e7c5ec64822750b6b370 --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/ComplexImage.java @@ -0,0 +1,2706 @@ +// +// ComplexImage.java +// PolyharmonicWavelets +// +// Created by Biomedical Imaging Group on 2/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +package polyharmonicwavelets; + +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import ij.process.*; +import ij.*; +import java.text.DecimalFormat; +import ij.plugin.filter.PlugInFilter; +import ij.text.*; + +/** + * A ComplexImage object is a two-dimensional array of complex numbers. + * + * @author Katarina Balac, EPFL. + */ + +public class ComplexImage { + + /** + * The real part of the ComplexImage object. + */ + public double real[]; + + /** + * The imaginary part of the ComplexImage object. + */ + public double imag[]; + + /** + * The number of columns in the ComplexImage object. + */ + public int nx; + + /** + * The number of rows in the ComplexImage object. + */ + public int ny; + + /** + * The total number of elements in the ComplexImage object. + */ + public int nxy; + + private final double PI2 = 2.0 * Math.PI; + private final double sqrt2 = Math.sqrt(2.0); + + /** + * Creates a ComplexImage object from an ImagePlus image. + * + * @param imp + * the ImagePlus image used to create the ComplexImage object + */ + + public ComplexImage(ImagePlus imp) { + nx = imp.getWidth(); + ny = imp.getHeight(); + nxy = nx * ny; + real = new double[nxy]; + imag = new double[nxy]; + if (imp.getType() == ImagePlus.GRAY8) { + byte[] pixels = (byte[]) imp.getProcessor().getPixels(); + for (int k = 0; k < nx * ny; k++) + real[k] = (double) (pixels[k] & 0x00FF); + } + if (imp.getType() == ImagePlus.GRAY16) { + short[] pixels = (short[]) imp.getProcessor().getPixels(); + for (int k = 0; k < nx * ny; k++) + real[k] = (double) (pixels[k]); + } + if (imp.getType() == ImagePlus.GRAY32) { + float[] pixels = (float[]) imp.getProcessor().getPixels(); + for (int k = 0; k < nx * ny; k++) + real[k] = (double) (pixels[k]); + } + } + + /** + * Creates a Compleximage object of a given size filed with zeros. + * + * @param sizex + * the number of columns in the ComplexImage + * @param sizey + * the number of rows in the ComplexImage + */ + + public ComplexImage(int sizex, int sizey) { + nx = sizex; + ny = sizey; + nxy = nx * ny; + real = new double[nxy]; + imag = new double[nxy]; + } + + /** + * Creates a Compleximage object of a given size filed with zeros, enables + * not to reserve space for the imaginary part. + * + * @param sizex + * the number of columns in the ComplexImage + * @param sizey + * the number of rows in the ComplexImage + * @param r + * if true the image is real, the imaginary part is set to null + */ + + public ComplexImage(int sizex, int sizey, boolean r) { + nx = sizex; + ny = sizey; + nxy = nx * ny; + real = new double[nxy]; + imag = null; + if (!r) { + imag = new double[nxy]; + } + } + + /** + * If necessary, this ComplexImage is cropped by keeping its central part so + * that the quincunx wavelet analysis can be performed. + * + * @param J + * number of decomposition levels + */ + + public void cropQuincunx(int J) { + int ind = 1; + int lx = nx; + int ly = ny; + for (int j = 0; j < J; j++) { + if (ind == 1) { + lx /= 2; + } + else { + ly /= 2; + } + ind = 1 - ind; + } + ind = 1 - ind; + for (int j = 0; j < J; j++) { + if (ind == 1) { + lx *= 2; + } + else { + ly *= 2; + } + ind = 1 - ind; + } + if (!((lx == nx) && (ly == ny))) { + System.out.println("Image has been cropped"); + int dx = (nx - lx) / 2; + int dy = (ny - ly) / 2; + ComplexImage temp = getSubimage(dx, lx - 1 + dx, dy, ly - 1 + dy); + nx = temp.nx; + ny = temp.ny; + nxy = temp.nxy; + System.arraycopy(temp.real, 0, real, 0, nxy); + System.arraycopy(temp.imag, 0, imag, 0, nxy); + showReal("Cropped image"); + } + } + + /** + * If necessary, this ComplexImage is cropped by keeping its central part so + * that the dyadic wavelet analysis can be performed. + * + * @param J + * number of decomposition levels + */ + + public void cropDyadic(int J) { + int lx = nx; + int ly = ny; + for (int j = 0; j < J; j++) { + lx /= 2; + ly /= 2; + } + + for (int j = 0; j < J; j++) { + lx *= 2; + ly *= 2; + } + if (!((lx == nx) && (ly == ny))) { + System.out.println("Image has been cropped"); + int dx = (nx - lx) / 2; + int dy = (ny - ly) / 2; + ComplexImage temp = getSubimage(dx, lx - 1 + dx, dy, ly - 1 + dy); + nx = temp.nx; + ny = temp.ny; + nxy = temp.nxy; + System.arraycopy(temp.real, 0, real, 0, nxy); + System.arraycopy(temp.imag, 0, imag, 0, nxy); + showReal("Cropped image"); + } + } + + /** + * Returns the maximum number of wavelet iterations for this ComplexImage. + * + * @param type + * the transform lattice, "Quincunx" or "Dyadic" + */ + + public int noIterations(String type) { + int noit = 0; + int dx = nx; + int dy = ny; + if (type == "Dyadic") { + while ((dx % 2 == 0) && (dy % 2 == 0)) { + noit++; + dx /= 2; + dy /= 2; + } + } + if (type == "Quincunx") { + while ((dx % 2 == 0) && (dy % 2 == 0)) { + noit += 2; + dx /= 2; + dy /= 2; + } + if (dx % 2 == 0) { + noit++; + } + } + return noit; + } + + /** + * Crops this ComplexImage to a given size by keeping its central part. + * + * @param lx + * number of columns in the cropped ComplexImage + * @param ly + * number of rows in the cropped ComplexImage + */ + + public void croptoSize(int lx, int ly) { + if (!((lx == nx) && (ly == ny))) { + int dx = (nx - lx) / 2; + int dy = (ny - ly) / 2; + ComplexImage temp = getSubimage(dx, lx - 1 + dx, dy, ly - 1 + dy); + nx = temp.nx; + ny = temp.ny; + nxy = temp.nxy; + System.arraycopy(temp.real, 0, real, 0, nxy); + System.arraycopy(temp.imag, 0, imag, 0, nxy); + } + } + + /** + * Fills the real part of this squared ComplexImage with the zoneplate + * image. + */ + + public void zone() { + int size = nx; + int size2 = size / 2; + double c = Math.PI / sqrt2 / (double) nx; + int ind = 0; + for (int y1 = -size2; y1 < size2; y1++) { + for (int x1 = -size2; x1 < size2; x1++) { + real[ind++] = (1.0 + Math.cos(c * (double) (y1 * y1 + x1 * x1))) * 127.5; + } + } + } + + /** + * Fills the real part of this ComplexImage with random values of Gaussian + * distribution N(0,1). + */ + + public void makeNoise() { + Random random = new Random(); + for (int k = 0; k < nxy; k++) { + real[k] = random.nextGaussian(); + } + } + + /** + * Fills the real part of this ComplexImage with the Gaussian shaped spots. + */ + + public void makeGaussianSpots() { + Random random = new Random(); + int N = random.nextInt(12) + 9; // Number of spots, between 10 and 20 + // int N=1; + int[] X0 = new int[N]; + int[] Y0 = new int[N]; + double[] sigma = new double[N]; + for (int k = 0; k < N; k++) { + X0[k] = random.nextInt(nx - 60) + 30; + Y0[k] = random.nextInt(ny - 60) + 30; + sigma[k] = random.nextDouble() * 5.0 + 1.0; // sigma between 1 and 6 + } + for (int k = 0; k < N; k++) { + double s2 = 2.0 * sigma[k] * sigma[k]; + // double s1=1.0/(s2*Math.PI); + double s1 = 1.0 / (2.0 * Math.PI); + for (int y = -30; y < 30; y++) { + int dy = nx * y; + for (int x = -30; x < 30; x++) { + int p0 = Y0[k] * nx + X0[k]; + double s = s1 * Math.exp(-(double) (x * x + y * y) / s2); + real[p0 + dy + x] += s; + } + } + } + } + + /** + * Displays the real part of this ComplexImage on the screen. + * + * @param text + * name of the image to display + */ + + public void showReal(String text) { + float re[][] = new float[nx][ny]; + int index; + for (int k = 0; k < nx; k++) + for (int l = 0; l < ny; l++) { + index = l * nx + k; + re[k][l] = (float) real[index]; + } + FloatProcessor fp = new FloatProcessor(re); + ImagePlus imp = new ImagePlus(text, fp); + imp.show(); + } + + /** + * Displays the imaginary part of this ComplexImage on the screen. + * + * @param text + * name of the image to display + */ + + public void showImag(String text) { + float imaginary[][] = new float[nx][ny]; + int index; + for (int k = 0; k < nx; k++) + for (int l = 0; l < ny; l++) { + index = l * nx + k; + imaginary[k][l] = (float) imag[index]; + } + FloatProcessor fp = new FloatProcessor(imaginary); + ImagePlus imp = new ImagePlus(text, fp); + imp.show(); + } + + /** + * Displays the modulus of this ComplexImage on the screen. + * + * @param text + * name of the image to display + */ + + public void showModulus(String text) { + float mod[][] = new float[nx][ny]; + int index; + for (int k = 0; k < nx; k++) + if (imag == null) { + for (int l = 0; l < ny; l++) { + index = l * nx + k; + mod[k][l] = (float) Math.abs(real[index]); + } + } + else { + for (int l = 0; l < ny; l++) { + index = l * nx + k; + mod[k][l] = (float) Math.sqrt(real[index] * real[index] + imag[index] * imag[index]); + } + } + FloatProcessor fp = new FloatProcessor(mod); + ImagePlus imp = new ImagePlus(text, fp); + imp.show(); + } + + /** + * Displays the real and the imaginary part of this ComplexImage as a stack. + * + * @param text + * name of the stack to be displayed + */ + + public void displayComplexStack(String text) { + double color = -255.0; + ComplexImage[] out = new ComplexImage[2]; + ImageStack stack = new ImageStack(nx, ny); + float ima[][] = new float[nx][ny]; + for (int k = 0; k < nx; k++) { + for (int l = 0; l < ny; l++) { + int index = l * nx + k; + ima[k][l] = (float) real[index]; + } + } + FloatProcessor fp = new FloatProcessor(ima); + fp.setValue(color); + stack.addSlice("Real part", fp); + for (int k = 0; k < nx; k++) { + for (int l = 0; l < ny; l++) { + int index = l * nx + k; + ima[k][l] = (float) imag[index]; + } + } + fp = new FloatProcessor(ima); + fp.setValue(color); + stack.addSlice("Imaginary part", fp); + ImagePlus imp = new ImagePlus(text, stack); + imp.show(); + } + + /** + * Displays the real parts of ComplexImages in an array as a stack. + * + * @param array + * the aray of images to be displayed + * @param text + * name of the stack to be displayed + */ + + public static void displayStack(ComplexImage[] array, String text) { + int nx = array[0].nx; + int ny = array[0].ny; + ImageStack stack = new ImageStack(nx, ny); + float ima[][] = new float[nx][ny]; + for (int j = 0; j < array.length; j++) { + float im[][] = new float[nx][ny]; + int index; + for (int k = 0; k < nx; k++) { + for (int l = 0; l < ny; l++) { + index = l * nx + k; + ima[k][l] = (float) array[j].real[index]; + } + } + FloatProcessor fp = new FloatProcessor(ima); + stack.addSlice("j", fp); + } + ImagePlus imp = new ImagePlus(text, stack); + imp.show(); + } + + /** + * Displays the imaginary parts of ComplexImages in an array as a stack. + * + * @param array + * the aray of images to be displayed + * @param text + * name of the stack to be displayed + */ + + public static void displayStackImag(ComplexImage[] array, String text) { + int nx = array[0].nx; + int ny = array[0].ny; + ImageStack stack = new ImageStack(nx, ny); + float ima[][] = new float[nx][ny]; + for (int j = 0; j < array.length; j++) { + float im[][] = new float[nx][ny]; + int index; + for (int k = 0; k < nx; k++) + for (int l = 0; l < ny; l++) { + index = l * nx + k; + ima[k][l] = (float) array[j].imag[index]; + } + FloatProcessor fp = new FloatProcessor(ima); + stack.addSlice("j", fp); + } + ImagePlus imp = new ImagePlus(text, stack); + imp.show(); + } + + /** + * Displays this ComplexImage values on the screen. + * + * @param text + * name of the image to be displayed + */ + + public void displayValues(String text) { + DecimalFormat decimalFormat = new DecimalFormat(); + decimalFormat.applyPattern("0.0000"); + System.out.println(" "); + System.out.println(text); + System.out.println("sizenxnx=" + nx); + System.out.println("sizeny=" + ny); + for (int i = 0; i < ny; i++) { + for (int j = 0; j < nx; j++) { + System.out.print(" " + decimalFormat.format(real[i * nx + j]) + "+" + decimalFormat.format(imag[i * nx + j]) + "i"); + } + System.out.println(" "); + } + } + + /** + * Sets both the real and the imaginary part of this ComplexImage object to + * zero. + */ + + public void putZeros() { + if (imag == null) { + for (int i = 0; i < nxy; i++) { + real[i] = 0.0; + } + } + else { + for (int i = 0; i < nxy; i++) { + real[i] = imag[i] = 0.0; + } + } + } + + /** + * Sets the real part of this ComplexImage object to zero. + */ + + public void setRealtoZero() { + for (int k = 0; k < nxy; k++) { + real[k] = 0.0; + } + } + + /** + * Sets the imaginary part of this ComplexImage object to zero. + */ + + public void setImagtoZero() { + for (int k = 0; k < nxy; k++) { + imag[k] = 0.0; + } + } + + /** + * Sets all the values in this ComplexImage to a given constant. + * + * @param r + * - the real part of the ComplexImage to be set + * @param i + * - the imaginary part of the ComplexImage to be set + */ + + public void settoConstant(double r, double i) { + for (int k = 0; k < nxy; k++) { + real[k] = r; + imag[k] = i; + } + } + + /** + * Sets the real part of this ComplexImage to a given constant. + * + * @param r + * - the value to be set + */ + + public void settoConstant(double r) { + for (int k = 0; k < nxy; k++) { + real[k] = r; + } + } + + /** + * Creates a new ComplexImage object containing the chosen row of this + * ComplexImage. + * + * @param y + * the number of row to be copied + * @return ComplexImage containing the chosen row + */ + + public ComplexImage getRow(int y) { + ComplexImage row = new ComplexImage(nx, 1, imag == null); + System.arraycopy(real, y * nx, row.real, 0, nx); + if (!(imag == null)) { + System.arraycopy(imag, y * nx, row.imag, 0, nx); + } + return row; + } + + /** + * Copies the content of the chosen row of image to this ComplexImage. + * + * @param image + * the ComplexImage to copy from + * @param y + * the number of row to be copied + */ + + public void getRowContent(int y, ComplexImage image) { + nx = image.nx; + ny = 1; + int s = y * nx; + System.arraycopy(image.real, s, real, 0, image.nx); + if ((!(imag == null)) && (!(image.imag == null))) { + System.arraycopy(image.imag, s, imag, 0, image.nx); + } + } + + /** + * Copies an 1D array row to y-th row of this ComplexImage. + * + * @param y + * number of row to modify + * @param row + * ComplexImage with one row containing the row to be placed + */ + + public void putRow(int y, ComplexImage row) { + System.arraycopy(row.real, 0, real, y * nx, nx); + if ((!(imag == null)) && (!(row.imag == null))) { + System.arraycopy(row.imag, 0, imag, y * nx, nx); + } + } + + /** + * Creates a new ComplexImage object containing the chosen column of this + * ComplexImage. + * + * @param x + * number of column to be copied + * @return ComplexImage containing the chosen column of this ComplexImage + */ + + public ComplexImage getColumn(int x) { + ComplexImage column = new ComplexImage(ny, 1, imag == null); + if (imag == null) { + for (int y = 0, n = x; y < ny; y++) { + column.real[y] = real[n]; + n += nx; + } + } + else { + for (int y = 0, n = x; y < ny; y++) { + column.real[y] = real[n]; + column.imag[y] = imag[n]; + n += nx; + } + } + return column; + } + + /** + * Copies the content of the chosen column of image to this ComplexImage. + * + * @param image + * the ComplexImage to copy from + * @param x + * the number of column to be copied + */ + + public void getColumnContent(int x, ComplexImage image) { + nx = 1; + ny = image.ny; + if ((image.imag == null) || (imag == null)) { + for (int y = 0, n = x; y < image.ny; y++) { + real[y] = image.real[n]; + n += image.nx; + } + } + else { + for (int y = 0, n = x; y < image.ny; y++) { + real[y] = image.real[n]; + imag[y] = image.imag[n]; + n += image.nx; + } + } + } + + /** + * Copies an 1D array column to x-th column of this ComplexImage. + * + * @param x + * number of column to modify + * @param column + * ComplexImage with one column containing the column to be + * placed + */ + + public void putColumn(int x, ComplexImage column) { + if ((!(imag == null)) && (!(column.imag == null))) { + for (int y = 0, n = x; y < ny; y++) { + real[n] = column.real[y]; + imag[n] = column.imag[y]; + n += nx; + } + } + else { + for (int y = 0, n = x; y < ny; y++) { + real[n] = column.real[y]; + n += nx; + } + } + } + + /** + * Creates a new ComplexImage object containing the subimage of this + * ComplexImage. + * + * @param x1 + * starting x coordinate within this ComplexImage + * @param x2 + * end x coordinate within this ComplexImage + * @param y1 + * starting y coordinate within this ComplexImage + * @param y2 + * end y coordinate within this ComplexImage + * @return the subimage + */ + + public ComplexImage getSubimage(int x1, int x2, int y1, int y2) { + ComplexImage sub = new ComplexImage(x2 - x1 + 1, y2 - y1 + 1, imag == null); + int d = x1 + y1 * nx; + if (imag == null) { + for (int y = 0; y < sub.ny; y++) { + System.arraycopy(real, d + y * nx, sub.real, y * sub.nx, sub.nx); + } + + } + else { + for (int y = 0; y < sub.ny; y++) { + System.arraycopy(real, d + y * nx, sub.real, y * sub.nx, sub.nx); + System.arraycopy(imag, d + y * nx, sub.imag, y * sub.nx, sub.nx); + } + } + return (sub); + } + + /** + * Copies the content of a subimage of image to this ComplexImage. Gives the + * same result as getSubimage, but does not create a new object. Total + * number of pixels assigned to this ComplexImage when created has to be + * sufficient for the subimage. + * + * @param x1 + * starting x coordinate within image + * @param x2 + * end x coordinate within image + * @param y1 + * starting y coordinate within image + * @param y2 + * end y coordinate within image + * @param image + * the image to copy + */ + + public void getSubimageContent(int x1, int x2, int y1, int y2, ComplexImage image) { + int d = x1 + y1 * image.nx; + nx = x2 - x1 + 1; + ny = y2 - y1 + 1; + nxy = nx * ny; + if ((imag == null) || (image.imag == null)) { + for (int y = 0; y < ny; y++) { + System.arraycopy(image.real, d + y * image.nx, real, y * nx, nx); + } + } + else { + for (int y = 0; y < ny; y++) { + System.arraycopy(image.real, d + y * image.nx, real, y * nx, nx); + System.arraycopy(image.imag, d + y * image.nx, imag, y * nx, nx); + } + } + } + + /** + * Copies the ComplexImage sub to the position in this ComplexImage given by + * its upper left corner. + * + * @param sub + * the image to copy + * @param x1 + * starting x coordinate + * @param y1 + * starting y coordinate + */ + + public void putSubimage(int x1, int y1, ComplexImage sub) { + int k; + int k1; + int d = x1 + y1 * nx; + if (sub.imag == null) { + for (int y = 0; y < sub.ny; y++) { + System.arraycopy(sub.real, y * sub.nx, real, d + y * nx, sub.nx); + } + } + else { + for (int y = 0; y < sub.ny; y++) { + System.arraycopy(sub.real, y * sub.nx, real, d + y * nx, sub.nx); + System.arraycopy(sub.imag, y * sub.nx, imag, d + y * nx, sub.nx); + } + } + } + + /** + * Creates a ComplexImage object as a copy of this ComplexImage. + * + * @return the copy of this ComplexImage + */ + + public ComplexImage copyImage() { + ComplexImage temp = null; + if (imag == null) { + temp = new ComplexImage(nx, ny, true); + System.arraycopy(real, 0, temp.real, 0, nxy); + } + else { + temp = new ComplexImage(nx, ny); + System.arraycopy(real, 0, temp.real, 0, nxy); + System.arraycopy(imag, 0, temp.imag, 0, nxy); + } + return temp; + } + + /** + * Copies the content of ComplexImage original to this ComplexImage. Gives + * the same result as copyImage, but does not create a new object. Total + * number of pixels assigned to this ComplexImage when created has to be + * sufficient for the original image. + * + * @param original + * the ComplexImage to copy + */ + + public void copyImageContent(ComplexImage original) { + nx = original.nx; + ny = original.ny; + nxy = original.nxy; + if ((original.imag == null) || (imag == null)) { + System.arraycopy(original.real, 0, real, 0, nxy); + } + else { + System.arraycopy(original.real, 0, real, 0, nxy); + System.arraycopy(original.imag, 0, imag, 0, nxy); + } + } + + /** + * Computes a square modulus of this ComplexImage. Puts a square modulus in + * the real part of this ComplexImage and zeros in the imaginary part if it + * exists. + */ + + public void squareModulus() { + if (imag == null) { + for (int i = 0; i < nxy; i++) { + real[i] = real[i] * real[i]; + } + } + else { + for (int i = 0; i < nxy; i++) { + real[i] = real[i] * real[i] + imag[i] * imag[i]; + imag[i] = 0.0; + } + } + } + + /** + * Computes a modulus of this ComplexImage. Puts a modulus in the real part + * of this ComplexImage and zeros in the imaginary part. + */ + + public void modulus() { + for (int k = 0; k < nxy; k++) { + real[k] = Math.sqrt(real[k] * real[k] + imag[k] * imag[k]); + imag[k] = 0.0; + } + } + + /** + * Computes the phase of this ComplexImage. Puts a phase in the real part of + * this ComplexImage and zeros in the imaginary part. + */ + + public void phase() { + for (int k = 0; k < nxy; k++) { + real[k] = Math.atan(imag[k] / real[k]); + if (real[k] < 0.0) { + real[k] += Math.PI; + } + imag[k] = 0.0; + } + } + + /** + * Adds a ComplexImage object of the same dimensions to this ComplexImage. + * + * @param im + * the ComplexImage to add + */ + + public void add(ComplexImage im) { + if (!(im.imag == null)) { // im is complex + if (imag == null) { + imag = new double[nxy]; + } + for (int k = 0; k < nxy; k++) { + real[k] += im.real[k]; + imag[k] += im.imag[k]; + } + } + else { // im is real + for (int k = 0; k < nxy; k++) { + real[k] += im.real[k]; + } + } + } + + /** + * Adds a real constant to every element in this ComplexImage. + * + * @param d + * the constant to add + */ + + public void add(double d) { + for (int k = 0; k < nxy; k++) { + real[k] += d; + } + } + + /** + * Substracts a ComplexImage of the same dimensions from this ComplexImage. + * + * @param im + * the ComplexImage to be substracted + */ + + public void subtract(ComplexImage im) { + if (!(im.imag == null)) { // im is complex + if (imag == null) { + imag = new double[nxy]; + } + for (int k = 0; k < nxy; k++) { + real[k] -= im.real[k]; + imag[k] -= im.imag[k]; + } + } + else { // im is real + for (int k = 0; k < nxy; k++) { + real[k] -= im.real[k]; + } + } + } + + /** + * Performs the complex conjugate on this ComplexImage. + */ + + public void conj() { + if (!(imag == null)) { + for (int k = 0; k < nxy; k++) { + imag[k] = -imag[k]; + } + } + } + + /** + * Multiplies each element in this ComplexImage with a given constant. + * + * @param constant + * the multiplication constant + */ + + public void multiply(double constant) { + if (imag == null) { + for (int k = 0; k < nxy; k++) { + real[k] *= constant; + } + } + else { + for (int k = 0; k < nxy; k++) { + real[k] *= constant; + imag[k] *= constant; + } + } + } + + /** + * Multiplies this complex image by a complex constant re+i*im. + * + * @param re + * real part of the complex constant + * @param im + * imaginary part of the complex constant + */ + + public void multiply(double re, double im) { + for (int k = 0; k < nxy; k++) { + double r = real[k]; + real[k] = re * real[k] - im * imag[k]; + imag[k] = re * imag[k] + im * r; + } + } + + /** + * Multiplies this ComplexImage with another ComplexImage of same + * dimensions, pointwise. + * + * @param im + * the ComplexImage to multiply with + */ + + public void multiply(ComplexImage im) { + if (!(im.imag == null)) { // im is complex + if (imag == null) { + imag = new double[nxy]; + } + for (int k = 0; k < nxy; k++) { + double re = real[k]; + real[k] = im.real[k] * re - im.imag[k] * imag[k]; + imag[k] = im.real[k] * imag[k] + im.imag[k] * re; + } + } + else { // im is real + if (imag == null) { + for (int k = 0; k < nxy; k++) { + real[k] *= im.real[k]; + } + } + else { + for (int k = 0; k < nxy; k++) { + real[k] *= im.real[k]; + imag[k] *= im.real[k]; + } + } + } + } + + /** + * Multiplies this ComplexImage by ComplexImage obtained by taking every + * l-th sample of circulary extended ComplexImage im. + * + * @param im + * the ComplexImage to multiply with + * @param l + * subsampling factor for im + */ + + public void multiplyCircular(ComplexImage im, int l) { + int l2 = l * l; + int k; + int t; + double ima; + double re; + int l2y; + if (!(im.imag == null)) { // im is complex + if (imag == null) { + imag = new double[nxy]; + } + for (int y = 0; y < ny; y++) { + l2y = ((l * y) % im.ny) * im.nx; + for (int x = 0; x < nx; x++) { // x,y-coordinates in the image + k = nx * y + x; + t = l2y + ((l * x) % im.nx); + re = real[k]; + ima = imag[k]; + real[k] = im.real[t] * re - im.imag[t] * ima; + imag[k] = im.real[t] * ima + im.imag[t] * re; + } + } + } + else { // im is real + if (imag == null) { + for (int y = 0; y < ny; y++) { + l2y = ((l * y) % im.ny) * im.nx; + for (int x = 0; x < nx; x++) { // x,y-coordinates in the + // image + k = nx * y + x; + t = l2y + ((l * x) % im.nx); + real[k] *= im.real[t]; + } + } + } + else { + for (int y = 0; y < ny; y++) { + l2y = ((l * y) % im.ny) * im.nx; + for (int x = 0; x < nx; x++) { // x,y-coordinates in the + // image + k = nx * y + x; + t = l2y + ((l * x) % im.nx); + re = real[k]; + ima = imag[k]; + real[k] *= im.real[t]; + imag[k] *= im.real[t]; + } + } + } + } + } + + /** + * Multiplies this ComplexImage pointwise with ComplexImage obtained by + * taking every l-th sample of another ComplexImage im along each dimension. + * Dimensions of im have to be bigger or equal to dimensions of the + * ComplexImage multiplied by l. + * + * @param im + * the ComplexImage to multiply with + * @param l + * subsampling factor for im + */ + + public void multiply(ComplexImage im, int l) { + if (l == 1) { + multiply(im); + } + else { + int l2 = l * l; + double ima; + double re; + int d = l * im.nx; + if (!(im.imag == null)) { // im is complex + if (imag == null) { + imag = new double[nxy]; + } + for (int y = 0, l2y = 0; y < ny; y++, l2y += d) { + for (int t = l2y, k = nx * y, end = nx * y + nx; k < end; t += l, k++) { // x,y-coordinates + // in + // the + // image + re = real[k]; + real[k] = im.real[t] * re - im.imag[t] * imag[k]; + imag[k] = im.real[t] * imag[k] + im.imag[t] * re; + } + } + } + else { // im is real + if (imag == null) { + for (int y = 0, l2y = 0; y < ny; y++, l2y += d) { + for (int t = l2y, k = nx * y, end = nx * y + nx; k < end; t += l, k++) { // x,y-coordinates + // in + // the + // image + real[k] *= im.real[t]; + } + } + } + else { + for (int y = 0, l2y = 0; y < ny; y++, l2y += d) { + for (int t = l2y, k = nx * y, end = nx * y + nx; k < end; t += l, k++) { // x,y-coordinates + // in + // the + // image + real[k] *= im.real[t]; + imag[k] *= im.real[t]; + } + } + } + } + } + } + + /** + * Divides this ComplexImage by another ComplexImage im of same dimensions, + * pointwise. Where both real and imaginary part of im are smaller then + * 10^-30 result is given by cr+i*cim. + * + * @param im + * the ComplexImage to divide by + * @param cr + * the real part of the result if division by zero + * @param cim + * the imaginary part of the result if division by zero + */ + + public void divide(ComplexImage im, double cr, double cim) { + double ima; + double rea; + double eps = 1E-30; + if (!(im.imag == null)) { // im is complex + if (imag == null) { + imag = new double[nxy]; + } + for (int k = 0; k < nxy; k++) { + if ((Math.abs(im.real[k]) < eps) && (Math.abs(im.imag[k]) < eps)) { + real[k] = cr; + imag[k] = cim; + } + else { + rea = real[k]; + ima = imag[k]; + real[k] = (rea * im.real[k] + ima * im.imag[k]) / (im.real[k] * im.real[k] + im.imag[k] * im.imag[k]); + imag[k] = (ima * im.real[k] - rea * im.imag[k]) / (im.real[k] * im.real[k] + im.imag[k] * im.imag[k]); + } + } + } + else { // im is real + if (imag == null) { // divide real by real + for (int k = 0; k < nxy; k++) { + if ((Math.abs(im.real[k]) < eps)) { + real[k] = cr; + } + else { + real[k] /= im.real[k]; + } + } + } + else { // divide complex by real + for (int k = 0; k < nxy; k++) { + if ((Math.abs(im.real[k]) < eps)) { + real[k] = cr; + imag[k] = cim; + } + else { + real[k] /= im.real[k]; + imag[k] /= im.real[k]; + } + } + } + } + } + + /** + * Divides this ComplexImage by another ComplexImage im of the same + * dimensions, pointwise. Does not check for division by zero. + * + * @param im + * the ComplexImage to divide by + */ + + public void divide(ComplexImage im) { + if (!(im.imag == null)) { // im is complex + if (imag == null) { + imag = new double[nxy]; + } + for (int k = 0; k < nxy; k++) { + double rea = real[k]; + double d = (im.real[k] * im.real[k] + im.imag[k] * im.imag[k]); + real[k] = (rea * im.real[k] + imag[k] * im.imag[k]) / d; + imag[k] = (imag[k] * im.real[k] - rea * im.imag[k]) / d; + } + } + else { // im is real + if (imag == null) { // divide real by real + for (int k = 0; k < nxy; k++) { + real[k] /= im.real[k]; + } + } + else { // divide complex by real + for (int k = 0; k < nxy; k++) { + real[k] /= im.real[k]; + imag[k] /= im.real[k]; + } + } + } + } + + /** + * Computes the square root of each element of the real part of this + * ComplexImage and puts it in the real part of this ComplexImage. + */ + + public void rootReal() { + for (int k = 0; k < nxy; k++) { + real[k] = Math.sqrt(real[k]); + } + } + + /** + * Returns the median of the real part of this ComplexImage. + * + * @return median of the real part of this ComplexImage + */ + + public double median() { + ComplexImage temp = copyImage(); + java.util.Arrays.sort(temp.real); + double m = temp.real[nxy / 2]; + return m; + } + + /** + * Returns the median absolute deviation of the real part of this + * ComplexImage. + * + * @return median absolute deviation of the real part of this ComplexImage + */ + + public double mad() { + double m = median(); + ComplexImage temp = copyImage(); + temp.add(-m); + for (int x = 0; x < nxy; x++) { + temp.real[x] = Math.abs(temp.real[x]); + } + double md = temp.median(); + return md; + } + + /** + * Rises each element of the real part of this ComplexImage to the power of + * exp. + * + * @param exp + * exponent + */ + + public void powerReal(double exp) { + for (int i = 0; i < nxy; i++) { + real[i] = Math.pow(real[i], exp); + } + } + + /** + * Returns the mean value of the real part of this ComplexImage. + * + * @return the mean of the real part of this ComplexImage + */ + + public double meanReal() { + double d = 0.0; + for (int k = 0; k < nxy; k++) { + d += real[k]; + } + d /= nxy; + return d; + } + + /** + * Returns the mean of the real part of this ComplexImage inside the mask + * which is defined by real(ma)=val. + * + * @param ma + * mask + * @param val + * defines the mask foreground + * @return the mean value of real part of this ComplexImage inside the mask + */ + + public double meanMask(int[] ma, int val) { + double cnt = 0; + double s = 0; + for (int k = 0; k < nxy; k++) { + if (ma[k] == val) { + cnt += 1.0; + s += real[k]; + } + } + s /= cnt; + return s; + } + + /** + * Returns the mean value of this ComplexImage modulus. + * + * @return mean of this ComplexImage modulus + */ + + public double meanModulus() { + double d = 0.0; + if (imag == null) { + for (int k = 0; k < nxy; k++) { + d += Math.abs(real[k]); + } + } + else { + for (int k = 0; k < nxy; k++) { + d += Math.pow(real[k] * real[k] + imag[k] * imag[k], 0.5); + } + } + d /= (nxy); + return d; + } + + /** + * Computes the sum of the real part of this ComplexImage. + * + * @return the sum of the real part of this ComplexImage + */ + + public double sumReal() { + double d = 0.0; + for (int k = 0; k < nxy; k++) { + d += real[k]; + } + return d; + } + + /** + * Returns the maximum absolute value of the real part of this ComplexImage. + * + * @return the maximum absolute value of the real part of this ComplexImage + */ + + public double maxAbsReal() { + double max = real[0]; + double min = real[0]; + for (int k = 0; k < nxy; k++) { + if (real[k] > max) { + max = real[k]; + } + else { + if (real[k] < min) { + min = real[k]; + } + } + } + max = Math.abs(max); + min = Math.abs(min); + if (min > max) { + max = min; + } + return max; + } + + /** + * Returns the maximum value of the real part of this ComplexImage. + * + * @return the maximum value of the real part of this ComplexImage + */ + + public double max() { + double m = real[0]; + for (int k = 0; k < nxy; k++) { + if (real[k] > m) { + m = real[k]; + } + } + return m; + } + + /** + * Returns the minimum value of the real part of this ComplexImage. + * + * @return the minimum value of the real part of this ComplexImage + */ + + public double min() { + double m = real[0]; + for (int k = 0; k < nxy; k++) { + if (real[k] < m) { + m = real[k]; + } + } + return m; + } + + /** + * Returns the standard deviation of the real part of this ComplexImage. + * + * @return the standard deviation of the real part of this ComplexImage + */ + + public double deviation() { + double m = meanReal(); + double s = 0; + for (int k = 0; k < nxy; k++) { + double d = real[k] - m; + s += (d * d); + } + s /= nxy; + s = Math.sqrt(s); + return s; + } + + /** + * Performs the 2D Fast Fourier Transform on this ComplexImage. + */ + + public void FFT2D() { + // perform FFT1D for each row + FFT1D FFTrow = new FFT1D(nx); + ComplexImage row = new ComplexImage(nx, 1); + for (int y = 0; y < ny; y++) { + row.getRowContent(y, this); + FFTrow.transform(row.real, row.imag, nx, 0); + putRow(y, row); + } + // perform FFT1D for each column + ComplexImage column = new ComplexImage(1, ny); + FFT1D FFTcolumn = new FFT1D(ny); + for (int x = 0; x < nx; x++) { + column.getColumnContent(x, this); + FFTcolumn.transform(column.real, column.imag, ny, 0); + putColumn(x, column); + } + } + + /** + * Performs the 2D inverse Fast Fourier Transform on this ComplexImage. + */ + + public void iFFT2D() { + // perform iFFT1D for each row + ComplexImage row = new ComplexImage(nx, 1); + FFT1D FFTrow = new FFT1D(nx); + for (int y = 0; y < ny; y++) { + row.getRowContent(y, this); + FFTrow.inverse(row.real, row.imag, nx, 0); + putRow(y, row); + } + // perform iFFT1D for each column + ComplexImage column = new ComplexImage(1, ny); + FFT1D FFTcolumn = new FFT1D(ny); + for (int x = 0; x < nx; x++) { + column.getColumnContent(x, this); + FFTcolumn.inverse(column.real, column.imag, ny, 0); + putColumn(x, column); + } + } + + /** + * Exchanges quadrants of this ComplexImage 1 <-> 3, 2 <-> 4. The quadrants + * are defined as follows: <br> + * 1 | 2 <br> + * ----- <br> + * 4 | 3 <br> + */ + + public void shift() { + double p; + int q1; + int q2; + int q3; + int q4; + int nxy2 = nxy / 2; + int nx2 = nx / 2; + if (imag == null) { + for (int y = 0; y < ny / 2; y++) { + int ynx = nx * y; + for (int x = 0; x < nx2; x++) { + q1 = ynx + x; + q2 = q1 + nx2; + q4 = q1 + nxy2; + q3 = q4 + nx2; + p = real[q1]; + real[q1] = real[q3]; + real[q3] = p; + p = real[q2]; + real[q2] = real[q4]; + real[q4] = p; + } + } + } + else { + for (int y = 0; y < ny / 2; y++) { + int ynx = nx * y; + for (int x = 0; x < nx2; x++) { + q1 = ynx + x; + q2 = q1 + nx2; + q4 = q1 + nxy2; + q3 = q4 + nx2; + p = real[q1]; + real[q1] = real[q3]; + real[q3] = p; + p = real[q2]; + real[q2] = real[q4]; + real[q4] = p; + p = imag[q1]; + imag[q1] = imag[q3]; + imag[q3] = p; + p = imag[q2]; + imag[q2] = imag[q4]; + imag[q4] = p; + } + } + } + } + + /** + * Exchanges quadrants of this ComplexImage 1 <-> 2, 3 <-> 4. The quadrants + * are defined as follows: <br> + * 1 | 2 <br> + * ----- <br> + * 4 | 3 <br> + */ + + public void shiftX() { + double p; + int q1; + int q2; + int nx2 = nx / 2; + if (imag == null) { + for (int y = 0; y < ny; y++) { + int ynx = nx * y; + for (int x = 0; x < nx2; x++) { + q1 = ynx + x; + q2 = q1 + nx2; + p = real[q1]; + real[q1] = real[q2]; + real[q2] = p; + } + } + } + else { + for (int y = 0; y < ny; y++) { + int ynx = nx * y; + for (int x = 0; x < nx2; x++) { + q1 = ynx + x; + q2 = q1 + nx2; + p = real[q1]; + real[q1] = real[q2]; + real[q2] = p; + p = imag[q1]; + imag[q1] = imag[q2]; + imag[q2] = p; + } + } + } + } + + /** + * Exchanges quadrants of this ComplexImage 1 <-> 4, 2 <-> 3. The quadrants + * are defined as follows: <br> + * 1 | 2 <br> + * ----- <br> + * 4 | 3 <br> + */ + + public void shiftY() { + final int halfim = nxy / 2; + double p; + if (imag == null) { + for (int k = 0; k < halfim; k++) { + p = real[k]; + real[k] = real[k + halfim]; + real[k + halfim] = p; + } + } + else { + for (int k = 0; k < halfim; k++) { + p = real[k]; + real[k] = real[k + halfim]; + real[k + halfim] = p; + p = imag[k]; + imag[k] = imag[k + halfim]; + imag[k + halfim] = p; + } + } + } + + /** + * Shifts this ComplexImage right by shiftx and down by shifty. + * + * @param shiftx + * shift to the right + * @param shifty + * shift down + */ + + public ComplexImage circShift(int shiftx, int shifty) { + while (shiftx < 0) { + shiftx = nx + shiftx; + } + while (shifty < 0) { + shifty = ny + shifty; + } + while (shiftx > (nx - 1)) { + shiftx = shiftx - nx; + } + while (shifty > (ny - 1)) { + shifty = shifty - ny; + } + ComplexImage res = new ComplexImage(nx, ny); + ComplexImage temp = getSubimage(0, nx - shiftx - 1, 0, ny - shifty - 1); + res.putSubimage(shiftx, shifty, temp); + temp = getSubimage(nx - shiftx, nx - 1, ny - shifty, ny - 1); + res.putSubimage(0, 0, temp); + temp = getSubimage(0, nx - shiftx - 1, ny - shifty, ny - 1); + res.putSubimage(shiftx, 0, temp); + temp = getSubimage(nx - shiftx, nx - 1, 0, ny - shifty - 1); + res.putSubimage(0, shifty, temp); + return res; + } + + /** + * Performs quincunx downsampling followed by upsampling in Fourier domain + * on this ComplexImage. Sums the first quadrant with the third and the + * second with the forth. <br> + * 1 | 2 <br> + * ----- <br> + * 4 | 3 <br> + */ + + public void quincunxDownUp() { + int nx2 = nx / 2; + int ny2 = ny / 2; + int nxy2 = nxy / 2; + for (int y = 0; y < nxy2; y += nx) { + for (int q1 = y, end = q1 + nx2; q1 < end; q1++) { + int q2 = q1 + nx2; + int q4 = q1 + nxy2; + int q3 = q4 + nx2; + double r = real[q1] + real[q3]; + double im = imag[q1] + imag[q3]; + real[q1] = real[q3] = r; + imag[q1] = imag[q3] = im; + r = real[q2] + real[q4]; + im = imag[q2] + imag[q4]; + real[q2] = real[q4] = r; + imag[q2] = imag[q4] = im; + } + } + } + + /** + * Down and upsampling in Y direction Sums the first quadrant with the forth + * and the third with the third. <br> + * 1 | 2 <br> + * ----- <br> + * 4 | 3 <br> + */ + + public void downUpY() { + int nxy2 = nxy / 2; + for (int q1 = 0; q1 < nxy2; q1++) { + int q2 = q1 + nxy2; + double r = real[q1] + real[q2]; + double im = imag[q1] + imag[q2]; + real[q1] = real[q2] = r; + imag[q1] = imag[q2] = im; + } + } + + /** + * Performs dyadic downsampling followed by upsampling in Fourier domain on + * this ComplexImage. Sums the four quadrants pointwise and places the sum + * in each quadrant. + */ + + public void dyadicDownUp() { + int nx2 = nx / 2; + int ny2 = ny / 2; + int nxy2 = nxy / 2; + for (int y = 0; y < nxy2; y += nx) { + for (int q1 = y, end = q1 + nx2; q1 < end; q1++) { + int q2 = q1 + nx2; + int q3 = q1 + nxy2; + int q4 = q3 + nx2; + double r = real[q1] + real[q2] + real[q3] + real[q4]; + real[q1] = real[q2] = real[q3] = real[q4] = r; + double im = imag[q1] + imag[q2] + imag[q3] + imag[q4]; + imag[q1] = imag[q2] = imag[q3] = imag[q4] = im; + } + } + } + + /** + * Sums the four quadrants of this ComplexImage pointwise and reduces its + * size by 2 along each dimension. + */ + + public void dyadicDownUpCrop() { + int nx2 = nx / 2; + int ny2 = ny / 2; + int nxy2 = nxy / 2; + int ind = 0; + for (int y = 0; y < nxy2; y += nx) { + for (int q1 = y, end = q1 + nx2; q1 < end; q1++) { + int q2 = q1 + nx2; + int q3 = q1 + nxy2; + int q4 = q3 + nx2; + double r = real[q1] + real[q2] + real[q3] + real[q4]; + real[ind] = r; + double im = imag[q1] + imag[q2] + imag[q3] + imag[q4]; + imag[ind++] = im; + } + } + nx = nx2; + ny = ny2; + nxy /= 4; + } + + /** + * Sums the lower half of this ComplexImage to the upper half, pointwise. + * Keeps only the upper half. + */ + + public void dyadicDownY() { + ComplexImage temp = getSubimage(0, nx - 1, 0, ny / 2 - 1); + ComplexImage temp1 = getSubimage(0, nx - 1, ny / 2, ny - 1); + temp1.add(temp); + putSubimage(0, 0, temp1); + ny = ny / 2; + nxy /= 2; + } + + /** + * Subsamples this ComplexImage by 2x2, reducing its size by 2 along each + * dimension. + */ + + public void decimateCrop() { + int nx2 = nx / 2; + int ny2 = ny / 2; + if (imag == null) { + for (int y = 0; y < ny2; y++) { + for (int x = 0, k = 2 * nx * y, k1 = nx2 * y; x < nx2; x++, k += 2, k1++) { + real[k1] = real[k]; + } + } + } + else { + for (int y = 0; y < ny2; y++) { + for (int x = 0, k = 2 * nx * y, k1 = nx2 * y; x < nx2; x++, k += 2, k1++) { + real[k1] = real[k]; + imag[k1] = imag[k]; + } + } + } + nx /= 2; + ny /= 2; + nxy /= 4; + } + + /** + * Subsamples this ComplexImage by 2x2, circularily, while keeping its size + * unchanged. + */ + + public void decimate() { + ComplexImage temp = copyImage(); + if (imag == null) { + for (int l = 0, y = 0; l < nxy; l += nx, y += 2) { + if (y >= ny) { + y -= ny; + } + for (int k = l, x = 0; k < l + nx; k++, x += 2) { + if (x >= nx) { + x -= nx; + } + int k1 = y * nx + x; + real[k] = temp.real[k1]; + } + } + } + else { + for (int l = 0, y = 0; l < nxy; l += nx, y += 2) { + if (y >= ny) { + y -= ny; + } + for (int k = l, x = 0; k < l + nx; k++, x += 2) { + if (x >= nx) { + x -= nx; + } + int k1 = y * nx + x; + real[k] = temp.real[k1]; + imag[k] = temp.imag[k1]; + } + } + } + } + + /** + * Substitutes the 2k-th and the 2k+1-th column of this ComplexImage by + * their sum, for each integer k. The number of columns of the ComplexImage + * is reduced by two. + */ + + public void fold() { + int nxy2 = nxy / 2; + for (int k = 0; k < nxy2; k++) { + real[k] = real[2 * k] + real[2 * k + 1]; + imag[k] = imag[2 * k] + imag[2 * k + 1]; + } + nx /= 2; + nxy /= 2; + } + + /** + * Substitutes each column of this ComplexImage by two columns. Each of them + * contains the even (odd) samples from the initial column and the odd + * (even) positions contain zeros. The number of columns of the ComplexImage + * is increased by two. + */ + + public void unfold() { + double[] real1 = new double[2 * nxy]; + double[] imag1 = new double[2 * nxy]; + for (int k = 0; k < 2 * nxy; k++) + real1[k] = imag1[k] = 0; + for (int k = 0; k < nx * ny; k++) { + if (k % (2 * nx) < nx) { // odd row + real1[2 * k] = real[k]; + imag1[2 * k] = imag[k]; + } + else { + real1[2 * k + 1] = real[k]; + imag1[2 * k + 1] = imag[k]; + } + } + real = real1; + imag = imag1; + nx = nx * 2; + nxy *= 2; + } + + /** + * Extends this ComplexImage circularily to double its size along each + * direction. <br> + */ + + public void dyadicUpsample() { + int index; + int q1; + int q2; + int q3; + int q4; + int nx2 = 2 * nx; + int nxy2 = 2 * nxy; + double r; + double i; + if (real.length < 4 * nxy) { + double[] re = new double[4 * nxy]; + System.arraycopy(real, 0, re, 0, nxy); + real = re; + } + if (imag.length < 4 * nxy) { + double[] im = new double[4 * nxy]; + System.arraycopy(imag, 0, im, 0, nxy); + imag = im; + } + for (int y = ny - 1; y >= 0; y--) { + int ynx = y * nx; + int ynx2 = 2 * ynx; + for (int x = nx - 1; x >= 0; x--) { + index = ynx + x; + r = real[index]; + i = imag[index]; + q1 = ynx2 + x; + real[q1] = r; // First quadrant + imag[q1] = i; + q2 = q1 + nx; + real[q2] = r; // Second quadrant + imag[q2] = i; + q3 = q1 + nxy2; + real[q3] = r; // Third quadrant + imag[q3] = i; + q4 = q3 + nx; + real[q4] = r; // Forth quadrant + imag[q4] = i; + } + } + nx *= 2; + ny *= 2; + nxy *= 4; + } + + /** + * Multiplies this ComplexImage by e^ix, with x=2*pi*kx/nx, where kx is the + * column index. + */ + + public void modulatePlusX() { + if (imag == null) { + imag = new double[nxy]; + } + int index; + double x; + double c; + double s; + double re; + double im; + for (int k = 1; k < nx; k++) { + x = PI2 * (double) k / (double) nx; + c = Math.cos(x); + s = Math.sin(x); + for (int l = 0; l < ny; l++) { + index = l * nx + k; + re = real[index]; + im = imag[index]; + real[index] = c * re - s * im; + imag[index] = s * re + c * im; + } + } + } + + /** + * Multiplies this ComplexImage by e^-ix, with x=2*pi*kx/nx, where kx is the + * column index. + */ + + public void modulateMinusX() { + if (imag == null) { + imag = new double[nxy]; + } + int index; + double x; + double c; + double s; + double re; + double im; + for (int k = 1; k < nx; k++) { + x = (double) k * PI2 / (double) nx; + c = Math.cos(x); + s = Math.sin(x); + for (int l = 0; l < ny; l++) { + index = l * nx + k; + re = real[index]; + im = imag[index]; + real[index] = c * re + s * im; + imag[index] = c * im - s * re; + } + } + } + + /** + * Multiplies this ComplexImage by e^iy, with y=2*pi*ky/ny, where ky is the + * row index. + */ + + public void modulatePlusY() { + if (imag == null) { + imag = new double[nxy]; + } + int index; + double y; + double c; + double s; + double re; + double im; + int knx; + for (int k = 1; k < ny; k++) { + y = PI2 * (double) k / (double) ny; + c = Math.cos(y); + s = Math.sin(y); + knx = k * nx; + for (int l = 0; l < nx; l++) { + index = knx + l; + re = real[index]; + im = imag[index]; + real[index] = c * re - s * im; + imag[index] = s * re + c * im; + } + } + } + + /** + * Multiplies this ComplexImage by e^-iy, with y=2*pi*ky/ny, where ky is the + * row index. + */ + + public void modulateMinusY() { + if (imag == null) { + imag = new double[nxy]; + } + int index; + double y; + double c; + double s; + double re; + double im; + int knx; + for (int k = 1; k < ny; k++) { + y = PI2 * (double) k / (double) ny; + c = Math.cos(y); + s = Math.sin(y); + knx = k * nx; + for (int l = 0; l < nx; l++) { + index = knx + l; + re = real[index]; + im = imag[index]; + real[index] = c * re + s * im; + imag[index] = c * im - s * re; + } + } + } + + /** + * Multiplies this ComplexImage by e^i(x+y), with x=2*pi*kx/nx, where kx is + * the column index, and y=2*pi*ky/ny, where ky is the row index. + */ + + public void modulatePlusQuincunx() { + if (imag == null) { + imag = new double[nxy]; + } + int index; + double x; + double c; + double s; + double re; + double im; + for (int k = 0; k < nx; k++) { + for (int l = 0; l < ny; l++) { + x = PI2 * ((double) k / (double) nx + (double) l / (double) ny); + c = Math.cos(x); + s = Math.sin(x); + index = l * nx + k; + re = real[index]; + im = imag[index]; + real[index] = c * re - s * im; + imag[index] = s * re + c * im; + } + } + } + + /** + * Multiplies this ComplexImage by e^-i(x+y), with x=2*pi*kx/nx, where kx is + * the column index, and y=2*pi*ky/ny, where ky is the row index. + */ + + public void modulateMinusQuincunx() { + if (imag == null) { + imag = new double[nxy]; + } + int index; + double x; + double c; + double s; + double re; + double im; + for (int k = 0; k < nx; k++) { + for (int l = 0; l < ny; l++) { + x = PI2 * ((double) k / (double) nx + (double) l / (double) ny); + c = Math.cos(x); + s = Math.sin(x); + index = l * nx + k; + re = real[index]; + im = imag[index]; + real[index] = c * re + s * im; + imag[index] = c * im - s * re; + } + } + } + + /** + * Returns this ComplexImage rotated by 45 degrees clockwise. Only the + * ComplexImage samples on the quincunx grid are kept, the ComplexImage is + * rotated so that the remaining samples are all in the same region, and the + * rest of the output ComplexImage is filled by the background. Size of + * rotated image is bigger or equal to image size before rotation + * + * @param back + * the background color to be used. + * @return the rotated ComplexImage + */ + + public ComplexImage rotate(double back) { + double s1 = 0; + double s0 = 0; + int k = 0; + int i = 1; + for (int y = 0; y < nxy; y += nx) { + for (int ind = y + k, end = y + nx; ind < end; ind += 2) { + s0 += Math.abs(real[ind]); + s1 += Math.abs(real[ind + i]); + } + k = 1 - k; + i = -i; + } + k = (s0 < s1) ? 1 : 0; + int s = (nx + ny) / 2; + ComplexImage rot = new ComplexImage(s, s); + rot.settoConstant(back, back); + for (int y = 0; y < ny; y++) { + for (int x = k, ind = y * nx + k; x < nx; x += 2, ind += 2) { + int x1 = (x - y + ny - 1) / 2; + int y1 = (x + y) / 2; + rot.real[rot.nx * y1 + x1] = real[ind]; + rot.imag[rot.nx * y1 + x1] = imag[ind]; + } + k = 1 - k; + } + return rot; + } + + /** + * Rotates this ComplexImage back, anticlockwise by 45 degrees. After + * applying the rotate operation followed by the unrotate, only the samples + * on the quincunx grid are kept. + * + * @param kx + * the number of rows in the unrotated ComplexImage + * @param ky + * the number of columns in the unrotated ComplexImage + */ + + public void unrotate(int kx, int ky) { + int kxy = kx * ky; + int nx1 = nx; + int ny1 = ny; + double[] re = new double[kxy]; + double[] im = new double[kxy]; + nx = kx; + ny = ky; + nxy = nx * ny; + int k = 0; + for (int y = 0; y < ky; y++) { + for (int x = k, ind = kx * y + k; x < kx; x += 2, ind += 2) { + int x1 = (x - y + ky - 1) / 2; + int y1 = (x + y) / 2; + re[ind] = real[nx1 * y1 + x1]; + im[ind] = imag[nx1 * y1 + x1]; + } + k = 1 - k; + } + System.arraycopy(re, 0, real, 0, kxy); + System.arraycopy(im, 0, imag, 0, kxy); + } + + /** + * Places the ComplexImage original extended by its first row and first + * column in this ComplexImage. + * + * @param original + * the image to extend + */ + + public void extend(ComplexImage original) { + putSubimage(0, 0, original); + for (int x = 0; x < original.nx; x++) { + real[(original.nx + 1) * original.ny + x] = real[x]; + } + for (int y = 0; y < original.ny + 1; y++) { + real[(original.nx + 1) * y + original.nx] = real[(original.nx + 1) * y]; + } + } + + /** + * Normalizes the modulus of this ComplexImage so that all values are in the + * range (0,250). Does not modify the background given by the value 255.0 in + * the real part. + */ + + public void stretch() { + double max = 250.0; + double back = 255.0; + ComplexImage mod = copyImage(); + if (imag == null) { + double maximage = mod.maxAbsReal(); + double sp = max / maximage; + for (int i = 0; i < nxy; i++) { + if (real[i] != back) { + real[i] *= sp; + } + } + } + else { + mod.modulus(); + double maximage = mod.max(); + double sp = max / maximage; + for (int i = 0; i < nxy; i++) { + if (real[i] != back) { + real[i] *= sp; + imag[i] *= sp; + } + } + } + } + + /** + * Stretches each subband of the nonredundant quincunx transform in this + * ComplexImage so that all values are between -250 and 250. + * + * @param J + * number of decomposition levels + */ + + void displayQuincunxNonredundant(int J) { + int dx = nx; + int dy = ny; + for (int j = 1; j <= J; j++) { + ComplexImage sub; + if (j % 2 == 1) { // Odd iteration + sub = getSubimage(dx / 2, dx - 1, 0, dy - 1); + sub.stretch(); + putSubimage(dx / 2, 0, sub); + dx /= 2; + } + else { + sub = getSubimage(0, dx - 1, dy / 2, dy - 1); + sub.stretch(); + putSubimage(0, dy / 2, sub); + dy /= 2; + } + } + } + + /** + * Puts a frame of the given color around the real part of this + * ComplexImage. + * + * @param color + * the frame color + */ + + public void frame(double color) { + for (int k = 0, nxy1 = nxy - 1; k < nx; k++) { + real[k] = real[nxy1 - k] = color; + } + for (int k = 1; k < ny; k++) { + real[k * nx] = real[k * nx - 1] = color; + } + } + + /** + * Puts the frames of given colors around both the real and the complex part + * of this ComplexImage. + * + * @param colorr + * the frame color for the real part + * @param colori + * the frame color for the complex part + */ + + public void frame(double colorr, double colori) { + for (int k = 0, nxy1 = nxy - 1; k < nx; k++) { + real[k] = real[nxy1 - k] = colorr; + imag[k] = imag[nxy1 - k] = colori; + } + for (int k = 1; k < ny; k++) { + real[k * nx] = real[k * nx - 1] = colorr; + imag[k * nx] = imag[k * nx - 1] = colori; + } + } + + /** + * Extends this ComplexImage by adding zero rows and columns around the + * edges. + */ + + public void extendWithZeros() { + ComplexImage temp = new ComplexImage(nx + 2, ny + 2); + ComplexImage temp1 = copyImage(); + temp.putSubimage(1, 1, temp1); + real = temp.real; + imag = temp.imag; + nx += 2; + ny += 2; + nxy = nx * ny; + } + + /** + * Removes the first and the last row and coulumn of this ComplexImage. + */ + + public void reduce() { + ComplexImage temp = getSubimage(1, nx - 2, 1, ny - 2); + real = temp.real; + imag = temp.imag; + nx -= 2; + ny -= 2; + nxy = nx * ny; + } + + /** + * Sets this ComplexImage value to 1 where it is different from 0. + */ + + public void createMap() { + for (int i = 0; i < nxy; i++) { + if (!(real[i] == 0.0)) { + real[i] = 1.0; + } + } + } + + /** + * Implements soft threshold on this ComplexImage. Where the modulus of the + * ComplexImage is bigger then t it is reduced by t while the phase of the + * ComplexImage remains unchanged. Elsewhere, the value is set to zero. + * + * @param t + * threshold + */ + + public void softThreshold(double t) { + double t2 = t * t; + for (int k = 0; k < nxy; k++) { + if ((real[k] * real[k] + imag[k] * imag[k]) < t2) { + real[k] = imag[k] = 0; + } + else { + double r = real[k]; + double im = imag[k]; + double m = Math.sqrt(r * r + im * im); + real[k] -= r / m; + imag[k] -= im / m; + } + } + } + + /** + * Implements hard threshold on this ComplexImage. Where the modulus of the + * ComplexImage is smaler then t the value it is set to zero. + * + * @param t + * the threshold + */ + + public void hardThreshold(double t) { + double t2 = t * t; + for (int k = 0; k < nxy; k++) { + if ((real[k] * real[k] + imag[k] * imag[k]) < t2) { + real[k] = imag[k] = 0.0; + } + } + } + + /** + * Sets the real part of this ComplexImage to max where it is higher then + * max and to min where it is smaller then min. + * + * @param min + * the lower limit + * @param max + * the upper limit + */ + + public void limitImage(double min, double max) { + for (int i = 0; i < nxy; i++) { + if (real[i] > max) { + real[i] = max; + } + else { + if (real[i] < min) { + real[i] = min; + } + } + } + } + + /* + * Searches for neighbouring pixels to include in the zerocrossings map + */ + + private void search8(int x, int y) { + if ((x < nx) && (x >= 0) && (y < ny) && (y >= 0)) { + int i = y * nx + x; + if (real[i] == 1.0) { + real[i] = 3.0; + search8(x + 1, y); + search8(x - 1, y); + search8(x, y + 1); + search8(x, y - 1); + search8(x + 1, y + 1); + search8(x - 1, y - 1); + search8(x - 1, y + 1); + search8(x + 1, y - 1); + } + } + } + + /* + * Creates the zerocrossing map from the primary map + */ + + private void zeroCrossHysteresis8() { + for (int y = 0; y < ny; y++) { + int i = y * nx; + for (int x = 0; x < nx; x++, i++) { + if (real[i] == 2.0) { + search8(x + 1, y); + search8(x - 1, y); + search8(x, y + 1); + search8(x, y - 1); + search8(x + 1, y + 1); + search8(x - 1, y - 1); + search8(x - 1, y + 1); + search8(x + 1, y - 1); + } + } + } + for (int x = 0; x < nxy; x++) { + if (real[x] < 1.5) { + real[x] = 0.0; + } + else { + real[x] = 1.0; + } + } + } + + /** + * Performs Canny edge detection on this ComplexImage and keeps only the + * pixels that belong to the edge map. The edge of the image is included in + * the map. + * + * @param Tl + * the lower threshold + * @param Th + * the higher threshold + * @return the percentage of pixels that belong to the edge map, excluding + * the edge + */ + + public double canny(double Tl, double Th) { + ComplexImage mod = copyImage(); + mod.modulus(); + // determin directions + int[] dir = new int[nxy]; // Directions of gradient 0,1,2,3 + for (int x = 0; x < nxy; x++) { + if (((imag[x] <= 0.0) && (real[x] > -imag[x])) || ((imag[x] >= 0.0) && (real[x] < -imag[x]))) { + dir[x] = 0; + } + if (((real[x] > 0.0) && (-imag[x] >= real[x])) || ((real[x] < 0.0) && (real[x] >= -imag[x]))) { + dir[x] = 1; + } + if (((real[x] <= 0.0) && (real[x] > imag[x])) || ((real[x] >= 0.0) && (real[x] < imag[x]))) { + dir[x] = 2; + } + if (((imag[x] < 0.0) && (real[x] <= imag[x])) || ((imag[x] > 0.0) && (real[x] >= imag[x]))) { + dir[x] = 3; + } + } + // Nonmaxima supression + ComplexImage mod1 = mod.copyImage(); + int[][] neighbours = { { nx, nx - 1, -nx, -nx + 1 }, { -1, nx - 1, 1, -nx + 1 }, { -1, -nx - 1, 1, nx + 1 }, { -nx, -nx - 1, nx, nx + 1 } }; + // exclude edges + for (int x = 0, x1 = nxy - 1; x < nx; x++, x1--) { + mod1.real[x] = mod1.real[x1] = 0.0; + } + for (int x = 0, x1 = nxy - 1; x < nxy; x += nx, x1 -= nx) { + mod1.real[x] = mod1.real[x1] = 0.0; + } + for (int x = nx + 1; x < nxy - nx - 1; x++) { + double d = Math.abs(imag[x] / real[x]); + if (d > 1.0) { + d = 1.0 / d; + } + double ss1 = mod.real[x + neighbours[dir[x]][0]] * (1.0 - d) + mod.real[x + neighbours[dir[x]][1]] * d; + double ss2 = mod.real[x + neighbours[dir[x]][2]] * (1.0 - d) + mod.real[x + neighbours[dir[x]][3]] * d; + if (!((mod.real[x] > ss1) && (mod.real[x] > ss2))) { + mod1.real[x] = 0.0; + } + } + // Hysteresis + // Form a map + ComplexImage map = new ComplexImage(nx, ny); + for (int x = 0; x < nxy; x++) { + if (mod1.real[x] > Th) { + map.real[x] = 2.0; + } + else { + if (mod1.real[x] > Tl) { + map.real[x] = 1.0; + } + } + } + map.zeroCrossHysteresis8(); + double pr = map.sumReal() / map.nxy; + map.frame(1.0); + multiply(map); + return pr; + } + + /** + * Differentiates the real part of this ComplexImage along x. + */ + + public void derivativeX() { + ComplexImage temp = new ComplexImage(nx, ny); + System.arraycopy(real, 0, temp.real, 0, nxy); + temp.FFT2D(); + for (int k = 0; k < nx; k++) { + double x = PI2 * (double) k / (double) nx; + if (x > Math.PI) { + x -= PI2; + } + for (int l = 0; l < ny; l++) { + int index = l * nx + k; + temp.real[index] *= x; + temp.imag[index] *= x; + } + } + temp.conj(); + System.arraycopy(temp.real, 0, imag, 0, nxy); + System.arraycopy(temp.imag, 0, real, 0, nxy); + iFFT2D(); + } + + /** + * Differentiates the real part of this ComplexImage along y. + */ + + public void derivativeY() { + ComplexImage temp = new ComplexImage(nx, ny); + System.arraycopy(real, 0, temp.real, 0, nxy); + temp.FFT2D(); + for (int k = 0; k < ny; k++) { + double y = PI2 * (double) k / (double) ny; + if (y > Math.PI) { + y -= PI2; + } + for (int l = 0; l < nx; l++) { + int index = k * nx + l; + temp.real[index] *= y; + temp.imag[index] *= y; + } + } + temp.conj(); + System.arraycopy(temp.real, 0, imag, 0, nxy); + System.arraycopy(temp.imag, 0, real, 0, nxy); + iFFT2D(); + } + + /** + * Smooth the real part of this ComplexImage. The value of each pixel is + * computed as the mean value of its 3x3 neighbourhood. + */ + + public void smooth() { + // Define neighbour + int[] d = { 1, -1, nx, -nx, nx + 1, nx - 1, -nx + 1, -nx - 1, 0 }; + double[] w1 = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; // additional + // weights + // that + // depend + // on + // position + ComplexImage temp = copyImage(); + for (int i = nx + 1; i < nxy - nx - 1; i++) { + double m = 0.0; + double s = 0.0; + for (int k = 0; k < 9; k++) { + double w = w1[k]; + s += w; // normalization + m += (temp.real[i + d[k]] * w); + } + m /= s; + real[i] = m; + } + } + + /** + * Smooth the real part of this ComplexImage using the given weights. The + * value of each pixel is computed as the mean value of its weighted 3x3 + * neighbourhood. + * + * @param weights + * the weights, a Compleximage of the same size as this + * ComplexImage + */ + + public void smooth(ComplexImage weights) { + // Define neighbour + int[] d = { 1, -1, nx, -nx, nx + 1, nx - 1, -nx + 1, -nx - 1, 0 }; + double[] w1 = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; // additional + // weights + // that + // depend + // on + // position + ComplexImage temp = copyImage(); + for (int i = nx + 1; i < nxy - nx - 1; i++) { + double m = 0.0; + double s = 0.0; + for (int k = 0; k < 9; k++) { + double w = weights.real[i + d[k]] * w1[k]; + s += w; // normalization + double t = temp.real[i + d[k]]; + m += (t * w); + } + m /= s; + real[i] = m; + } + } + + /** + * Computes the first parameter of Riesz transform of this ComplexImage. + */ + + public void riesz1() { + FFT2D(); + ComplexImage mult1 = new ComplexImage(nx, ny); + for (int y = 0; y < ny; y++) { + double omy = 2.0 * Math.PI * (double) y / (double) ny - Math.PI; + for (int x = 0; x < nx; x++) { + double omx = 2.0 * Math.PI * (double) x / (double) nx - Math.PI; + mult1.real[nx * y + x] = 1.0 / Math.sqrt(omx * omx + omy * omy); + mult1.real[nx * y + x] *= omx; + } + } + mult1.shift(); + mult1.real[0] = 1.0; + multiply(mult1); + iFFT2D(); + double[] temparray = new double[nxy]; + System.arraycopy(real, 0, temparray, 0, nxy); + System.arraycopy(imag, 0, real, 0, nxy); + System.arraycopy(temparray, 0, imag, 0, nxy); + conj(); + } + + /** + * Computes the second parameter of Riesz transform of this ComplexImage. + */ + + public void riesz2() { + FFT2D(); + ComplexImage mult1 = new ComplexImage(nx, ny); + for (int y = 0; y < ny; y++) { + double omy = 2.0 * Math.PI * (double) y / (double) ny - Math.PI; + for (int x = 0; x < nx; x++) { + double omx = 2.0 * Math.PI * (double) x / (double) nx - Math.PI; + mult1.real[nx * y + x] = 1.0 / Math.sqrt(omx * omx + omy * omy); + mult1.real[nx * y + x] *= omy; + } + } + mult1.shift(); + mult1.real[0] = 1.0; + multiply(mult1); + double[] temparray = new double[nxy]; + System.arraycopy(real, 0, temparray, 0, nxy); + System.arraycopy(imag, 0, real, 0, nxy); + System.arraycopy(temparray, 0, imag, 0, nxy); + conj(); + iFFT2D(); + } +} diff --git a/src/bilib/src/polyharmonicwavelets/DyadicFilters.java b/src/bilib/src/polyharmonicwavelets/DyadicFilters.java new file mode 100644 index 0000000000000000000000000000000000000000..36b7f36f62dc7723487e1a9d0c9e5d5d7a210cb2 --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/DyadicFilters.java @@ -0,0 +1,497 @@ +package polyharmonicwavelets; + +// +// DyadicFilters.java +// PolyharmonicWavelets +// +// Created by Biomedical Imaging Group on 2/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +import java.util.*; +import ij.*; +import java.text.DecimalFormat; + +/** + * This class computes the filters for the dyadic wavelet transform. + * + * @author Katarina Balac, EPFL. + */ + +public class DyadicFilters { + + /** + * The analysis filters. FA[0] the lowpass analysis filter FA[1], FA[2], + * FA[3] the highpass analysis filters + */ + public ComplexImage[] FA; + + /** + * The synthesis filters. FS[0] the lowpass synthesis filter FS[1], FS[2], + * FS[3] the highpass synthesis filters + */ + public ComplexImage[] FS; + + /** + * Pyramid synthesis filters + */ + public ComplexImage[] FP; + + /** + * The prefilter. + */ + public ComplexImage P; + + /** + * The autocorrelation. + */ + + public ComplexImage ac; + + private Parameters param; // Parameters for the + // transform + private int nx; // Size of filters + private int ny; + private final double PI = Math.PI; + private final double PI2 = 2.0 * PI; + private final double sqrt2 = Math.sqrt(2.0); + + /** + * Constructor, creates a filters object and reserves the memory space for + * all the analysis and synthesis filters that will be needed depending on + * parameters. + * + * @param par + * the wavelet transform parameters + * @param sizex + * the number of columns in the image to transform + * @param sizey + * the number of rows in the image to transform + */ + + public DyadicFilters(Parameters par, int sizex, int sizey) { + param = par; + nx = sizex; + ny = sizey; + FA = new ComplexImage[4]; + FA[0] = new ComplexImage(nx, ny, param.N == 0); + FA[1] = new ComplexImage(nx, ny, (!(param.redundancy == param.BASIS) && (param.N == 0))); + if (param.redundancy == param.BASIS) { + FA[2] = new ComplexImage(nx, ny); + FA[3] = new ComplexImage(nx, ny); + } + FS = new ComplexImage[4]; + if (!(param.analysesonly)) { + FS = new ComplexImage[4]; + FS[0] = new ComplexImage(nx, ny, param.N == 0); + for (int i = 1; i < 4; i++) { + FS[i] = new ComplexImage(nx, ny); + } + if (param.redundancy == param.PYRAMID) { + FP = new ComplexImage[3]; + for (int i = 0; i < 3; i++) { + FP[i] = new ComplexImage(nx, ny); + } + } + } + } + + /** + * Sets the wavelet transform parameters to desired value. + * + * @param param + * the parameters to set + */ + + public void setParameters(Parameters param) { + this.param = param; + } + + /* + * Calculates numenator of scaling function, localization support is [ minx + * : (maxx-minx)/sizex : maxx-(maxx-minx)/sizex, miny : (maxy-miny)/sizey : + * maxy-(maxy-miny)/sizey ] output is of size [sizex, sizey] and defined + * on[minx...maxx-eps,miny...maxy-eps] + */ + + private ComplexImage multiplicator(int sizex, int sizey, double minx, double miny, double maxx, double maxy, double gama, int N) { + ComplexImage result = new ComplexImage(sizex, sizey, N == 0); + double gama2 = gama / 2.0; + final double d83 = 8.0 / 3.0; + final double d23 = 2.0 / 3.0; + double epsx = (maxx - minx) / (4.0 * (double) sizex); + double epsy = (maxy - miny) / (4.0 * (double) sizey); + double rx = (maxx - minx) / (double) sizex; + double ry = (maxy - miny) / (double) sizey; + double[] sxarr = new double[sizex]; + double[] x1arr = new double[sizex]; + double x = minx; + for (int kx = 0; kx < sizex; kx++, x += rx) { + sxarr[kx] = Math.sin(x / 2) * Math.sin(x / 2); + double x1 = x; + while (x1 >= Math.PI - epsx) + x1 = x1 - PI2; + while (x1 < -Math.PI - epsx) + x1 = x1 + PI2; + x1arr[kx] = x1; + } + double y = miny; + for (int ky = 0; ky < sizey; ky++, y += ry) { + int kxy = ky * sizex; + double sy = Math.sin(y / 2.0); + sy = sy * sy; + double y1 = y; + while (y1 >= Math.PI - epsy) + y1 = y1 - PI2; + while (y1 < -Math.PI - epsy) + y1 = y1 + PI2; + double y11 = y1; + for (int kx = 0, index = kxy; kx < sizex; kx++, index++) { + y1 = y11; + double x1 = x1arr[kx]; + final double sx = sxarr[kx]; + double a = 1.0; + if (param.type == param.ISOTROPIC) { // Isotropic + a = 4.0 * (sx + sy) - d83 * (sx * sy); + } + if (param.type == param.CHANGESIGMA) { + final double sigma2 = param.s2; + final double b = -16.0 / sigma2; + final double c = 24.0 / (sigma2 * sigma2) - 16.0 / (3.0 * sigma2); + final double d = 8.0 / (sigma2 * sigma2) + 32.0 / 45.0 - 16.0 / (3.0 * sigma2); + final double e = 4.0 / 3.0 - 8.0 / sigma2; + a = 4.0 * (sx + sy) + b * (sx * sy) + c * (sx * sx * sy + sy * sy * sx) + d * (sx * sx * sx + sy * sy * sy) + e * (sx * sx + sy * sy); + } + double re = Math.pow(a, gama2); + double im = 0.0; + if (N > 0) { + boolean xpi = ((x1 < -Math.PI + epsx) && (x1 > -Math.PI - epsx)); + boolean ypi = ((y1 < -Math.PI + epsy) && (y1 > -Math.PI - epsy)); + boolean x0 = ((x1 < epsx) && (x1 > -epsx)); + boolean y0 = ((y1 < epsy) && (y1 > -epsy)); + if (!(x0 && y0)) { + double x1p = x1; + double y1p = y1; + if (xpi && !y0 && !ypi) { + x1p = 0.0; + } + if (ypi && !x0 && !xpi) { + y1p = 0.0; + } + x1 = x1p; + y1 = y1p; + } + for (int i = 0; i < N; i++) { + double re1 = re * x1 - im * y1; + double im1 = re * y1 + im * x1; + re = re1; + im = im1; + } + double t = Math.pow(x1 * x1 + y1 * y1, (double) N / 2.0); + if (t == 0.0) { + result.real[index] = 0.0; + result.imag[index] = 0.0; + } + else { + result.real[index] = re / t; + result.imag[index] = im / t; + } + } + else { + result.real[index] = re; + } + } + } + return result; + } + + /* + * Calculates denominator of scaling function support is [ 0 : maxx/sizex : + * maxx-maxx/sizex, 0 : maxy/sizey : maxy-maxy/sizey ] output is of size + * [sizex, sizey] and defined on[0...maxx-eps,0...maxy-eps] + */ + + private ComplexImage denominator(int sizex, int sizey, double minx, double miny, double maxx, double maxy, int N) { + ComplexImage result = new ComplexImage(sizex, sizey); + double gamaN2; + gamaN2 = (param.order - N) / 2.0; + for (int ky = 0; ky < sizey; ky++) { + int kxy = ky * sizex; + double y = miny + (double) ky * (maxy - miny) / (double) sizey; + for (int kx = 0, index = kxy; kx < sizex; kx++, index++) { + double x = minx + (double) kx * (maxx - minx) / (double) sizex; + double re = Math.pow(x * x + y * y, gamaN2); + double im = 0.0; + if (N > 0) { + for (int i = 0; i < N; i++) { + double re1 = re * x - im * y; + double im1 = re * y + im * x; + re = re1; + im = im1; + } + result.real[index] = re; + result.imag[index] = im; + } + else { + result.real[index] = re; + } + } + } + return result; + } + + /* + * Computes the prefilter P + */ + + private void calculatePrefilter() { + P = multiplicator(nx, ny, -PI, -PI, PI, PI, param.order, 0); + ComplexImage d = denominator(nx, ny, -PI, -PI, PI, PI, 0); + P.divide(d, 1.0, 0.0); + P.shift(); + if (param.flavor == param.DUALOPERATOR) { + P.divide(ac); + } + } + + /* + * Calculate filters for pyramid synthesis + */ + + private void pyramidSynthesisFilters() { + FA[1].multiply(1 / sqrt2); + ComplexImage[] Ge = FP; + Ge[0].copyImageContent(FA[1]); + Ge[1].copyImageContent(FA[1]); + Ge[2].copyImageContent(FA[1]); + Ge[0].multiply(FS[1]); + Ge[1].multiply(FS[2]); + Ge[2].multiply(FS[3]); + Ge[0].multiply(0.5); + Ge[1].multiply(0.5); + Ge[2].multiply(0.5); + ComplexImage[] Geconj = Ge; + Geconj[0].conj(); + Geconj[1].conj(); + Geconj[2].conj(); + int nx2 = FA[1].nx / 2; + int ny2 = FA[1].ny / 2; + int nxy2 = FA[1].nxy / 2; + int[] d = { 0, nx2, nxy2, nx2 + nxy2 }; + double[] mr = new double[9]; + double[] mi = new double[9]; + for (int ky = 0, km = 0; ky < nxy2; ky += FA[1].nx) { + for (int kx = ky, end = ky + nx2; kx < end; kx++, km++) { + for (int i = 0; i < 9; i++) { + mr[i] = mi[i] = 0.0; + } + double inr0 = 0.0; + double inr1 = 0.0; + double inr2 = 0.0; + double inr4 = 0.0; + double inr5 = 0.0; + double inr8 = 0.0; + double inri = 0.0; + double ini1 = 0.0; + double ini2 = 0.0; + double ini4 = 0.0; + double ini5 = 0.0; + double ini8 = 0.0; + for (int l = 0; l < 4; l++) { + int k = kx + d[l]; + inr0 += Geconj[0].real[k] * Geconj[0].real[k] + Geconj[0].imag[k] * Geconj[0].imag[k]; + inr4 += Geconj[1].real[k] * Geconj[1].real[k] + Geconj[1].imag[k] * Geconj[1].imag[k]; + inr8 += Geconj[2].real[k] * Geconj[2].real[k] + Geconj[2].imag[k] * Geconj[2].imag[k]; + inr1 += Geconj[0].real[k] * Geconj[1].real[k] + Geconj[0].imag[k] * Geconj[1].imag[k]; + ini1 += (-Geconj[0].real[k] * Geconj[1].imag[k] + Geconj[0].imag[k] * Geconj[1].real[k]); + inr2 += Geconj[0].real[k] * Geconj[2].real[k] + Geconj[0].imag[k] * Geconj[2].imag[k]; + ini2 += (-Geconj[0].real[k] * Geconj[2].imag[k] + Geconj[0].imag[k] * Geconj[2].real[k]); + inr5 += Geconj[1].real[k] * Geconj[2].real[k] + Geconj[1].imag[k] * Geconj[2].imag[k]; + ini5 += (-Geconj[1].real[k] * Geconj[2].imag[k] + Geconj[1].imag[k] * Geconj[2].real[k]); + } + // invert m + mr[0] = (inr4 * inr8) - (inr5 * inr5 + ini5 * ini5); + mr[1] = (inr2 * inr5 + ini2 * ini5) - (inr1 * inr8); + mi[1] = (-inr2 * ini5 + ini2 * inr5) - (ini1 * inr8); + mr[2] = (inr1 * inr5 - ini1 * ini5) - (inr2 * inr4); + mi[2] = (inr1 * ini5 + ini1 * inr5) - (ini2 * inr4); + double dr = mr[0] * inr0 + mr[1] * inr1 + mi[1] * ini1 + mr[2] * inr2 + mi[2] * ini2; + mr[3] = ((inr2 * inr5 + ini2 * ini5) - (inr1 * inr8)) / dr; + mi[3] = ((inr2 * ini5 - ini2 * inr5) + (ini1 * inr8)) / dr; + mr[4] = ((inr0 * inr8) - (inr2 * inr2 + ini2 * ini2)) / dr; + mr[5] = ((inr1 * inr2 + ini1 * ini2) - (inr0 * inr5)) / dr; + mi[5] = ((inr1 * ini2 - ini1 * inr2) - (inr0 * ini5)) / dr; + mr[6] = ((inr1 * inr5 - ini1 * ini5) - (inr2 * inr4)) / dr; + mi[6] = ((-inr1 * ini5 - ini1 * inr5) + (ini2 * inr4)) / dr; + mr[7] = ((inr2 * inr1 + ini2 * ini1) - (inr0 * inr5)) / dr; + mi[7] = ((inr2 * ini1 - ini2 * inr1) + (inr0 * ini5)) / dr; + mr[8] = ((inr0 * inr4) - (inr1 * inr1 + ini1 * ini1)) / dr; + mr[0] /= dr; + mr[1] /= dr; + mi[1] /= dr; + mr[2] /= dr; + mi[2] /= dr; + // end invert m + for (int l = 0; l < 4; l++) { + int k = kx + d[l]; + double[] ger = new double[3]; + double[] gei = new double[3]; + for (int i = 0; i < 3; i++) { + ger[i] = Geconj[i].real[k]; + gei[i] = Geconj[i].imag[k]; + } + for (int i = 0; i < 3; i++) { + double gr = 0.0; + double gi = 0.0; + for (int j = 0; j < 3; j++) { + gr += ger[j] * mr[3 * i + j] - gei[j] * mi[3 * i + j]; + gi += ger[j] * mi[3 * i + j] + gei[j] * mr[3 * i + j]; + } + Geconj[i].real[k] = gr; + Geconj[i].imag[k] = gi; + } + } + } + } + FP = Geconj; + FA[1].multiply(sqrt2); + } + + /** + * Calculates all filters needed to perform dyadic transform with given + * parameters. + */ + + public void calculateFilters() { + double k = 1.0 / Math.pow(2.0, param.order); + ComplexImage HH = null; + ComplexImage L1 = null; + if (param.accompute == param.ITERATIVE) { + // Compute filter on a 2x finer grid for autocorrelation + ComplexImage L = multiplicator(2 * nx, 2 * ny, 0.0, 0.0, 2.0 * PI2, 2.0 * PI2, param.order, param.N); // Numerator(2*omega) + // is + // complex + L1 = multiplicator(2 * nx, 2 * ny, 0.0, 0.0, PI2, PI2, param.order, param.N); // Numerator(omega) + // is + // complex + ComplexImage HHdouble = L; + HHdouble.multiply(k); + HHdouble.divide(L1, 1.0, 0.0); + // compute filter on a regular grid + HH = HHdouble.copyImage(); + HH.decimateCrop(); + L1.decimateCrop(); + // compute autocorrelation if needed + if (!(param.analysesonly)) { + HHdouble.squareModulus(); + ac = Autocorrelation.autocorrIterative(HHdouble); + } + } + else { + ComplexImage L = multiplicator(nx, ny, 0.0, 0.0, 2.0 * PI2, 2.0 * PI2, param.order, param.N); // Numerator(2*omega) + // is + // complex + L1 = multiplicator(nx, ny, 0.0, 0.0, PI2, PI2, param.order, param.N); // Numerator(omega) + // is + // complex + HH = L; + HH.multiply(k); + HH.divide(L1, 1.0, 0.0); + if (!((param.analysesonly) && (param.flavor == Parameters.MARR))) { + ComplexImage simpleloc = multiplicator(nx, ny, 0.0, 0.0, PI2, PI2, 2 * param.order, 0); + ac = Autocorrelation.autocorrGamma(simpleloc, param.order); + } + } + calculatePrefilter(); + if ((param.flavor == param.OPERATOR) || (param.flavor == param.DUALOPERATOR) || (param.flavor == param.MARR)) { + // Analysis filters + FA[0].copyImageContent(HH); + FA[0].multiply(2.0); + ComplexImage G = FA[1]; + G.copyImageContent(L1); + if (!(param.flavor == param.MARR)) { + G.divide(ac); + } + G.multiply(2.0); + if (param.rieszfreq == 1) { + ComplexImage V2 = multiplicator(nx, ny, 0.0, 0.0, PI2, PI2, 2.0, 0); + G.multiply(V2); + } + G.conj(); + ComplexImage R = null; + if (param.redundancy == param.BASIS) { // Basis is not for Marr + FA[2].copyImageContent(G); + FA[3].copyImageContent(G); + } + FA[1] = G; + // Compute synthesis filters + if (!(param.analysesonly)) { + // Synthesis lowpass + ComplexImage L1conj = L1.copyImage(); + L1conj.conj(); + ComplexImage H = FS[0]; + H.copyImageContent(HH); + H.conj(); + double k1 = k * 4.0; + H.multiply(k1); + ComplexImage acd = ac.copyImage(); + acd.decimate(); + ComplexImage Gs = ac.copyImage(); + Gs.divide(acd); + Gs.multiply(0.25); + H.multiply(Gs); + FS[0] = H; + FS[0].multiply(2.0 / k); + // Synthesis highpass + Gs.divide(L1conj, 0.0, 0.0); + ComplexImage D = HH.copyImage(); + D.squareModulus(); + D.multiply(1.0 / k); + D.multiply(ac); + D.multiply(k1); + ComplexImage D1 = D.copyImage(); + ComplexImage D2 = D.copyImage(); + ComplexImage D12 = D.copyImage(); + D1.shiftX(); + D2.shiftY(); + D12.shift(); + D1.multiply(Gs); + D2.multiply(Gs); + D12.multiply(Gs); + FS[1] = D1.copyImage(); + FS[1].add(D12); + FS[2] = D2.copyImage(); + FS[2].add(D12); + FS[3] = D1; + FS[3].add(D2); + } + if (param.flavor == param.DUALOPERATOR) { + ComplexImage[] Ftmp = FA; + FA = FS; + FS = Ftmp; + FA[0].conj(); + FA[1].conj(); + FA[2].conj(); + FA[3].conj(); + FS[0].conj(); + FS[1].conj(); + FS[2].conj(); + FS[3].conj(); + } + } + if (param.redundancy == param.BASIS) { // Basis is not for Marr + FA[1].modulateMinusX(); + FA[2].modulateMinusY(); + FA[3].modulateMinusQuincunx(); + } + if (!(param.analysesonly)) { + FS[1].modulatePlusX(); + FS[2].modulatePlusY(); + FS[3].modulatePlusQuincunx(); + } + + if ((param.redundancy == param.PYRAMID) && (!(param.analysesonly))) { + pyramidSynthesisFilters(); + } + } +} \ No newline at end of file diff --git a/src/bilib/src/polyharmonicwavelets/DyadicTransform.java b/src/bilib/src/polyharmonicwavelets/DyadicTransform.java new file mode 100644 index 0000000000000000000000000000000000000000..70f06bf4ffc779d9e458dad34d6ba74be485cae2 --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/DyadicTransform.java @@ -0,0 +1,556 @@ +package polyharmonicwavelets; + +// +// DyadicTransform.java +// PolyharmonicWavelets +// +// Created by Biomedical Imaging Group on 2/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +import java.util.*; +import ij.*; +import java.text.DecimalFormat; + +/** + * This class performs basis, pyramid and redundant dyadic transform. + * + * @author Katarina Balac, EPFL. + */ + +public class DyadicTransform { + + // Analysis and synthesis filters + // FA[0]=H1 + // FA[1]=G1 + // FA[2]=G2 + // FA[3]=G3 + // similar for analysis filters + // H - lowpass filters + // G - highpass filters + + private ComplexImage[] FA; + private ComplexImage[] FS; + private ComplexImage[] FP; + private ComplexImage P; + private int J; // number of iterations + private Parameters param; + private final int nx; + private final int ny; + private final double PI2 = 2.0 * Math.PI; + private final double sqrt2 = Math.sqrt(2.0); + private DyadicFilters filters; + + /** + * Creates a DyadicTransform object. + * + * @param filt + * the filters used for the dyadic transform + * @param par + * the transform parameters + */ + + public DyadicTransform(DyadicFilters filt, Parameters par) { + J = par.J; + param = par; + FA = filt.FA; + FS = filt.FS; + FP = filt.FP; + P = filt.P; + nx = FA[0].nx; + ny = FA[0].ny; + filters = filt; + } + + /** + * Performs the in-place nonredundant dyadic analysis on the input + * ComplexImage. + * + * @param image + * the image to transform + */ + + public void dyadicAnalysis(ComplexImage image) { + ComplexImage H = FA[0].copyImage(); + ComplexImage G1 = FA[1].copyImage(); + ComplexImage G2 = FA[2].copyImage(); + ComplexImage G3 = FA[3].copyImage(); + H.multiply(0.25); + G1.multiply(0.25); + G2.multiply(0.25); + G3.multiply(0.25); + ComplexImage R = image.copyImage(); // remaining lowpass subband + R.FFT2D(); + if (param.prefilter) { + R.multiply(P); + } + int l = 1; + for (int j = 1; j <= J; j++) { + ComplexImage Y0 = R.copyImage(); + ComplexImage Y1 = R.copyImage(); + ComplexImage Y2 = R.copyImage(); + ComplexImage Y3 = R.copyImage(); + Y0.multiply(H, l); + Y1.multiply(G1, l); + Y2.multiply(G2, l); + Y3.multiply(G3, l); + Y0.dyadicDownUpCrop(); + Y1.dyadicDownUpCrop(); + Y2.dyadicDownUpCrop(); + Y3.dyadicDownUpCrop(); + // Put highpass subbands in place + Y1.iFFT2D(); + Y2.iFFT2D(); + Y3.iFFT2D(); + R = Y0.copyImage(); + image.putSubimage(R.nx, 0, Y1); + image.putSubimage(0, R.ny, Y2); + image.putSubimage(R.nx, R.ny, Y3); + l *= 2; + } + R.iFFT2D(); + image.putSubimage(0, 0, R); + } + + /** + * Performs the in-place nonredundant dyadic synthesis on ComplexImage. + * + * @param image + * the image to transform + */ + + public void dyadicSynthesis(ComplexImage image) { + ComplexImage H = FS[0]; + ComplexImage G1 = FS[1]; + ComplexImage G2 = FS[2]; + ComplexImage G3 = FS[3]; + int l = 1; + for (int k = 1; k < J; k++, l *= 2) + ; + int cx = image.nx; // size of remaining lowpass subband + int cy = image.ny; + for (int i = 0; i < J; i++, cx /= 2, cy /= 2) + ; + ComplexImage Y = new ComplexImage(image.nx, image.ny); + ComplexImage Z = new ComplexImage(image.nx, image.ny); + Y.getSubimageContent(0, cx - 1, 0, cy - 1, image); // Lowpass + Y.FFT2D(); + for (int j = J; j > 0; j--) { + Y.dyadicUpsample(); + Y.multiply(H, l); + Z.getSubimageContent(cx, 2 * cx - 1, 0, cy - 1, image); + Z.FFT2D(); + Z.dyadicUpsample(); + Z.multiply(G1, l); + Y.add(Z); + Z.getSubimageContent(0, cx - 1, cy, 2 * cy - 1, image); + Z.FFT2D(); + Z.dyadicUpsample(); + Z.multiply(G2, l); + Y.add(Z); + Z.getSubimageContent(cx, 2 * cx - 1, cy, 2 * cy - 1, image); + Z.FFT2D(); + Z.dyadicUpsample(); + Z.multiply(G3, l); + Y.add(Z); + l /= 2; + cx *= 2; + cy *= 2; + } + if (param.prefilter) { + Y.divide(P); + } + Y.iFFT2D(); + image.copyImageContent(Y); + } + + /** + * Returns the result of fully redundant pyramid analysis of ComplexImage + * and all the intermediary lowpass subbands. + * + * @param image + * the image to transform + * @return in [0][] the array of dyadic transform subbands, and in [1][] the + * intermidiary lowpass subbands + */ + + public ComplexImage[][] dyadicAnalysesRedundantLowpass(ComplexImage image) { + ComplexImage[] lowpassSubbands = new ComplexImage[J + 1]; + ComplexImage[] array = new ComplexImage[J + 1]; + ComplexImage H = FA[0].copyImage(); + ComplexImage G = FA[1].copyImage(); + G.multiply(0.5 * sqrt2); + ComplexImage X = image.copyImage(); + X.FFT2D(); + if (param.prefilter) { + X.multiply(P); + } + for (int j = 1, l = 1; j <= J; j++) { + ComplexImage Yh = X.copyImage(); + Yh.multiplyCircular(G, l); + // Put Yh in stack + Yh.iFFT2D(); + array[j - 1] = Yh; + ComplexImage Yl = X; + Yl.multiplyCircular(H, l); + lowpassSubbands[j - 1] = Yl.copyImage(); + lowpassSubbands[j - 1].iFFT2D(); + X = Yl; + l *= 2; + } + // Put remaining lowpass in stack + X.iFFT2D(); + array[J] = X; + lowpassSubbands[J] = X.copyImage(); + G.multiply(sqrt2); + ComplexImage[][] out = new ComplexImage[2][]; + out[0] = array; + out[1] = lowpassSubbands; + return out; + } + + /** + * Returns the result of fully redundant dyadic analysis of ComplexImage. + * + * @param image + * the ComplexImage to transform + * @return the array of dyadic transform subbands + */ + + public ComplexImage[] dyadicAnalysesRedundant(ComplexImage image) { + ComplexImage[] array = new ComplexImage[J + 1]; + ComplexImage H = FA[0].copyImage(); + ComplexImage G = FA[1].copyImage(); + G.multiply(0.5 * sqrt2); + ComplexImage X = image.copyImage(); + X.FFT2D(); + if (param.prefilter) { + X.multiply(P); + } + for (int j = 1, l = 1; j <= J; j++) { + ComplexImage Yh = X.copyImage(); + Yh.multiplyCircular(G, l); + // Put Yh in stack + Yh.iFFT2D(); + array[j - 1] = Yh; + ComplexImage Yl = X; + Yl.multiplyCircular(H, l); + X = Yl; + l *= 2; + } + // Put remaining lowpass in stack + X.iFFT2D(); + array[J] = X; + G.multiply(sqrt2); + return array; + } + + /** + * Returns the result of fully redundant dyadic synthesis. + * + * @param array + * subbands of dyadic pyramid transform + * @return the result of synthesis + */ + + public ComplexImage dyadicSynthesisRedundant(ComplexImage[] array) { + ComplexImage H = FS[0].copyImage(); + ComplexImage G = FS[1].copyImage(); + G.add(FS[2]); + G.add(FS[3]); + G.multiply(0.25 * sqrt2); + H.multiply(0.25); + if (param.flavor == param.MARR) { + G.divide(filters.ac); + } + int l = 1; + for (int k = 1; k < J; k++, l *= 2) + ; + ComplexImage Y = array[J].copyImage(); // Lowpass + Y.FFT2D(); + for (int j = J; j > 0; j--) { + ComplexImage Z = array[j - 1].copyImage(); + Z.FFT2D(); + Y.multiplyCircular(H, l); + Z.multiplyCircular(G, l); + l /= 2; + Y.add(Z); + } + if (param.prefilter) { + Y.divide(P); + } + Y.iFFT2D(); + return Y; + } + + /** + * Returns the result of dyadic pyramid analysis of ComplexImage. + * + * @param image + * the image to transform + * @return the array of dyadic transform subbands + */ + + public ComplexImage[] dyadicAnalysesPyramid(ComplexImage image) { + ComplexImage[] array = new ComplexImage[J + 1]; + ComplexImage H = FA[0]; + ComplexImage G = FA[1]; + H.multiply(0.25); + G.multiply(0.5 * sqrt2); + ComplexImage X = image.copyImage(); + X.FFT2D(); + if (param.prefilter) { + X.multiply(P); + } + for (int j = 1, l = 1; j <= J; j++) { + ComplexImage Yh = X.copyImage(); + Yh.multiply(G, l); + // Put Yh in stack + Yh.iFFT2D(); + array[j - 1] = Yh; + ComplexImage Yl = X; + Yl.multiply(H, l); + l *= 2; + Yl.dyadicDownUpCrop(); + X = Yl; + } + // Put remaining lowpass in stack + X.iFFT2D(); + array[J] = X; + H.multiply(4.0); + G.multiply(sqrt2); + return array; + } + + /** + * Returns the result of dyadic pyramid analysis of ComplexImage and all the + * intermediary lowpass subbands. + * + * @param image + * the image to transform + * @return in [0][] the array of dyadic transform subbands, and in [1][] the + * intermidiary lowpass subbands + */ + + public ComplexImage[][] dyadicAnalysesPyramidLowpass(ComplexImage image) { + ComplexImage[] lowpassSubbands = new ComplexImage[J + 1]; + ComplexImage[] array = new ComplexImage[J + 1]; + ComplexImage H = FA[0]; + ComplexImage G = FA[1]; + H.multiply(0.25); + G.multiply(0.5 * sqrt2); + ComplexImage X = image.copyImage(); + // ComplexImage Yh=new ComplexImage(image.nx,image.ny); + X.FFT2D(); + if (param.prefilter) { + X.multiply(P); + } + for (int j = 1, l = 1; j <= J; j++) { + ComplexImage Yh = new ComplexImage(image.nx, image.ny); + Yh.copyImageContent(X); + Yh.multiply(G, l); + // Put Yh in stack + Yh.iFFT2D(); + array[j - 1] = Yh; + ComplexImage Yl = X; + Yl.multiply(H, l); + lowpassSubbands[j - 1] = Yl.copyImage(); + lowpassSubbands[j - 1].iFFT2D(); + l *= 2; + Yl.dyadicDownUpCrop(); + X = Yl; + } + // Put remaining lowpass in stack + X.iFFT2D(); + array[J] = X; + lowpassSubbands[J] = X.copyImage(); + // H.multiply(4.0); + // G.multiply(sqrt2); + ComplexImage[][] out = new ComplexImage[2][]; + out[0] = array; + out[1] = lowpassSubbands; + return out; + } + + /** + * Returns the result of pyramid dyadic synthesis of array. + * + * @param array + * subbands of dyadic pyramid transform + * @return the result of synthesis + */ + + public ComplexImage dyadicSynthesisPyramid(ComplexImage[] array) { + FS[1].multiply(0.5); + FS[2].multiply(0.5); + FS[3].multiply(0.5); + ComplexImage Gconj = FA[1].copyImage(); + Gconj.multiply(1 / sqrt2); + ComplexImage[] G0 = FP; + // Reconstruct with calculated filters G0, FS, Gconj + int l = 1; + for (int i = 0; i < J; i++, l *= 2) + ; + ComplexImage Y1 = new ComplexImage(array[0].nx, array[0].ny); + ComplexImage Y2 = new ComplexImage(array[0].nx, array[0].ny); + ComplexImage GY = new ComplexImage(array[0].nx, array[0].ny); + Y1.copyImageContent(array[J]); + Y1.FFT2D(); + for (int j = J - 1; j >= 0; j--) { + Y2.copyImageContent(array[j]); + Y2.FFT2D(); + l /= 2; + Y1.dyadicUpsample(); + Y1.multiply(FS[0], l); + GY.copyImageContent(Y1); + GY.multiply(Gconj, l); + ComplexImage Y21 = Y2; + Y21.subtract(GY); + GY.copyImageContent(Y21); + GY.multiply(G0[1], l); + GY.dyadicDownUp(); + GY.multiply(FS[2], l); + Y1.add(GY); + GY.copyImageContent(Y21); + GY.multiply(G0[2], l); + GY.dyadicDownUp(); + GY.multiply(FS[3], l); + Y1.add(GY); + Y21.multiply(G0[0], l); + Y21.dyadicDownUp(); + Y21.multiply(FS[1], l); + Y1.add(Y21); + } + if (param.prefilter) { + Y1.divide(P); + } + Y1.iFFT2D(); + FS[1].multiply(2.0); + FS[2].multiply(2.0); + FS[3].multiply(2.0); + return Y1; + } + + /** + * Prepares the real dyadic pyramid transform coeffitients for being + * displayed. Rescales the subbands for visualisation and puts all subbands + * in one ComplexImage. + * + * @param array + * subbands of dyadic pyramid transform + * @param back + * background color + * @param rescale + * if rescale=false there is no rescaling + * @param lp + * if lp=false the lowpass subband is not displayed + * @return the image to display + */ + + public ComplexImage displayDyadicPyramidReal(ComplexImage[] array, double back, boolean rescale, boolean lp) { + int J1 = J; + if (!lp) { + J1 -= 1; + } + int nx = array[0].nx; + int ny = array[0].ny; + ComplexImage disp = new ComplexImage(nx, 2 * ny); + disp.settoConstant(back, back); + int x = 0; + int y = 0; + int dx = nx / 4; + int dy = ny; + for (int j = 0; j <= J1; j++) { + ComplexImage temp = array[j].copyImage(); + if (rescale) { + temp.stretch(); + } + temp.frame(back); + disp.putSubimage(x, y, temp); + x += dx; + y += dy; + dx /= 2; + dy /= 2; + } + return disp; + } + + /** + * Prepares the dyadic pyramid transform coeffitients for being displayed. + * + * @param array + * subbands of dyadic pyramid transform + * @param back + * background color + * @param rescale + * if rescale=false there is no rescaling + * @param lp + * if lp=false the lowpass subband is not displayed + * @return the image to display + */ + + public ComplexImage displayDyadicPyramid(ComplexImage[] array, double back, boolean rescale, boolean lp) { + int J1 = J; + if (!lp) { + J1 -= 1; + } + int nx = array[0].nx; + int ny = array[0].ny; + ComplexImage disp = new ComplexImage(2 * nx, 2 * ny); + disp.settoConstant(back, back); + int x = 0; + int y = 0; + int dx = nx / 2; + int dy = ny; + for (int j = 0; j <= J1; j++) { + ComplexImage temp = array[j].copyImage(); + if (rescale) { + temp.stretch(); + } + temp.frame(back, back); + + disp.putSubimage(x, y, temp); + System.arraycopy(temp.imag, 0, temp.real, 0, temp.nxy); + disp.putSubimage(x + temp.nx, y, temp); + disp.setImagtoZero(); + x += dx; + y += dy; + dx /= 2; + dy /= 2; + } + return disp; + } + + /** + * Prepares a nonredundant dyadic transform for being displayed, stretches + * each subband. + * + * @param image + * the basis transform coefficients + * @return the image with rescaled subbands to display + */ + + public ComplexImage displayBasis(ComplexImage image) { + int dx = image.nx; + int dy = image.ny; + ComplexImage out = new ComplexImage(dx, dy); + ComplexImage sub; + for (int j = 1; j <= J; j++) { + sub = image.getSubimage(dx / 2, dx - 1, 0, dy / 2 - 1); + sub.stretch(); + out.putSubimage(dx / 2, 0, sub); + sub.getSubimageContent(dx / 2, dx / 2 + sub.nx - 1, dy / 2, dy / 2 + sub.ny - 1, image); + sub.stretch(); + out.putSubimage(dx / 2, dy / 2, sub); + sub.getSubimageContent(0, sub.nx - 1, dy / 2, dy / 2 + sub.ny - 1, image); + sub.stretch(); + out.putSubimage(0, dy / 2, sub); + dx /= 2; + dy /= 2; + } + sub = image.getSubimage(0, dx - 1, 0, dy - 1); + sub.stretch(); + out.putSubimage(0, 0, sub); + return out; + } +} \ No newline at end of file diff --git a/src/bilib/src/polyharmonicwavelets/FFT1D.java b/src/bilib/src/polyharmonicwavelets/FFT1D.java new file mode 100644 index 0000000000000000000000000000000000000000..d2458f78b9e8d4b5251127ded26140530d18615a --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/FFT1D.java @@ -0,0 +1 @@ +package polyharmonicwavelets; import ij.*; /** * Performs a 1D FFT. * <hr> * <p> * <b>Plugin of ImageJ:</b><br> * Fractional Spline Wavelet<br> * * <p> * <b>Authors:</b><br> * Gil Gaillard, Michael Liebling, Daniel Sage, Dimitri Van De Ville <a * href="mailto:daniel.sage@epfl.ch?subject=Fractional Spline Wavelet Plugin" * >daniel.sage@epfl.ch</a><br> * Swiss Federal Institute of Technology Lausanne, Biomedical Imaging Group, * CH-1015 Lausanne, Switzerland, <a * href="http://bigwww.epfl.ch">http://bigwww.epfl.ch</a><br> * * <p> * <b>Version:</b><br> * April 2003<br> * * <p> * <b>Copyright</b><br> * Copyright � 2003, Swiss Federal Institute of Technology, Lausanne, * Switzerland, (EPFL)<br> * * <hr> * * <p> * <b>Purpose of the class:</b><br> * Perform a 1D FFT. */ public class FFT1D { private boolean radix2 = true; private double Rearg[]; private double Imarg[]; private double[] yReOut; private double[] yImOut; public FFT1D(int size) { int m = 1; int size1 = size; double fact; double arg; while (size1 > 2) { size1 /= 2; m++; } if ((int) Math.round(Math.pow(2, m)) == size) { radix2 = true; n = 1 << m; fact = 2.0 * Math.PI / (double) n; Imarg = new double[n]; Rearg = new double[n]; // compute W coefficients for (int i = 0; i < n; i++) { arg = fact * (double) i; Rearg[i] = Math.cos(arg); Imarg[i] = -Math.sin(arg); } } else { radix2 = false; maxPrimeFactor = /* 65537; */(int) ((double) (size + 1)); maxPrimeFactorDiv2 = (maxPrimeFactor + 1) / 2;// (int)((double)(maxPrimeFactor+1)/2); twiddleRe = new double[maxPrimeFactor]; twiddleIm = new double[maxPrimeFactor]; trigRe = new double[maxPrimeFactor]; trigIm = new double[maxPrimeFactor]; zRe = new double[maxPrimeFactor]; zIm = new double[maxPrimeFactor]; vRe = new double[maxPrimeFactorDiv2]; vIm = new double[maxPrimeFactorDiv2]; wRe = new double[maxPrimeFactorDiv2]; wIm = new double[maxPrimeFactorDiv2]; yReOut = new double[size]; yImOut = new double[size]; // Math.pi = 4*Math.atan(1); n = size; sofarRadix = new int[maxFactorCount]; actualRadix = new int[maxFactorCount]; remainRadix = new int[maxFactorCount]; transTableSetup(sofarRadix, actualRadix, remainRadix); } } /** * Select the algorithm to perform the FFT1D, Cooley-Tukey or Mix. * * @param Re * real part of the input signal * @param Im * imaginary part of the input signal * @param size * length of the FFT * @param shift * set the start of the FFT */ final public void transform(double Re[], double Im[], int size, int shift) // Call // this // function // for // FFT! { n = size; if (radix2) { doFFT1D_CooleyTukey(Re, Im, size, shift); } else { if (shift == 0) doFFT_Mix(Re, Im, size); else doFFT_Mix(Re, Im, size, shift); } } /** * Select the algorithm to perform the Inverse FFT1D, Cooley-Tukey or Mix. * * @param Re * real part of the input signal * @param Im * imaginary part of the input signal * @param size * length of the IFFT * @param shift * set the start of the IFFT */ final public void inverse(double Re[], double Im[], int size, int shift) // Call // this // for // inverse // FFT! { n = size; if (radix2) { doIFFT1D_CooleyTukey(Re, Im, size, shift); } else { if (shift == 0) doIFFT_Mix(Re, Im, size); else doIFFT_Mix(Re, Im, size, shift); } } /** * Perform the FFT1D. * * There are two algorithms, the first for power of two length is a * Cooley-Tukey algorithm, the second for all size has been downloaded from * the Web (Mixfft.java). These are used to transform rows or columns in the * wavelet transform. * * @param Re * real part of the input signal * @param Im * imaginary part of the input signal * @param size * length of the FFT * @param shift * set the start of the FFT */ private void doFFT1D_CooleyTukey(double Re[], double Im[], int size, int shift) { int m = 1; int size1 = size; while (size1 > 2) { size1 /= 2; m++; } double Retmp, Imtmp; int i, j, k, stepsize, shifter; int i_j, i_j_s; // bit inversion for (i = j = shift; i < shift + n - 1; i++) { if (i < j) { Retmp = Re[i]; Imtmp = Im[i]; Re[i] = Re[j]; Im[i] = Im[j]; Re[j] = Retmp; Im[j] = Imtmp; } k = n >> 1; while (k + shift <= j) { j -= k; k /= 2; } j += k; } // Perform the FFT for (stepsize = 1, shifter = m - 1; stepsize < n; stepsize <<= 1, --shifter) { for (j = shift; j < shift + n; j += stepsize << 1) { for (i = 0; i < stepsize; i++) { i_j = i + j; i_j_s = i_j + stepsize; if (i > 0) { Retmp = Rearg[i << shifter] * Re[i_j_s] - Imarg[i << shifter] * Im[i_j_s]; Im[i_j_s] = Rearg[i << shifter] * Im[i_j_s] + Imarg[i << shifter] * Re[i_j_s]; Re[i_j_s] = Retmp; } Retmp = Re[i_j] - Re[i_j_s]; Imtmp = Im[i_j] - Im[i_j_s]; Re[i_j] += Re[i_j_s]; Im[i_j] += Im[i_j_s]; Re[i_j_s] = Retmp; Im[i_j_s] = Imtmp; } } } } /** * Perform the IFFT1D. * * Same algorithms as these used for the FFT. * * @param Re * real part of the input signal * @param Im * imaginary part of the input signal * @param size * length of the IFFT * @param shift * set the start of the IFFT */ private void doIFFT1D_CooleyTukey(double Re[], double Im[], final int size, int shift) { for (int i = shift; i < shift + size; i++) { Im[i] = -Im[i]; } transform(Re, Im, size, shift); for (int i = shift; i < shift + size; i++) { Re[i] = Re[i] / size; /* Output is in Re */ Im[i] = -Im[i] / size; } } /* * fft(int n, double xRe[], double xIm[], double yRe[], double yIm[]) * ------------------------------------------------------------------------ * NOTE : This is copyrighted material, Not public domain. See below. * ------------------------------------------------------------------------ * Input/output: int n transformation length. double xRe[] real part of * input sequence. double xIm[] imaginary part of input sequence. double * yRe[] real part of output sequence. double yIm[] imaginary part of output * sequence. * ------------------------------------------------------------------------ * Function: The procedure performs a fast discrete Fourier transform (FFT) * of a complex sequence, x, of an arbitrary length, n. The output, y, is * also a complex sequence of length n. * * y[k] = sum(x[m]*exp(-i*2*Math.pi*k*m/n), m=0..(n-1)), k=0,...,(n-1) * * The largest prime factor of n must be less than or equal to the constant * maxPrimeFactor defined below. * ------------------------------------------------------------------------ * Author: Jens Joergen Nielsen For non-commercial use only. Bakkehusene 54 * A $100 fee must be paid if used DK-2970 Hoersholm commercially. Please * contact. DENMARK * * E-mail : jjn@get2net.dk All rights reserved. October 2000. Homepage : * http://home.get2net.dk/jjn * ------------------------------------------------------------------------ * Implementation notes: The general idea is to factor the length of the * DFT, n, into factors that are efficiently handled by the routines. * * A number of short DFT's are implemented with a minimum of arithmetical * operations and using (almost) straight line code resulting in very fast * execution when the factors of n belong to this set. Especially radix-10 * is optimized. * * Prime factors, that are not in the set of short DFT's are handled with * direct evaluation of the DFP expression. * * Please report any problems to the author. Suggestions and improvements * are welcomed. * ------------------------------------------------------------------------ * Benchmarks: The Microsoft Visual C++ comMath.piler was used with the * following comMath.pile options: /nologo /Gs /G2 /W4 /AH /Ox /D "NDEBUG" * /D "_DOS" /FR and the FFTBENCH test executed on a 50MHz 486DX : * * Length Time [s] Accuracy [dB] * * 128 0.0054 -314.8 256 0.0116 -309.8 512 0.0251 -290.8 1024 0.0567 -313.6 * 2048 0.1203 -306.4 4096 0.2600 -291.8 8192 0.5800 -305.1 100 0.0040 * -278.5 200 0.0099 -280.3 500 0.0256 -278.5 1000 0.0540 -278.5 2000 0.1294 * -280.6 5000 0.3300 -278.4 10000 0.7133 -278.5 * ------------------------------------------------------------------------ * The following procedures are used : factorize : factor the transformation * length. transTableSetup : setup table with sofar-, actual-, and * remainRadix. permute : permutation allows in-place calculations. * twiddleTransf : twiddle multiplications and DFT's for one stage. initTrig * : initialise sine/cosine table. fft_4 : length 4 DFT, a la Nussbaumer. * fft_5 : length 5 DFT, a la Nussbaumer. fft_10 : length 10 DFT using prime * factor FFT. fft_odd : length n DFT, n odd. * *********************************************************************** */ private int maxPrimeFactor; private int maxPrimeFactorDiv2; private int maxFactorCount = 20; private int n, nFactor; private final double c3_1 = -1.5000000000000E+00; // c3_1 = // cos(2*Math.pi/3)-1; private final double c3_2 = 8.6602540378444E-01; // c3_2 = // sin(2*Math.pi/3); private final double u5 = 1.2566370614359E+00; // u5 = // 2*Math.pi/5; private final double c5_1 = -1.2500000000000E+00; // c5_1 = // (cos(u5)+cos(2*u5))/2-1; private final double c5_2 = 5.5901699437495E-01; // c5_2 = // (cos(u5)-cos(2*u5))/2; private final double c5_3 = -9.5105651629515E-01; // c5_3 = // -sin(u5); private final double c5_4 = -1.5388417685876E+00; // c5_4 = // -(sin(u5)+sin(2*u5)); private final double c5_5 = 3.6327126400268E-01; // c5_5 = // (sin(u5)-sin(2*u5)); private final double c8 = 7.0710678118655E-01; // c8 = // 1/sqrt(2); // private double Math.pi; private int groupOffset, dataOffset, blockOffset, adr; private int groupNo, dataNo, blockNo, twNo; private double omega, tw_re, tw_im; private double[] twiddleRe; private double[] twiddleIm; private double[] trigRe; private double[] trigIm; private double[] zRe; private double[] zIm; private double[] vRe; private double[] vIm; private double[] wRe; private double[] wIm; private int[] sofarRadix; private int[] actualRadix; private int[] remainRadix; /** * */ private void factorize(int fact[], int num) { int i, j, k; int nRadix; int[] radices = new int[7]; int[] factors = new int[maxFactorCount]; nRadix = 6; radices[1] = 2; radices[2] = 3; radices[3] = 4; radices[4] = 5; radices[5] = 8; radices[6] = 10; if (num == 1) { j = 1; factors[1] = 1; } else j = 0; i = nRadix; while ((num > 1) && (i > 0)) { if ((num % radices[i]) == 0) { num = num / radices[i]; j = j + 1; factors[j] = radices[i]; } else i = i - 1; } if (factors[j] == 2) /* substitute factors 2*8 with 4*4 */ { i = j - 1; while ((i > 0) && (factors[i] != 8)) i--; if (i > 0) { factors[j] = 4; factors[i] = 4; } } if (num > 1) { for (k = 2; k < Math.sqrt(num) + 1; k++) while ((num % k) == 0) { num = num / k; j = j + 1; factors[j] = k; } if (num > 1) { j = j + 1; factors[j] = num; } } for (i = 1; i <= j; i++) { fact[i] = factors[j - i + 1]; } nFactor = j; } /** * After N is factored the parameters that control the stages are generated. * * @param sofar * the product of the radices so far. * @param actual * : the radix handled in this stage. * @param remain * : the product of the remaining radices. */ final private void transTableSetup(int sofar[], int actual[], int remain[]) { int i; factorize(actual, n); if (actual[1] > maxPrimeFactor) { System.out.println("\nPrime factor of FFT length too large : %6d" + actual[1]); System.out.println("\nPlease modify the value of maxPrimeFactor in mixfft.c"); } remain[0] = n; sofar[1] = 1; remain[1] = n / actual[1]; for (i = 2; i <= nFactor; i++) { sofar[i] = sofar[i - 1] * actual[i - 1]; remain[i] = remain[i - 1] / actual[i]; } } /** * The sequence y is the permuted input sequence x so that the following * transformations can be performed in-place, and the final result is the * normal degree. */ final private void permute(int fact[], int remain[], double xRe[], double xIm[], double yRe[], double yIm[]) { int i, j = 0, k; int[] count = new int[maxFactorCount]; for (i = 1; i <= nFactor; i++) count[i] = 0; k = 0; for (i = 0; i <= n - 2; i++) { yRe[i] = xRe[k]; yIm[i] = xIm[k]; j = 1; k = k + remain[j]; count[1] = count[1] + 1; while (count[j] >= fact[j]) { count[j] = 0; k = k - remain[j - 1] + remain[j + 1]; j = j + 1; count[j] = count[j] + 1; } } yRe[n - 1] = xRe[n - 1]; yIm[n - 1] = xIm[n - 1]; } /* * Twiddle factor multiplications and transformations are performed on a * group of data. The number of multiplications with 1 are reduced by * skipMath.ping the twiddle multiplication of the first stage and of the * first group of the following stages. */ final private void initTrig(final int radix) { int i; double w, xre, xim; w = 2 * Math.PI / radix; trigRe[0] = 1; trigIm[0] = 0; xre = Math.cos(w); xim = -Math.sin(w); trigRe[1] = xre; trigIm[1] = xim; for (i = 2; i < radix; i++) { trigRe[i] = xre * trigRe[i - 1] - xim * trigIm[i - 1]; trigIm[i] = xim * trigRe[i - 1] + xre * trigIm[i - 1]; } } /** * */ private void fft_4(double aRe[], double aIm[]) { double t1_re, t1_im, t2_re, t2_im; double m2_re, m2_im, m3_re, m3_im; t1_re = aRe[0] + aRe[2]; t1_im = aIm[0] + aIm[2]; t2_re = aRe[1] + aRe[3]; t2_im = aIm[1] + aIm[3]; m2_re = aRe[0] - aRe[2]; m2_im = aIm[0] - aIm[2]; m3_re = aIm[1] - aIm[3]; m3_im = aRe[3] - aRe[1]; aRe[0] = t1_re + t2_re; aIm[0] = t1_im + t2_im; aRe[2] = t1_re - t2_re; aIm[2] = t1_im - t2_im; aRe[1] = m2_re + m3_re; aIm[1] = m2_im + m3_im; aRe[3] = m2_re - m3_re; aIm[3] = m2_im - m3_im; } /** * */ private void fft_5(double aRe[], double aIm[]) { double t1_re, t1_im, t2_re, t2_im, t3_re, t3_im; double t4_re, t4_im, t5_re, t5_im; double m2_re, m2_im, m3_re, m3_im, m4_re, m4_im; double m1_re, m1_im, m5_re, m5_im; double s1_re, s1_im, s2_re, s2_im, s3_re, s3_im; double s4_re, s4_im, s5_re, s5_im; t1_re = aRe[1] + aRe[4]; t1_im = aIm[1] + aIm[4]; t2_re = aRe[2] + aRe[3]; t2_im = aIm[2] + aIm[3]; t3_re = aRe[1] - aRe[4]; t3_im = aIm[1] - aIm[4]; t4_re = aRe[3] - aRe[2]; t4_im = aIm[3] - aIm[2]; t5_re = t1_re + t2_re; t5_im = t1_im + t2_im; aRe[0] = aRe[0] + t5_re; aIm[0] = aIm[0] + t5_im; m1_re = c5_1 * t5_re; m1_im = c5_1 * t5_im; m2_re = c5_2 * (t1_re - t2_re); m2_im = c5_2 * (t1_im - t2_im); m3_re = -c5_3 * (t3_im + t4_im); m3_im = c5_3 * (t3_re + t4_re); m4_re = -c5_4 * t4_im; m4_im = c5_4 * t4_re; m5_re = -c5_5 * t3_im; m5_im = c5_5 * t3_re; s3_re = m3_re - m4_re; s3_im = m3_im - m4_im; s5_re = m3_re + m5_re; s5_im = m3_im + m5_im; s1_re = aRe[0] + m1_re; s1_im = aIm[0] + m1_im; s2_re = s1_re + m2_re; s2_im = s1_im + m2_im; s4_re = s1_re - m2_re; s4_im = s1_im - m2_im; aRe[1] = s2_re + s3_re; aIm[1] = s2_im + s3_im; aRe[2] = s4_re + s5_re; aIm[2] = s4_im + s5_im; aRe[3] = s4_re - s5_re; aIm[3] = s4_im - s5_im; aRe[4] = s2_re - s3_re; aIm[4] = s2_im - s3_im; } /** * */ private void fft_8() { double[] aRe = new double[4]; double[] aIm = new double[4]; double[] bRe = new double[4]; double[] bIm = new double[4]; double gem; aRe[0] = zRe[0]; bRe[0] = zRe[1]; aRe[1] = zRe[2]; bRe[1] = zRe[3]; aRe[2] = zRe[4]; bRe[2] = zRe[5]; aRe[3] = zRe[6]; bRe[3] = zRe[7]; aIm[0] = zIm[0]; bIm[0] = zIm[1]; aIm[1] = zIm[2]; bIm[1] = zIm[3]; aIm[2] = zIm[4]; bIm[2] = zIm[5]; aIm[3] = zIm[6]; bIm[3] = zIm[7]; fft_4(aRe, aIm); fft_4(bRe, bIm); gem = c8 * (bRe[1] + bIm[1]); bIm[1] = c8 * (bIm[1] - bRe[1]); bRe[1] = gem; gem = bIm[2]; bIm[2] = -bRe[2]; bRe[2] = gem; gem = c8 * (bIm[3] - bRe[3]); bIm[3] = -c8 * (bRe[3] + bIm[3]); bRe[3] = gem; zRe[0] = aRe[0] + bRe[0]; zRe[4] = aRe[0] - bRe[0]; zRe[1] = aRe[1] + bRe[1]; zRe[5] = aRe[1] - bRe[1]; zRe[2] = aRe[2] + bRe[2]; zRe[6] = aRe[2] - bRe[2]; zRe[3] = aRe[3] + bRe[3]; zRe[7] = aRe[3] - bRe[3]; zIm[0] = aIm[0] + bIm[0]; zIm[4] = aIm[0] - bIm[0]; zIm[1] = aIm[1] + bIm[1]; zIm[5] = aIm[1] - bIm[1]; zIm[2] = aIm[2] + bIm[2]; zIm[6] = aIm[2] - bIm[2]; zIm[3] = aIm[3] + bIm[3]; zIm[7] = aIm[3] - bIm[3]; } /** * */ private void fft_10() { double[] aRe = new double[5]; double[] aIm = new double[5]; double[] bRe = new double[5]; double[] bIm = new double[5]; aRe[0] = zRe[0]; bRe[0] = zRe[5]; aRe[1] = zRe[2]; bRe[1] = zRe[7]; aRe[2] = zRe[4]; bRe[2] = zRe[9]; aRe[3] = zRe[6]; bRe[3] = zRe[1]; aRe[4] = zRe[8]; bRe[4] = zRe[3]; aIm[0] = zIm[0]; bIm[0] = zIm[5]; aIm[1] = zIm[2]; bIm[1] = zIm[7]; aIm[2] = zIm[4]; bIm[2] = zIm[9]; aIm[3] = zIm[6]; bIm[3] = zIm[1]; aIm[4] = zIm[8]; bIm[4] = zIm[3]; fft_5(aRe, aIm); fft_5(bRe, bIm); zRe[0] = aRe[0] + bRe[0]; zRe[5] = aRe[0] - bRe[0]; zRe[6] = aRe[1] + bRe[1]; zRe[1] = aRe[1] - bRe[1]; zRe[2] = aRe[2] + bRe[2]; zRe[7] = aRe[2] - bRe[2]; zRe[8] = aRe[3] + bRe[3]; zRe[3] = aRe[3] - bRe[3]; zRe[4] = aRe[4] + bRe[4]; zRe[9] = aRe[4] - bRe[4]; zIm[0] = aIm[0] + bIm[0]; zIm[5] = aIm[0] - bIm[0]; zIm[6] = aIm[1] + bIm[1]; zIm[1] = aIm[1] - bIm[1]; zIm[2] = aIm[2] + bIm[2]; zIm[7] = aIm[2] - bIm[2]; zIm[8] = aIm[3] + bIm[3]; zIm[3] = aIm[3] - bIm[3]; zIm[4] = aIm[4] + bIm[4]; zIm[9] = aIm[4] - bIm[4]; } /** * */ private void fft_odd(int radix) { double rere, reim, imre, imim; int i, j, k, p, max; p = radix; max = (p + 1) / 2; for (j = 1; j < max; j++) { vRe[j] = zRe[j] + zRe[p - j]; vIm[j] = zIm[j] - zIm[p - j]; wRe[j] = zRe[j] - zRe[p - j]; wIm[j] = zIm[j] + zIm[p - j]; } for (j = 1; j < max; j++) { zRe[j] = zRe[0]; zIm[j] = zIm[0]; zRe[p - j] = zRe[0]; zIm[p - j] = zIm[0]; k = j; for (i = 1; i < max; i++) { rere = trigRe[k] * vRe[i]; imim = trigIm[k] * vIm[i]; reim = trigRe[k] * wIm[i]; imre = trigIm[k] * wRe[i]; zRe[p - j] += rere + imim; zIm[p - j] += reim - imre; zRe[j] += rere - imim; zIm[j] += reim + imre; k = k + j; if (k >= p) k = k - p; } } for (j = 1; j < max; j++) { zRe[0] = zRe[0] + vRe[j]; zIm[0] = zIm[0] + wIm[j]; } } /** * */ final private void twiddleTransf(int sofarRadix, int radix, int remainRadix, double yRe[], double yIm[]) { double cosw, sinw, gem; double t1_re, t1_im, t2_re, t2_im, t3_re, t3_im; double t4_re, t4_im, t5_re, t5_im; double m2_re, m2_im, m3_re, m3_im, m4_re, m4_im; double m1_re, m1_im, m5_re, m5_im; double s1_re, s1_im, s2_re, s2_im, s3_re, s3_im; double s4_re, s4_im, s5_re, s5_im; initTrig(radix); omega = 2 * Math.PI / (double) (sofarRadix * radix); cosw = Math.cos(omega); sinw = -Math.sin(omega); tw_re = 1.0; tw_im = 0; dataOffset = 0; groupOffset = dataOffset; adr = groupOffset; for (dataNo = 0; dataNo < sofarRadix; dataNo++) { if (sofarRadix > 1) { twiddleRe[0] = 1.0; twiddleIm[0] = 0.0; twiddleRe[1] = tw_re; twiddleIm[1] = tw_im; for (twNo = 2; twNo < radix; twNo++) { twiddleRe[twNo] = tw_re * twiddleRe[twNo - 1] - tw_im * twiddleIm[twNo - 1]; twiddleIm[twNo] = tw_im * twiddleRe[twNo - 1] + tw_re * twiddleIm[twNo - 1]; } gem = cosw * tw_re - sinw * tw_im; tw_im = sinw * tw_re + cosw * tw_im; tw_re = gem; } for (groupNo = 0; groupNo < remainRadix; groupNo++) { if ((sofarRadix > 1) && (dataNo > 0)) { zRe[0] = yRe[adr]; zIm[0] = yIm[adr]; blockNo = 1; do { adr = adr + sofarRadix; zRe[blockNo] = twiddleRe[blockNo] * yRe[adr] - twiddleIm[blockNo] * yIm[adr]; zIm[blockNo] = twiddleRe[blockNo] * yIm[adr] + twiddleIm[blockNo] * yRe[adr]; blockNo++; } while (blockNo < radix); } else for (blockNo = 0; blockNo < radix; blockNo++) { zRe[blockNo] = yRe[adr]; zIm[blockNo] = yIm[adr]; adr = adr + sofarRadix; } switch (radix) { case 2: gem = zRe[0] + zRe[1]; zRe[1] = zRe[0] - zRe[1]; zRe[0] = gem; gem = zIm[0] + zIm[1]; zIm[1] = zIm[0] - zIm[1]; zIm[0] = gem; break; case 3: t1_re = zRe[1] + zRe[2]; t1_im = zIm[1] + zIm[2]; zRe[0] = zRe[0] + t1_re; zIm[0] = zIm[0] + t1_im; m1_re = c3_1 * t1_re; m1_im = c3_1 * t1_im; m2_re = c3_2 * (zIm[1] - zIm[2]); m2_im = c3_2 * (zRe[2] - zRe[1]); s1_re = zRe[0] + m1_re; s1_im = zIm[0] + m1_im; zRe[1] = s1_re + m2_re; zIm[1] = s1_im + m2_im; zRe[2] = s1_re - m2_re; zIm[2] = s1_im - m2_im; break; case 4: t1_re = zRe[0] + zRe[2]; t1_im = zIm[0] + zIm[2]; t2_re = zRe[1] + zRe[3]; t2_im = zIm[1] + zIm[3]; m2_re = zRe[0] - zRe[2]; m2_im = zIm[0] - zIm[2]; m3_re = zIm[1] - zIm[3]; m3_im = zRe[3] - zRe[1]; zRe[0] = t1_re + t2_re; zIm[0] = t1_im + t2_im; zRe[2] = t1_re - t2_re; zIm[2] = t1_im - t2_im; zRe[1] = m2_re + m3_re; zIm[1] = m2_im + m3_im; zRe[3] = m2_re - m3_re; zIm[3] = m2_im - m3_im; break; case 5: t1_re = zRe[1] + zRe[4]; t1_im = zIm[1] + zIm[4]; t2_re = zRe[2] + zRe[3]; t2_im = zIm[2] + zIm[3]; t3_re = zRe[1] - zRe[4]; t3_im = zIm[1] - zIm[4]; t4_re = zRe[3] - zRe[2]; t4_im = zIm[3] - zIm[2]; t5_re = t1_re + t2_re; t5_im = t1_im + t2_im; zRe[0] = zRe[0] + t5_re; zIm[0] = zIm[0] + t5_im; m1_re = c5_1 * t5_re; m1_im = c5_1 * t5_im; m2_re = c5_2 * (t1_re - t2_re); m2_im = c5_2 * (t1_im - t2_im); m3_re = -c5_3 * (t3_im + t4_im); m3_im = c5_3 * (t3_re + t4_re); m4_re = -c5_4 * t4_im; m4_im = c5_4 * t4_re; m5_re = -c5_5 * t3_im; m5_im = c5_5 * t3_re; s3_re = m3_re - m4_re; s3_im = m3_im - m4_im; s5_re = m3_re + m5_re; s5_im = m3_im + m5_im; s1_re = zRe[0] + m1_re; s1_im = zIm[0] + m1_im; s2_re = s1_re + m2_re; s2_im = s1_im + m2_im; s4_re = s1_re - m2_re; s4_im = s1_im - m2_im; zRe[1] = s2_re + s3_re; zIm[1] = s2_im + s3_im; zRe[2] = s4_re + s5_re; zIm[2] = s4_im + s5_im; zRe[3] = s4_re - s5_re; zIm[3] = s4_im - s5_im; zRe[4] = s2_re - s3_re; zIm[4] = s2_im - s3_im; break; case 8: fft_8(); break; case 10: fft_10(); break; default: fft_odd(radix); break; } adr = groupOffset; for (blockNo = 0; blockNo < radix; blockNo++) { yRe[adr] = zRe[blockNo]; yIm[adr] = zIm[blockNo]; adr = adr + sofarRadix; } groupOffset = groupOffset + sofarRadix * radix; adr = groupOffset; } dataOffset = dataOffset + 1; groupOffset = dataOffset; adr = groupOffset; } } /* * Perform the FFT for all sizes of signal. */ private void doFFT_Mix(double xRe[], double xIm[], final int size) { // int[] sofarRadix = new int[maxFactorCount]; // int[] actualRadix = new int[maxFactorCount]; // int[] remainRadix = new int[maxFactorCount]; int count; // Mod // Math.pi = 4*Math.atan(1); n = size; transTableSetup(sofarRadix, actualRadix, remainRadix); permute(actualRadix, remainRadix, xRe, xIm, yReOut, yImOut); for (count = 1; count <= nFactor; count++) twiddleTransf(sofarRadix[count], actualRadix[count], remainRadix[count], yReOut, yImOut); // Copy results for (int i = 0; i < n; i++) { xRe[i] = yReOut[i]; xIm[i] = yImOut[i]; } } /* * Perform the FFT for all sizes of signal, the start and the length of the * FFT can be choosen to transform a part of a signal. */ private void doFFT_Mix(double xRe[], double xIm[], final int size, final int shift) { double[] tmp_xRe = new double[size]; double[] tmp_xIm = new double[size]; for (int i = 0; i < size; i++) { tmp_xRe[i] = xRe[i + shift]; tmp_xIm[i] = xIm[i + shift]; } doFFT_Mix(tmp_xRe, tmp_xIm, size); for (int i = 0; i < size; i++) { xRe[i + shift] = tmp_xRe[i]; xIm[i + shift] = tmp_xIm[i]; } } /* * Perform the IFFT for all sizes of signal. */ private void doIFFT_Mix(double xRe[], double xIm[], final int size) { for (int i = 0; i < size; i++) { xIm[i] = -xIm[i]; } doFFT_Mix(xRe, xIm, size); for (int i = 0; i < size; i++) { xRe[i] = xRe[i] / size; xIm[i] = -xIm[i] / size; } } /* * Perform the IFFT for all sizes of signal, the start and the length of the * IFFT can be choosen to transform a part of a signal. */ private void doIFFT_Mix(double xRe[], double xIm[], final int size, final int shift) { double[] tmp_xRe = new double[size]; double[] tmp_xIm = new double[size]; for (int i = 0; i < size; i++) { tmp_xRe[i] = xRe[i + shift]; tmp_xIm[i] = xIm[i + shift]; } doIFFT_Mix(tmp_xRe, tmp_xIm, size); for (int i = 0; i < size; i++) { xRe[i + shift] = tmp_xRe[i]; xIm[i + shift] = tmp_xIm[i]; } } } // end of class \ No newline at end of file diff --git a/src/bilib/src/polyharmonicwavelets/GammaFunction.java b/src/bilib/src/polyharmonicwavelets/GammaFunction.java new file mode 100644 index 0000000000000000000000000000000000000000..aa2ec7e6e75d228cb259cb69a78813b1618b9324 --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/GammaFunction.java @@ -0,0 +1,208 @@ + +//package dr.math; + +package polyharmonicwavelets; + +/** + * (This file is part of BEAST) Computes the Gamma function. + * <p> + * Copyright (C) 2002-2006 Alexei Drummond and Andrew Rambaut + * <p> + * This file is part of BEAST. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership and licensing. + * <p> + * BEAST is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) any + * later version. + * <p> + * BEAST is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * <p> + * You should have received a copy of the GNU Lesser General Public License + * along with BEAST; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA<br> + * + * @author Korbinian Strimmer + * + */ +public class GammaFunction { + // + // Public stuff + // + + // Gamma function + + /** + * log Gamma function: ln(gamma(alpha)) for alpha>0, accurate to 10 decimal + * places + * + * @param alpha + * argument + * @return the log of the gamma function of the given alpha + */ + public static double lnGamma(double alpha) { + // Pike MC & Hill ID (1966) Algorithm 291: Logarithm of the gamma + // function. + // Communications of the Association for Computing Machinery, 9:684 + + double x = alpha, f = 0.0, z; + + if (x < 7) { + f = 1; + z = x - 1; + while (++z < 7) { + f *= z; + } + x = z; + f = -Math.log(f); + } + z = 1 / (x * x); + + return f + (x - 0.5) * Math.log(x) - x + 0.918938533204673 + (((-0.000595238095238 * z + 0.000793650793651) * z - 0.002777777777778) * z + 0.083333333333333) / x; + } + + /** + * Incomplete Gamma function Q(a,x) (a cleanroom implementation of Numerical + * Recipes gammq(a,x); in Mathematica this function is called + * GammaRegularized) + * + * @param a + * parameter + * @param x + * argument + * @return function value + */ + public static double incompleteGammaQ(double a, double x) { + return 1.0 - incompleteGamma(x, a, lnGamma(a)); + } + + /** + * Incomplete Gamma function P(a,x) = 1-Q(a,x) (a cleanroom implementation + * of Numerical Recipes gammp(a,x); in Mathematica this function is + * 1-GammaRegularized) + * + * @param a + * parameter + * @param x + * argument + * @return function value + */ + public static double incompleteGammaP(double a, double x) { + return incompleteGamma(x, a, lnGamma(a)); + } + + /** + * Incomplete Gamma function P(a,x) = 1-Q(a,x) (a cleanroom implementation + * of Numerical Recipes gammp(a,x); in Mathematica this function is + * 1-GammaRegularized) + * + * @param a + * parameter + * @param x + * argument + * @param lnGammaA + * precomputed lnGamma(a) + * @return function value + */ + public static double incompleteGammaP(double a, double x, double lnGammaA) { + return incompleteGamma(x, a, lnGammaA); + } + + /** + * Returns the incomplete gamma ratio I(x,alpha) where x is the upper limit + * of the integration and alpha is the shape parameter. + * + * @param x + * upper limit of integration + * @param alpha + * shape parameter + * @param ln_gamma_alpha + * the log gamma function for alpha + * @return the incomplete gamma ratio + */ + private static double incompleteGamma(double x, double alpha, double ln_gamma_alpha) { + // (1) series expansion if (alpha>x || x<=1) + // (2) continued fraction otherwise + // RATNEST FORTRAN by + // Bhattacharjee GP (1970) The incomplete gamma integral. Applied + // Statistics, + // 19: 285-287 (AS32) + + double accurate = 1e-8, overflow = 1e30; + double factor, gin, rn, a, b, an, dif, term; + double pn0, pn1, pn2, pn3, pn4, pn5; + + if (x == 0.0) { + return 0.0; + } + // System.out.println("x="+x+" alpha="+alpha); + if (x < 0.0 || alpha <= 0.0) { + throw new IllegalArgumentException("Arguments out of bounds"); + } + + factor = Math.exp(alpha * Math.log(x) - x - ln_gamma_alpha); + + if (x > 1 && x >= alpha) { + // continued fraction + a = 1 - alpha; + b = a + x + 1; + term = 0; + pn0 = 1; + pn1 = x; + pn2 = x + 1; + pn3 = x * b; + gin = pn2 / pn3; + + do { + a++; + b += 2; + term++; + an = a * term; + pn4 = b * pn2 - an * pn0; + pn5 = b * pn3 - an * pn1; + + if (pn5 != 0) { + rn = pn4 / pn5; + dif = Math.abs(gin - rn); + if (dif <= accurate) { + if (dif <= accurate * rn) { + break; + } + } + + gin = rn; + } + pn0 = pn2; + pn1 = pn3; + pn2 = pn4; + pn3 = pn5; + if (Math.abs(pn4) >= overflow) { + pn0 /= overflow; + pn1 /= overflow; + pn2 /= overflow; + pn3 /= overflow; + } + } + while (true); + gin = 1 - factor * gin; + } + else { + // series expansion + gin = 1; + term = 1; + rn = alpha; + do { + rn++; + term *= x / rn; + gin += term; + } + while (term > accurate); + gin *= factor / alpha; + } + return gin; + } + +} diff --git a/src/bilib/src/polyharmonicwavelets/Parameters.java b/src/bilib/src/polyharmonicwavelets/Parameters.java new file mode 100644 index 0000000000000000000000000000000000000000..6ee099fd5a7f535f82ac411700496c4be2bfea9a --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/Parameters.java @@ -0,0 +1,139 @@ +package polyharmonicwavelets; + +// +// Parameters.java +// PolyharmonicWavelets +// +// Created by Biomedical Imaging Group on 2/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +/** + * This class stores all the parameters neded to perform the wavelet transform. + */ + +public class Parameters { + /** + * If true, only compute the analyses filters. + */ + public boolean analysesonly = false; + /** + * If rieszfreq=1 analysis wavelet filter will be multiplied by V2. Used for + * Riesz transform. No need to change this, it is not a user input. + */ + public int rieszfreq = 0; + /** + * Constant that defines the polyharmonic B-spline flavor. + */ + public final static int BSPLINE = 0; + /** + * Constant that defines the orthogonal flavor, quincunx only. + */ + public final static int ORTHOGONAL = 1; + /** + * Constant that defines the dual of the B-spline. + */ + public final static int DUAL = 2; + /** + * Constant that defines the operator wavelet. + */ + public final static int OPERATOR = 3; + /** + * Constant that defines the Marr wavelet. + */ + public final static int MARR = 7; + /** + * Constant that defines the dual of the operator. + */ + public final static int DUALOPERATOR = 8; + /** + * Defines the wavelet flavor: BSPLINE, ORTHOGONAL, DUAL, OPERATOR, MARR or + * DUALOPERATOR. + */ + public int flavor = ORTHOGONAL; + + /** + * Constant that defines the basis transform. + */ + public final static int BASIS = 0; + /** + * Constant that defines the fully redundant transform. + */ + public final static int REDUNDANT = 1; + /** + * Constant that defines the pyramid transform. + */ + public final static int PYRAMID = 2; + /** + * The redundancy, should be set to BASIS, PYRAMID, or REDUNDANT. + */ + public int redundancy = PYRAMID; + /** + * Constant that defines standard isotropic polyharmonic Bspline. + */ + public final static int ISOTROPIC = 1; + /** + * Constant that defines isotropic polyharmonic Bspline that allowes to + * change standard deviation. + */ + public final static int CHANGESIGMA = 4; + /** + * Te isotropy type. + */ + public int type = ISOTROPIC; + /** + * Defines the standard deviation of gaussian if type=changesigma + */ + public double s2 = 6.0; // only used if + // type=changesigma + /** + * Constant that defines the quincunx lattice. + */ + public final static int QUINCUNX = 0; + /** + * Constant that defines the dyadic lattice. + */ + public final static int DYADIC = 1; + /** + * The lattice type, set to QUINCUNX or DYADIC. + */ + public int lattice = DYADIC; + + /** + * This parameter defines whether the prefilter should be used (if true) or + * not (if false). + */ + public boolean prefilter = true; + + /** + * Constant that defines the iterative method for computing the + * autocorrelation. + */ + public final static int ITERATIVE = 0; + /** + * Constant that defines the gamma function method for computing the + * autocorrelation. + */ + public final static int GAMMA = 1; + /** + * This parameter defines the autocorrelation computation method, GAMMA or + * ITERATIVE. + */ + public int accompute = GAMMA; + + /** + * The B-spline order, gamma. + */ + public double order = 2.0; + + /** + * The iterate of a rotation covariant operator. Usually 0 for polyharmonic + * wavelets or 1 for Marr wavelets, but other values are also possible. + */ + public int N = 1; + + /** + * The number of wavelet decomposition levels. + */ + public int J = 1; +} diff --git a/src/bilib/src/polyharmonicwavelets/QuincunxFilters.java b/src/bilib/src/polyharmonicwavelets/QuincunxFilters.java new file mode 100644 index 0000000000000000000000000000000000000000..3992040c40e1b09042b86bdbc2b5433a6d251be5 --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/QuincunxFilters.java @@ -0,0 +1,505 @@ +package polyharmonicwavelets; + +// +// QuincunxFilters.java +// PolyharmonicWavelets +// +// Created by Biomedical Imaging Group on 2/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +import java.util.*; +import ij.*; +import java.text.DecimalFormat; + +/** + * This class computes the filters for the quincunx wavelet transform. + * + * @author Katarina Balac, EPFL. + */ + +public class QuincunxFilters { + + /** + * The analysis filters. FA[0] lowpass analysis filter for odd iteration + * FA[1] highpass analysis filter for odd iteration FA[2] lowpass analysis + * filter for even iteration FA[3] highpass analysis filter for even + * iteration + */ + public ComplexImage[] FA; + + /** + * The synthesis filters. FS[0] lowpass synthesis filter for odd iteration + * FS[1] highpass synthesis filter for odd iteration FS[2] lowpass synthesis + * filter for even iteration FS[3] highpass synthesis filter for even + * iteration + */ + public ComplexImage[] FS; + + /** + * The prefilter. + */ + public ComplexImage P; // Prefilter + private Parameters param; // Parameters for the + // transform + private int nx; // Size of filters + private int ny; + private final double PI2 = 2.0 * Math.PI; + private final double PI = Math.PI; + + /** + * Constructor, creates a QuincunxFilters objectand computes all the + * filters. + * + * @param par + * the wavelet transform parameters + * @param sizex + * the number of columns in the image to transform + * @param sizey + * the number of rows in the image to transform + */ + + public QuincunxFilters(Parameters par, int sizex, int sizey) { + param = par; + nx = sizex; + ny = sizey; + FA = new ComplexImage[4]; + FS = new ComplexImage[4]; + calculateFilters(); + } + + /* + * Performs linear interpolation on the real part of ComplexImage ac as + * ac[w]=ac[Dw], where D is the quincunx subsampling matrix and w is a two + * element column vector with w1 and w2 uniformly distributed from 0 to + * 2*PI, and ac[w1+2*k*PI,w2+2*n*PI]=ac[w1,w2] for all k and n integer. + */ + + private ComplexImage interpolateQuincunxReal(ComplexImage ac) { + ComplexImage out = new ComplexImage(nx, ny, ac.imag == null); + int nx1 = nx - 1; + int ny1 = ny - 1; + for (int cy = 0; cy < ny; cy++) { + for (int cx = 0; cx < nx; cx++) { + // calculate (x+y)mod(2pi),(y-x)mod(2pi) + double x = ((double) cx / (double) nx) * PI2; + double y = ((double) cy / (double) ny) * PI2; + double sum = x + y; + double dif = y - x; + // Find closest integers to x,y + double x1 = sum * (double) nx / PI2; + double y1 = dif * (double) ny / PI2; + double fx = Math.floor(x1); + double fy = Math.floor(y1); + x1 = x1 - fx; + y1 = y1 - fy; + int kx = (int) fx; + int ky = (int) fy; + while (ky > ny1) + ky -= ny; + while (ky < 0) + ky += ny; + while (kx > nx1) + kx -= nx; + while (kx < 0) + kx += nx; + int ky1 = ky + 1; + while (ky1 > ny1) + ky1 -= ny; + int kx1 = kx + 1; + while (kx1 > nx1) + kx1 -= nx; + double a = ac.real[nx * ky1 + kx1]; + double b = ac.real[nx * ky1 + kx]; + double c = ac.real[nx * ky + kx]; + double d = ac.real[nx * ky + kx1]; + double res = y1 * (x1 * a + (1.0 - x1) * b) + (1.0 - y1) * (x1 * d + (1.0 - x1) * c); + out.real[cy * nx + cx] = res; + } + } + return out; + } + + /* + * Returns the numenator of scaling function, localization support is [ minx + * : (maxx-minx)/sizex : maxx-(maxx-minx)/sizex, miny : (maxy-miny)/sizey : + * maxy-(maxy-miny)/sizey ] output is of size [sizex, sizey] and defined + * on[minx...maxx-eps,miny...maxy-eps] type=0, dyadic type=1, quincunx, + * computes V(D^tw) + */ + + private ComplexImage localization(int sizex, int sizey, double minx, double miny, double maxx, double maxy, double gama, int N, int type) { + ComplexImage result = new ComplexImage(sizex, sizey, N == 0); + double gama2 = gama / 2.0; + double epsx = PI2 / (5.0 * (double) sizex); + double epsy = PI2 / (5.0 * (double) sizey); + final double d83 = 8.0 / 3.0; + final double d23 = 2.0 / 3.0; + for (int ky = 0; ky < sizey; ky++) { + int kxy = ky * sizex; + double rx = (maxx - minx) / (double) sizex; + double ry = (maxy - miny) / (double) sizey; + for (int kx = 0, index = kxy; kx < sizex; kx++, index++) { + double y = miny + (double) ky * ry; + double x = minx + (double) kx * rx; + if (type == 1) { // quincunx + double xt = x; + double yt = y; + x = xt + yt; + y = yt - xt; + } + double y1 = y; + while (y1 >= Math.PI - epsy) + y1 = y1 - PI2; + while (y1 < -Math.PI - epsy) + y1 = y1 + PI2; + double x1 = x; + while (x1 >= Math.PI - epsx) + x1 = x1 - PI2; + while (x1 < -Math.PI - epsx) + x1 = x1 + PI2; + double a = 1.0; + // Compute modulus of localization depending on type + double sx = Math.sin(x / 2); + sx = sx * sx; + double sy = Math.sin(y / 2); + sy = sy * sy; + if (param.type == param.ISOTROPIC) { // Isotropic + a = 4.0 * (sx + sy) - d83 * (sx * sy); + } + if (param.type == param.CHANGESIGMA) { + final double sigma2 = param.s2; + final double b = -16.0 / sigma2; + final double c = 24.0 / (sigma2 * sigma2) - 16.0 / (3.0 * sigma2); + final double d = 8.0 / (sigma2 * sigma2) + 32.0 / 45.0 - 16.0 / (3.0 * sigma2); + final double e = 4.0 / 3.0 - 8.0 / sigma2; + a = 4.0 * (sx + sy) + b * (sx * sy) + c * (sx * sx * sy + sy * sy * sx) + d * (sx * sx * sx + sy * sy * sy) + e * (sx * sx + sy * sy); + } + double re = Math.pow(a, gama2); + double im = 0.0; + if (N > 0) { + for (int i = 0; i < N; i++) { + double re1 = re * x1 - im * y1; + double im1 = re * y1 + im * x1; + re = re1; + im = im1; + } + double t = Math.pow(x1 * x1 + y1 * y1, (double) N / 2.0); + if (t == 0.0) { + result.real[index] = 0.0; + result.imag[index] = 0.0; + } + else { + result.real[index] = re / t; + result.imag[index] = im / t; + } + } + else { + result.real[index] = re; + } + } + } + return result; + } + + /* + * Calculates denominator of scaling function support is [ 0 : maxx/sizex : + * maxx-maxx/sizex, 0 : maxy/sizey : maxy-maxy/sizey ] output is of size + * [sizex, sizey] and defined on[0...maxx-eps,0...maxy-eps] + */ + + private ComplexImage denominator(int sizex, int sizey, double minx, double miny, double maxx, double maxy, int N) { + ComplexImage result = new ComplexImage(sizex, sizey); + double gamaN2; + gamaN2 = (param.order - N) / 2.0; + for (int ky = 0; ky < sizey; ky++) { + int kxy = ky * sizex; + double y = miny + (double) ky * (maxy - miny) / (double) sizey; + for (int kx = 0, index = kxy; kx < sizex; kx++, index++) { + double x = minx + (double) kx * (maxx - minx) / (double) sizex; + double re = Math.pow(x * x + y * y, gamaN2); + double im = 0.0; + if (N > 0) { + for (int i = 0; i < N; i++) { + double re1 = re * x - im * y; + double im1 = re * y + im * x; + re = re1; + im = im1; + } + result.real[index] = re; + result.imag[index] = im; + } + else { + result.real[index] = re; + } + } + } + return result; + } + + /* + * Computes prefilter + */ + + private void quincunxPrefilter(ComplexImage ac) { + P = new ComplexImage(nx, ny, true); + P.settoConstant(1.0); + P = localization(nx, ny, -PI, -PI, PI, PI, param.order, 0, 0); + ComplexImage d = denominator(nx, ny, -PI, -PI, PI, PI, 0); + P.divide(d, 1.0, 0.0); + P.shift(); + if (param.flavor == param.ORTHOGONAL) { + ComplexImage acsqrt = ac.copyImage(); + acsqrt.rootReal(); + P.divide(acsqrt); + } + if ((param.flavor == param.BSPLINE) || (param.flavor == param.DUALOPERATOR)) { + P.divide(ac); + } + } + + /* + * Computesall the filters for odd iteration B-refinement filter for the + * quincunx lattice ortho-orthonormalizing factor ac - autocorrelation acD - + * sampled autocorrelation it-number of iteration if it=0 computes filters + * for odd iteration, if it=1 for even iteration H - analysis highpass H1 - + * synthesis highpass L1 - analysis lowpass L - synthesis lowpass if even, + * even iteration, else, odd iteration + */ + + private void computeLowpassHighpass(ComplexImage B, ComplexImage ac, ComplexImage acD, ComplexImage loc, boolean even) { + ComplexImage L = null; + ComplexImage L1 = null; + ComplexImage H = null; + ComplexImage H1 = null; + ComplexImage ortho = acD.copyImage(); + ortho.divide(ac); + final double sqrt2 = Math.sqrt(2.0); + B.multiply(sqrt2); + if (param.flavor == param.ORTHOGONAL) { + ComplexImage orthot = ortho; + orthot.rootReal(); + L1 = B; + L1.divide(orthot); + H = L1.copyImage(); + if (even) { + H.shift(); + } + else { + H.shiftY(); + } + if (!param.analysesonly) { + L = L1.copyImage(); + H1 = H.copyImage(); + H1.conj(); + } + L1.conj(); + } + if (param.flavor == param.DUAL) { + L1 = B.copyImage(); + if (even) { + ac.shift(); + B.shift(); + } + else { + ac.shiftY(); + B.shiftY(); + } + H = B.copyImage(); + H.conj(); + H.multiply(ac); + if (!param.analysesonly) { + L = L1.copyImage(); + L.divide(ortho); + L.conj(); + H1 = B; + H1.divide(acD); + } + } + if (param.flavor == param.BSPLINE) { + L1 = B.copyImage(); + L1.divide(ortho); + L1.conj(); + if (!param.analysesonly) { + L = B.copyImage(); + H = B.copyImage(); + H.divide(acD); + } + if (even) { + B.shift(); + } + else { + B.shiftY(); + } + H1 = B; + H1.conj(); + ac.shift(); + H1.multiply(ac); + } + if (param.flavor == param.OPERATOR) { + L1 = B.copyImage(); + ComplexImage ac0 = ac.copyImage(); + ComplexImage loc0 = loc; + loc0.multiply(sqrt2); + if (even) { + ac.shift(); + B.shift(); + } + else { + ac.shiftY(); + B.shiftY(); + } + if (!param.analysesonly) { + L = L1.copyImage(); + L.divide(ortho); + L.conj(); + H1 = B; + H1.squareModulus(); + H1.multiply(ac); + H1.multiply(ac0); + H1.divide(loc0, 0.0, 0.0); + H1.divide(acD, 0.0, 0.0); + H1.conj(); + } + H = loc0; + H.conj(); + H.divide(ac0); + } + if (param.flavor == param.DUALOPERATOR) { + L1 = B.copyImage(); + if (!param.analysesonly) { + L = L1.copyImage(); + L.conj(); + H1 = loc.copyImage(); + H1.multiply(sqrt2); + H1.divide(ac); + } + L1.divide(ortho); + ComplexImage ac0 = ac.copyImage(); + ComplexImage loc0 = loc; + if (even) { + ac.shift(); + ortho.shift(); + B.shift(); + } + else { + ac.shiftY(); + ortho.shiftY(); + B.shiftY(); + } + H = B; + H.squareModulus(); + H.multiply(1.0 / Math.sqrt(2.0)); + H.multiply(ac); + H.multiply(ac0); + H.divide(loc0, 0.0, 0.0); + H.divide(acD, 0.0, 0.0); + } + if (param.flavor == param.MARR) { + loc.multiply(sqrt2); + L1 = B.copyImage(); + ComplexImage ac0 = ac.copyImage(); + ComplexImage loc0 = loc; + if (even) { + ac.shift(); + B.shift(); + } + else { + ac.shiftY(); + B.shiftY(); + } + if (!param.analysesonly) { + H1 = B; + H1.squareModulus(); + H1.multiply(ac); + H1.multiply(ac0); + H1.divide(loc0, 0.0, 0.0); + H1.divide(acD); + H1.conj(); + L = L1.copyImage(); + L.divide(ortho); + L.conj(); + } + H = loc0; + H.conj(); + } + if (even) { + if (param.redundancy == param.BASIS) { + H.modulateMinusY(); + if (!param.analysesonly) { + H1.modulatePlusY(); + } + } + if ((param.redundancy == param.PYRAMID) && (!param.analysesonly)) { + H1.modulatePlusY(); + } + FA[1] = H; + FS[1] = H1; + FA[0] = L1; + FS[0] = L; + } + else { + if (param.redundancy == param.BASIS) { + H.modulateMinusQuincunx(); + if (!param.analysesonly) { + H1.modulatePlusQuincunx(); + } + } + if ((param.redundancy == param.PYRAMID) && (!param.analysesonly)) { + H1.modulatePlusQuincunx(); + } + FA[3] = H; + FS[3] = H1; + FA[2] = L1; + FS[2] = L; + } + } + + /** + * Computes all filters needed for the quincunx transform. + */ + + public void calculateFilters() { + ComplexImage ac = null; + ComplexImage L = null; + ComplexImage LD = localization(nx, ny, 0.0, 0.0, PI2, PI2, param.order, param.N, 1); + double c = Math.pow(0.5, param.order / 2.0); + if (param.accompute == param.ITERATIVE) { + int nx2 = 2 * nx; + int ny2 = 2 * ny; + ComplexImage Ldouble = localization(2 * nx, 2 * ny, 0.0, 0.0, PI2, PI2, param.order, param.N, 1); + L = Ldouble.copyImage(); + L.decimateCrop(); + ComplexImage H = localization(2 * nx, 2 * ny, 0.0, 0.0, 2.0 * PI2, 2.0 * PI2, param.order, param.N, 0); + H.multiply(c * c); + H.divide(Ldouble, 1.0, 0.0); + ac = H; + ac.squareModulus(); + ac = Autocorrelation.autocorrIterative(ac); + } + else { + L = localization(nx, ny, 0.0, 0.0, PI2, PI2, param.order, param.N, 0); + ComplexImage simpleloc = localization(nx, ny, 0.0, 0.0, PI2, PI2, 2 * param.order, 0, 0); + ac = Autocorrelation.autocorrGamma(simpleloc, param.order); + } + ComplexImage B = LD.copyImage(); + B.multiply(c); + B.divide(L, Math.cos(0.25 * PI * (double) param.N), -Math.sin(0.25 * PI * (double) param.N)); + // Interpolation to calculate acD + ComplexImage acD = interpolateQuincunxReal(ac); + ComplexImage loc = L; + quincunxPrefilter(ac); + ComplexImage ac0 = ac.copyImage(); + ComplexImage loc0 = loc.copyImage(); + computeLowpassHighpass(B, ac, acD, loc, true); + B = loc0; + B.decimate(); + B.multiply(c); + B.divide(LD, Math.cos(0.25 * PI * (double) param.N), -Math.sin(0.25 * PI * (double) param.N)); + loc = LD; + ac = acD; + acD = ac0; + acD.decimate(); + computeLowpassHighpass(B, ac, acD, loc, false); + } +} diff --git a/src/bilib/src/polyharmonicwavelets/QuincunxTransform.java b/src/bilib/src/polyharmonicwavelets/QuincunxTransform.java new file mode 100644 index 0000000000000000000000000000000000000000..f97d3eaaa3ed2be3d12f0e9f80add68b64f0b118 --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/QuincunxTransform.java @@ -0,0 +1,561 @@ +package polyharmonicwavelets; + +// +// QuincunxTransform.java +// PolyharmonicWavelets +// +// Created by Biomedical Imaging Group on 2/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +import java.util.*; +import ij.*; +import java.text.DecimalFormat; +import ij.text.*; +import ij.process.*; +import ij.plugin.filter.PlugInFilter; + +/** + * This class performs basis, pyramid and redundant quincunx transform. + * + * @author Katarina Balac, EPFL. + */ + +public class QuincunxTransform { + + // Analysis and synthesis filters + // FA[0]=H1 + // FA[1]=G1 + // FA[2]=H1D + // FA[3]=G1D + // similar for analysis filters + // H - lowpass filters + // G - highpass filters + // H1,G1 - filters for odd iteration + // H1D, G1D - filters for even iteration + // if transform is pyramid, filters for pyramid transform are FP: + // FP[0]=Gls + // FP[1]=GlsD + + private Parameters param; + private ComplexImage[] FA; + private ComplexImage[] FS; + private ComplexImage[] FP; + private ComplexImage P; + private int J; // number of iterations + private final double PI2 = 2.0 * Math.PI; + private final double sqrt2 = Math.sqrt(2.0); + + /** + * Creates a QuincunxTransform object. + * + * @param filt + * the filters used for the transform + * @param par + * the transform parameters + */ + + public QuincunxTransform(QuincunxFilters filt, Parameters par) { + J = par.J; + param = par; + FA = new ComplexImage[4]; + FS = new ComplexImage[4]; + for (int i = 0; i < 4; i++) { + FA[i] = filt.FA[i]; + FS[i] = filt.FS[i]; + } + P = filt.P.copyImage(); + } + + /** + * Performs the in-place nonredundant quincunx analysis on the input + * ComplexImage. + * + * @param image + * the image to transform + */ + + public void quincunxAnalysis(ComplexImage image) { + ComplexImage H1 = FA[0]; // Filters for odd iteration + ComplexImage G1 = FA[1]; + H1.multiply(0.5); + G1.multiply(0.5); + ComplexImage H1Dl = FA[2].getSubimage(0, FA[2].nx / 2 - 1, 0, FA[2].ny - 1); // Filters + // for + // even + // iteration + ComplexImage G1Dl = FA[3].getSubimage(0, FA[3].nx / 2 - 1, 0, FA[3].ny - 1); + H1Dl.multiply(0.5); + G1Dl.multiply(0.5); + ComplexImage Y1 = null; // lowpass subband + ComplexImage Y2 = null; // highpass subband + ComplexImage R = image.copyImage(); // remaining lowpass subband + R.FFT2D(); + if (param.prefilter) { + R.multiply(P); + } + int l = 1; + for (int j = 1; j <= J; j++) { + int mj = j % 2; + if (mj == 1) { // odd iteration + // filtering: Y1=R*H1 Y2=R*G1 + Y1 = R.copyImage(); + Y1.multiply(H1, l); + Y2 = R.copyImage(); + Y2.multiply(G1, l); + Y1.quincunxDownUp(); + if (!(j == J)) { // not last itteration, leave only left half of + // Y1 + Y1 = Y1.getSubimage(0, Y1.nx / 2 - 1, 0, Y1.ny - 1); + } + Y2.quincunxDownUp(); + // Transform highpass subband Y2 and put it in image + Y2.iFFT2D(); + Y2.fold(); + image.putSubimage(Y2.nx, 0, Y2); + } + else { // even iteration + Y1 = R.copyImage(); + Y1.multiply(H1Dl, l); + Y2 = R.copyImage(); + Y2.multiply(G1Dl, l); + // Downsampling + Y1.dyadicDownY(); + Y2.dyadicDownY(); + // Transform highpass subband Y2 and put it in image + Y2.iFFT2D(); + image.putSubimage(0, Y2.ny, Y2); + l *= 2; + } + R = Y1; + } + // insert lowpass subband + Y1.iFFT2D(); + if (J % 2 == 1) { + Y1.fold(); + } + H1.multiply(2.0); + G1.multiply(2.0); + image.putSubimage(0, 0, Y1); + } + + /** + * Performs the in-place nonredundant quincunx synthesis of image. + * + * @param image + * the image to transform + */ + + public void quincunxSynthesis(ComplexImage image) { + ComplexImage H1 = FS[0]; + ComplexImage G1 = FS[1]; + ComplexImage H1D = FS[2]; + ComplexImage G1D = FS[3]; + int p = (J - J % 2) / 2; + int l = 1; + for (int k = 0; k < p; k++, l *= 2) + ; + // Size of lowpass subband + int cy = image.ny / l; + int cx = image.nx / l; + if (J % 2 == 1) { + cx = cx / 2; + } + // Get lowpasssubband + ComplexImage Y1 = image.getSubimage(0, cx - 1, 0, cy - 1); + if (J % 2 == 1) { + Y1.unfold(); + } + Y1.FFT2D(); + for (int j = J; j > 0; j--) { + int mj = j % 2; + if (mj == 1) { // odd iteration + // Get highpass + ComplexImage Y2 = image.getSubimage(cx, 2 * cx - 1, 0, cy - 1); + cx *= 2; + Y2.unfold(); + Y2.FFT2D(); + // filtering + Y1.multiplyCircular(H1, l); + Y2.multiplyCircular(G1, l); + Y1.add(Y2); + } + else { // even iteration + // Get highpass + ComplexImage Y2 = image.getSubimage(0, cx - 1, cy, 2 * cy - 1); + cy *= 2; + Y2.FFT2D(); + l /= 2; + Y1.dyadicUpsample(); + Y2.dyadicUpsample(); + // filtering + Y1.multiplyCircular(H1D, l); + Y2.multiplyCircular(G1D, l); + Y1.add(Y2); + } + } + image.real = Y1.real; + image.imag = Y1.imag; + if (param.prefilter) { + image.divide(P, 1.0, 0.0); + } + image.iFFT2D(); + } + + /** + * Returns the fully redundant quincunx analysis of image. + * + * @param image + * the image to transform + * @return the array of quincunx transform subbands + */ + + public ComplexImage[] quincunxAnalysisRedundant(ComplexImage image) { + ComplexImage H = FA[0]; // Lowpass odd iteration filter + ComplexImage G = FA[1]; // Highpass odd iteration filter + ComplexImage HD = FA[2]; // Lowpass even iteration filter + ComplexImage GD = FA[3]; // Highpass even iteration filter + G.multiply(sqrt2); + GD.multiply(sqrt2); + H.multiply(sqrt2); + HD.multiply(sqrt2); + double sqrt2inv = 1.0 / sqrt2; + ComplexImage[] array = new ComplexImage[J + 1]; + int l = 1; + // Next index in array + ComplexImage R = image.copyImage(); + R.FFT2D(); + if (param.prefilter) { + R.multiply(P); + } + for (int j = 1; j < J + 1; j++) { + int k = j - 1; + array[k] = R.copyImage(); + if (j % 2 == 1) { // odd iteration + array[k].multiplyCircular(G, l); // Multiply with highpass odd + // iteration filter + R.multiplyCircular(H, l); // Multiply with lowpass odd iteration + // filter + } + else { + array[k].multiplyCircular(GD, l); // Multiply with highpass even + // iteration filter + R.multiplyCircular(HD, l); // Multiply with lowpass even + // iteration filter + l *= 2; + } + array[k].multiply(sqrt2inv); + R.multiply(sqrt2inv); + array[k].iFFT2D(); + } + array[J] = R.copyImage(); + array[J].iFFT2D(); + G.multiply(1.0 / sqrt2); + GD.multiply(1.0 / sqrt2); + H.multiply(1.0 / sqrt2); + HD.multiply(1.0 / sqrt2); + return array; + } + + /** + * Returns the fully redundant quincunx synthesis of array. + * + * @param array + * subbands of fully redundant quincunx transform + * @return the result of synthesis + */ + + public ComplexImage quincunxSynthesisRedundant(ComplexImage[] array) { + ComplexImage H = FS[0]; // Lowpass odd iteration filter + ComplexImage G = FS[1]; // Highpass odd iteration filter + ComplexImage HD = FS[2]; // Lowpass even iteration filter + ComplexImage GD = FS[3]; // Highpass even iteration filter + G.multiply(1.0 / sqrt2); + GD.multiply(1.0 / sqrt2); + H.multiply(1.0 / sqrt2); + HD.multiply(1.0 / sqrt2); + double sqrt2inv = 1.0 / Math.sqrt(2.0); + ComplexImage LP = array[J]; + ComplexImage HP; + LP.FFT2D(); + int l = 1; + for (int j = 1; j < (J + 1) / 2; j++, l *= 2) + ; + for (int j = J; j > 0; j--) { + HP = array[j - 1]; + HP.FFT2D(); + if (j % 2 == 1) { // odd iteration + HP.multiplyCircular(G, l); // Multiply with highpass odd + // iteration filter + LP.multiplyCircular(H, l); // Multiply with lowpass odd + // iteration filter + l /= 2; + } + else { + HP.multiplyCircular(GD, l); // Multiply with highpass even + // iteration filter + LP.multiplyCircular(HD, l); // Multiply with lowpass even + // iteration filter + } + LP.add(HP); + LP.multiply(sqrt2inv); + } + if (param.prefilter) { + LP.divide(P, 1.0, 0.0); + } + LP.iFFT2D(); + G.multiply(sqrt2); + GD.multiply(sqrt2); + H.multiply(sqrt2); + HD.multiply(sqrt2); + return LP; + } + + /** + * Returns the result of pyramid quincunx analysis of ComplexImage. + * + * @param image + * the image to transform + * @return the array of quincunx transform subbands + */ + + public ComplexImage[] quincunxAnalysisPyramid(ComplexImage image) { + ComplexImage[] array = new ComplexImage[J + 1]; + ComplexImage H1 = FA[0].copyImage(); // Filters for odd iteration + H1.multiply(0.5); + ComplexImage H1Dl = FA[2].getSubimage(0, FA[2].nx / 2 - 1, 0, FA[2].ny - 1); // Filters + // for + // even + // iteration + H1Dl.multiply(0.5); + ComplexImage G1 = FA[1].copyImage(); + ComplexImage G1D = FA[3].copyImage(); + ComplexImage Y2 = null; // highpass subband + ComplexImage Y1 = image.copyImage(); // remaining lowpass subband + Y1.FFT2D(); + if (param.prefilter) { + Y1.multiply(P); + } + int l = 1; + for (int j = 1; j <= J; j++) { + int mj = j % 2; + Y2 = Y1.copyImage(); + if (mj == 1) { // odd iteration + Y2.multiply(G1, l); + Y1.multiply(H1, l); + Y1.quincunxDownUp(); + // Put Y2 in stack + Y2.iFFT2D(); + array[j - 1] = Y2; + } + else { // even iteration + // Y1=left half of Y1*left half of H1D + Y2.multiply(G1D, l); + Y2.iFFT2D(); + Y2 = Y2.rotate(0); + array[j - 1] = Y2; + Y1 = Y1.getSubimage(0, Y1.nx / 2 - 1, 0, Y1.ny - 1); + Y1.multiply(H1Dl, l); + Y1.dyadicDownY(); + l *= 2; + } + } + // insert lowpass subband + Y1.iFFT2D(); + if (J % 2 == 1) { + Y1 = Y1.rotate(0.0); + } + array[J] = Y1; + return array; + } + + /** + * Returns the result of pyramid quincunx synthesis of array. + * + * @param array + * subbands of quincunx pyramid transform + * @return the result of synthesis + */ + + public ComplexImage quincunxSynthesisPyramid(ComplexImage[] array) { + // Compute Gls + ComplexImage Ge = FS[1].copyImage(); + Ge.multiply(FA[1]); + ComplexImage Gemodsqr = Ge.copyImage(); + Gemodsqr.squareModulus(); + Gemodsqr.quincunxDownUp(); + ComplexImage Gls = Ge; + Gls.conj(); + Gls.divide(Gemodsqr, 1.0, 0.0); + // Compute GlsD + ComplexImage GeD = FS[3].copyImage(); + GeD.multiply(FA[3]); + Gemodsqr = GeD.copyImage(); + Gemodsqr.squareModulus(); + Gemodsqr.downUpY(); + ComplexImage GlsD = GeD.copyImage(); + GlsD.conj(); + GlsD.divide(Gemodsqr, 1.0, 0.0); + // do synthesis + // Filters for odd iteration + ComplexImage H = FS[0]; + ComplexImage H1 = FA[1]; + ComplexImage G = FS[1]; + // Filters for even iteration + ComplexImage HD = FS[2]; + ComplexImage H1D = FA[3]; + ComplexImage GD = FS[3]; + ComplexImage HP = new ComplexImage(array[1].nx, array[1].ny); + ComplexImage LP = new ComplexImage(array[1].nx, array[0].ny); + ComplexImage LP1 = new ComplexImage(array[1].nx, array[1].ny); + // Get lowpass + LP.copyImageContent(array[J]); + if (J % 2 == 1) { + LP.unrotate(array[J - 1].nx, array[J - 1].ny); + } + LP.FFT2D(); + int l = 1; + for (int i = 0, J12 = (J - 1) / 2; i < J12; i++, l *= 2) + ; + int mj = J % 2; + for (int j = J; j > 0; j--) { + HP.copyImageContent(array[j - 1]); + if (mj == 0) { // even iteration + HP.unrotate(array[j - 2].nx, array[j - 2].ny); + HP.FFT2D(); + LP.dyadicUpsample(); + LP.multiply(HD, l); + LP1.copyImageContent(LP); + LP1.multiply(H1D, l); + HP.subtract(LP1); + HP.multiply(GlsD, l); + HP.downUpY(); + HP.multiplyCircular(GD, l); + LP.add(HP); + } + else { // odd iteration + HP.FFT2D(); + LP.multiplyCircular(H, l); + LP1.copyImageContent(LP); + LP1.multiply(H1, l); + HP.subtract(LP1); + HP.multiply(Gls, l); + HP.quincunxDownUp(); + HP.multiply(G, l); + LP.add(HP); + l /= 2; + } + mj = 1 - mj; + } + if (param.prefilter) { + LP.divide(P, 1.0, 0.0); + } + LP.iFFT2D(); + return LP; + } + + /** + * Prepares the quincunx pyramid transform coeffitients for being displayed. + * Rescales the subbands for visualisation and puts all subbands in one + * ComplexImage. + * + * @param array + * subbands of quincunx pyramid transform + * @param back + * background color + * @param rescale + * if rescale=false there is no rescaling + * @param lp + * if lp=false the lowpass subband is not displayed + * @return the image to display + */ + + public ComplexImage displayPyramid(ComplexImage[] array, double back, boolean rescale, boolean lp) { + int nx = array[0].nx; + int ny = array[0].ny; + int s = (nx + ny) / 2; + int l; + if (nx > ny) { + l = (nx + ny) / 2; + } + else { + l = ny; + } + ComplexImage display = new ComplexImage(nx + s, 2 * l); + display.settoConstant(back, back); + int x = 0; + int y = 0; + for (int j = 0; j < J; j++) { + ComplexImage temp = array[j].copyImage(); + if (rescale) { + temp.stretch(); + } + if (j % 2 == 1) { // even iteration + temp.unrotate(array[j - 1].nx, array[j - 1].ny); + temp = temp.rotate(back); + } + + temp.frame(back); + display.putSubimage(x, y, temp); + if ((j == J - 1) && (J % 2 == 0)) { + y += l; + x = nx - array[J].nx / 2; + } + else { + if (x == nx) { + y += l; + l /= 2; + x = nx - array[j + 1].nx; + } + else { + x = nx; + } + } + } + if (lp) { + ComplexImage temp = array[J].copyImage(); + if (J % 2 == 1) { // even iteration + temp.unrotate(array[J - 1].nx, array[J - 1].ny); + temp = temp.rotate(back); + } + temp.stretch(); + temp.frame(back); + display.putSubimage(x, y, temp); + } + return display; + } + + /** + * Prepares a nonredundant quincunx transform for being displayed, stretches + * each subband. + * + * @param image + * the basis transform coefficients + * @return the image with rescaled subbands to display + */ + + public ComplexImage displayBasis(ComplexImage image) { + int dx = image.nx; + int dy = image.ny; + ComplexImage out = new ComplexImage(dx, dy); + ComplexImage sub; + for (int j = 1; j <= J; j++) { + if (j % 2 == 1) { // Odd iteration + sub = image.getSubimage(dx / 2, dx - 1, 0, dy - 1); + sub.stretch(); + out.putSubimage(dx / 2, 0, sub); + dx /= 2; + } + else { + sub = image.getSubimage(0, dx - 1, dy / 2, dy - 1); + sub.stretch(); + out.putSubimage(0, dy / 2, sub); + dy /= 2; + } + } + sub = image.getSubimage(0, dx - 1, 0, dy - 1); + sub.stretch(); + out.putSubimage(0, 0, sub); + return out; + } +} \ No newline at end of file diff --git a/src/bilib/src/polyharmonicwavelets/Riesz.java b/src/bilib/src/polyharmonicwavelets/Riesz.java new file mode 100644 index 0000000000000000000000000000000000000000..bc26422aaceb214056bd142deb8d425a3a7722cc --- /dev/null +++ b/src/bilib/src/polyharmonicwavelets/Riesz.java @@ -0,0 +1,447 @@ +package polyharmonicwavelets; + +// +// Riesz.java +// +// +// Created by Biomedical Imaging Group on 2/14/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +import java.util.*; +import ij.*; + +/** + * This class computes the Riesz wavelet transform of the image as well as its + * monogenic transform parameters such as the local orientation, amplitude and + * the instantaneous frequency in each subband. + * + * @author Katarina Balac, EPFL. + */ + +public class Riesz { + + /** + * The image. + */ + public ComplexImage image; + + /** + * The polyharmonic wavelet transform of the image. + */ + public ComplexImage[] p; + + /** + * The riesz transform of p, the wavelet Riesz transform of the image. + */ + public ComplexImage[] q; + + private Parameters param; + + /** + * Local wavenumber for subband j in wavenumber[j] + */ + public ComplexImage[] wavenumber = null; + /** + * Local modulus for subband j in modulus[j] + */ + public ComplexImage[] modulus = null; + /** + * Local phase for subband j in phase[j] + */ + public ComplexImage[] phase = null; + /** + * Local orientation for subband j in orientation[j] + */ + public ComplexImage[] orientation = null; + + private DyadicTransform transform; + private DyadicFilters filters; + private int J; + private double order; + + /** + * This variable stores all the lowpass subbands. The j-th subband is in + * lowpassSubbands[j-1], j=1...J+1. + */ + + public ComplexImage[] lowpassSubbands; + + /** + * Creates a Riesz object, computes all the monogenic features desired. The + * modulus is always computes. + * + * @param imag + * the image + * @param parameters + * the transform parameters + * @param phase + * if true compute the monogenic phase + * @param orientation + * if true compute the monogenic orientation + * @param wavenumber + * if true compute the monogenic wavenumber + */ + + public Riesz(ComplexImage imag, Parameters parameters, boolean phase, boolean orientation, boolean wavenumber) { + image = imag; + param = parameters; + param.analysesonly = true; + param.flavor = param.MARR; + param.prefilter = true; + param.lattice = param.DYADIC; // only gamma and J can be set from the + // outside + param.rieszfreq = 0; + order = param.order; + J = param.J; + param.N = 1; + filters = new DyadicFilters(param, image.nx, image.ny); + filters.calculateFilters(); + transform = new DyadicTransform(filters, param); + switch (parameters.redundancy) { + case Parameters.PYRAMID: { + q = transform.dyadicAnalysesPyramid(image); + } + break; + case Parameters.REDUNDANT: { + q = transform.dyadicAnalysesRedundant(image); + } + break; + } + double[] temp1 = filters.FA[0].imag; + filters.FA[0].imag = null; + double[] temp2 = filters.FA[1].imag; + filters.FA[1].imag = null; + param.N = 0; + filters.setParameters(param); + filters.calculateFilters(); + transform = new DyadicTransform(filters, param); + ComplexImage[][] plp = null; + switch (param.redundancy) { + case Parameters.PYRAMID: { + plp = transform.dyadicAnalysesPyramidLowpass(image); + } + break; + case Parameters.REDUNDANT: { + plp = transform.dyadicAnalysesRedundantLowpass(image); + } + break; + default: { + System.out.println("Redundancy has to be REDUNDANT or PYRAMID"); + } + } + p = plp[0]; + lowpassSubbands = plp[1]; + filters.FA[0].imag = temp1; + filters.FA[1].imag = temp2; + + computeModulus(); + + if (orientation) { + computeOrientation(); + } + if (phase) { + computePhase(); + } + if (wavenumber) { + computeWavenumber(); + } + } + + /* + * Computes the local modulus and places it in modulus. + */ + private void computeModulus() { + modulus = new ComplexImage[J]; + for (int j = 0; j < J; j++) { + modulus[j] = new ComplexImage(q[j].nx, q[j].ny, true); + int size = modulus[j].nxy; + for (int k = 0; k < size; k++) { + modulus[j].real[k] = Math.sqrt(p[j].real[k] * p[j].real[k] + q[j].real[k] * q[j].real[k] + q[j].imag[k] * q[j].imag[k]); + } + } + } + + /* + * Computes the local orientation and places it in orientation. + */ + private void computeOrientation() { + orientation = new ComplexImage[J]; + int lx = image.nx; + int ly = image.ny; + ComplexImage modq = new ComplexImage(image.nx, image.ny); + for (int j = 0; j < J; j++) { + orientation[j] = new ComplexImage(q[j].nx, q[j].ny, true); + modq.nx = q[j].nx; + modq.ny = q[j].ny; + int size = orientation[j].nxy; + for (int k = 0; k < size; k++) { + double a = modulus[j].real[k] * modulus[j].real[k]; + // Compute the weights modq to smooth + // modq.real[k]=(q[j].real[k]*q[j].real[k]+q[j].imag[k]*q[j].imag[k])/a; + orientation[j].real[k] = Math.atan2(q[j].real[k], q[j].imag[k]); + if (orientation[j].real[k] < 0) + orientation[j].real[k] += Math.PI / 2; + else + orientation[j].real[k] -= Math.PI / 2; + orientation[j].real[k] = -orientation[j].real[k]; + } + // Added by Daniel Sage 30.05.2008 + // Median-like on the angle when the modulus is too low + // orientation[j].smooth(modq); + /* + * modq.showReal("modq "+ j); for(int k=0; k<modq.nxy; k++) { int x= + * k / modq.nx; int y= k % modq.nx; if (x > 0) if (x <modq.nx-1) if + * (y > 0) if (y <modq.ny-1) { double max = modq.real[k]; int kmax = + * k; double min = modq.real[k]; int kmin = k; for (int u=x-1; + * u<x+1; u++) for (int v=y-1; v<y+1; v++) { if + * (modq.real[u+v*modq.nx] > max) { kmax = u+v*modq.nx; max = + * modq.real[kmax]; } if (modq.real[u+v*modq.nx] < min) { kmin = + * u+v*modq.nx; min = modq.real[kmin]; } } if (max - modq.real[k] > + * 0.8) { orientation[j].real[k] = orientation[j].real[kmax]; } if + * (modq.real[k]-min > 0.8) { orientation[j].real[k] = + * orientation[j].real[kmin]; } } } + */ + } + } + + /* + * Computes the local phase and places it in phase. + */ + private void computePhase() { + phase = new ComplexImage[J]; + for (int j = 0; j < J; j++) { + phase[j] = new ComplexImage(q[j].nx, q[j].ny, true); + int size = phase[j].nxy; + for (int k = 0; k < size; k++) { + double a = modulus[j].real[k]; + phase[j].real[k] = Math.acos(p[j].real[k] / a); + if (q[j].imag[k] < 0) { + phase[j].real[k] *= -1.0; + } + } + } + } + + /* + * Computes the local wave number and places it in wavenumber. + */ + private void computeWavenumber() { + ComplexImage[] q1xq2y = null; + ComplexImage[] pxpy = null; + param.rieszfreq = 1; + param.N = 0; + param.order = order - 1; + double[] temp1 = filters.FA[0].imag; + filters.FA[0].imag = null; + double[] temp2 = filters.FA[1].imag; + filters.FA[1].imag = null; + filters.setParameters(param); + filters.calculateFilters(); + transform = new DyadicTransform(filters, param); + if (param.redundancy == param.PYRAMID) { + q1xq2y = transform.dyadicAnalysesPyramid(image); + } + if (param.redundancy == param.REDUNDANT) { + q1xq2y = transform.dyadicAnalysesRedundant(image); + } + param.N = 1; + filters.FA[0].imag = temp1; + filters.FA[1].imag = temp2; + filters.setParameters(param); + filters.calculateFilters(); + transform = new DyadicTransform(filters, param); + if (param.redundancy == param.PYRAMID) { + pxpy = transform.dyadicAnalysesPyramid(image); + } + if (param.redundancy == param.REDUNDANT) { + pxpy = transform.dyadicAnalysesRedundant(image); + } + filters = null; + wavenumber = new ComplexImage[J]; + ComplexImage modq = new ComplexImage(image.nx, image.ny); + for (int j = 0; j < J; j++) { + wavenumber[j] = new ComplexImage(q[j].nx, q[j].ny, true); + modq.nx = q[j].nx; + modq.ny = q[j].ny; + int size = size = wavenumber[j].nxy; + for (int k = 0; k < size; k++) { + double a = modulus[j].real[k] * modulus[j].real[k]; + // Compute the weights modq to smooth + // modq.real[k]=(q[j].real[k]*q[j].real[k]+q[j].imag[k]*q[j].imag[k])/a; + // wave number + wavenumber[j].real[k] = (p[j].real[k] * q1xq2y[j].real[k] + q[j].real[k] * pxpy[j].real[k] + q[j].imag[k] * pxpy[j].imag[k]) / a; + } + // wavenumber[j].smooth(modq); + } + } + + /* + * Computes the local wave number and places it in wavenumber. + */ + public ComplexImage[] computeModifiedRiesz() { + ComplexImage[] q1xq2y = null; + ComplexImage[] pxpy = null; + param.rieszfreq = 1; + param.N = 0; + param.order = order - 1; + double[] temp1 = filters.FA[0].imag; + filters.FA[0].imag = null; + double[] temp2 = filters.FA[1].imag; + filters.FA[1].imag = null; + filters.setParameters(param); + filters.calculateFilters(); + transform = new DyadicTransform(filters, param); + if (param.redundancy == param.PYRAMID) { + q1xq2y = transform.dyadicAnalysesPyramid(image); + } + if (param.redundancy == param.REDUNDANT) { + q1xq2y = transform.dyadicAnalysesRedundant(image); + } + param.N = 1; + filters.FA[0].imag = temp1; + filters.FA[1].imag = temp2; + filters.setParameters(param); + filters.calculateFilters(); + transform = new DyadicTransform(filters, param); + if (param.redundancy == param.PYRAMID) { + pxpy = transform.dyadicAnalysesPyramid(image); + } + if (param.redundancy == param.REDUNDANT) { + pxpy = transform.dyadicAnalysesRedundant(image); + } + return q1xq2y; + } + + public ComplexImage[] computeModifiedWavelet() { + ComplexImage[] q1xq2y = null; + ComplexImage[] pxpy = null; + param.rieszfreq = 1; + param.N = 0; + param.order = order - 1; + double[] temp1 = filters.FA[0].imag; + filters.FA[0].imag = null; + double[] temp2 = filters.FA[1].imag; + filters.FA[1].imag = null; + filters.setParameters(param); + filters.calculateFilters(); + transform = new DyadicTransform(filters, param); + if (param.redundancy == param.PYRAMID) { + q1xq2y = transform.dyadicAnalysesPyramid(image); + } + if (param.redundancy == param.REDUNDANT) { + q1xq2y = transform.dyadicAnalysesRedundant(image); + } + param.N = 1; + filters.FA[0].imag = temp1; + filters.FA[1].imag = temp2; + filters.setParameters(param); + filters.calculateFilters(); + transform = new DyadicTransform(filters, param); + if (param.redundancy == param.PYRAMID) { + pxpy = transform.dyadicAnalysesPyramid(image); + } + if (param.redundancy == param.REDUNDANT) { + pxpy = transform.dyadicAnalysesRedundant(image); + } + return pxpy; + } + + /** + * Displays the local modulus on the screen. + */ + + public void displayModulus() { + if (param.redundancy == param.PYRAMID) { + ComplexImage disp = transform.displayDyadicPyramidReal(modulus, 0.0, false, false); + disp.showReal("Riesz modulus"); + } + if (param.redundancy == param.REDUNDANT) { + ComplexImage.displayStack(modulus, "Riesz modulus"); + } + } + + /** + * Displays the local wave number on the screen. + */ + + public void displayWaveNumber() { + if (param.redundancy == param.PYRAMID) { + ComplexImage disp = transform.displayDyadicPyramidReal(wavenumber, 0.0, false, false); + disp.showReal("Riesz wave number magnitude"); + } + if (param.redundancy == param.REDUNDANT) { + ComplexImage.displayStack(wavenumber, "Riesz wave number magnitude"); + } + } + + /** + * Displays the local phase on the screen. + */ + + public void displayPhase() { + if (param.redundancy == param.PYRAMID) { + ComplexImage disp = transform.displayDyadicPyramidReal(phase, 0.0, false, false); + disp.showReal("Riesz phase"); + } + if (param.redundancy == param.REDUNDANT) { + ComplexImage.displayStack(phase, "Riesz phase"); + } + } + + /** + * Displays the local orientation on the screen. + */ + + public void displayOrientation() { + if (param.redundancy == param.PYRAMID) { + ComplexImage disp = transform.displayDyadicPyramidReal(orientation, 0.0, false, false); + disp.showReal("Riesz orientation"); + } + if (param.redundancy == param.REDUNDANT) { + ComplexImage.displayStack(orientation, "Riesz orientation"); + } + } + + /** + * Displays the derivative in y direction. + */ + + public void displayRieszY() { + if (param.redundancy == param.PYRAMID) { + ComplexImage disp = transform.displayDyadicPyramidReal(q, 0.0, false, false); + disp.showReal("Riesz transform y"); + } + if (param.redundancy == param.REDUNDANT) { + ComplexImage.displayStack(q, "Riesz transform y"); + } + } + + /** + * Displays the derivative in x direction. + */ + + public void displayRieszX() { + if (param.redundancy == param.PYRAMID) { + ComplexImage disp = transform.displayDyadicPyramidReal(q, 0.0, false, false); + disp.showImag("Riesz transform x"); + } + if (param.redundancy == param.REDUNDANT) { + ComplexImage.displayStackImag(q, "Riesz transform x"); + } + } + + /** + * Displays the mother wavelet transform. + */ + + public void displayMother() { + if (param.redundancy == param.PYRAMID) { + ComplexImage disp = transform.displayDyadicPyramidReal(p, 0.0, false, false); + disp.showReal("Mother transform"); + } + if (param.redundancy == param.REDUNDANT) { + ComplexImage.displayStack(p, "Mother transform"); + } + } +} \ No newline at end of file diff --git a/src/bilib/src/wavelets/ComplexWaveFilter.java b/src/bilib/src/wavelets/ComplexWaveFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..c4ab89a4b024ff53866086823f095a84abadb95f --- /dev/null +++ b/src/bilib/src/wavelets/ComplexWaveFilter.java @@ -0,0 +1,283 @@ +package wavelets; + +/** + * This class generate the complex wavelets filter. + * <hr> + * <p> + * <b>Organisation</b>: <a href="http://bigwww.epfl.ch">Biomedical Imaging + * Group</a> (BIG), Ecole Polytechnique Federale de Lausanne (EPFL), Lausanne, + * Switzerland + * </p> + * <p> + * <b>Authors</b>: Jesse Berent, Daniel Sage + * </p> + * <p> + * <b>Reference</b>: B. Forster, D. Van De Ville, J. Berent, D. Sage, M. Unser, + * "<a href="http://bigwww.epfl.ch/publications/forster0404.html + * ">Complex Wavelets for Extended Depth-of-Field: A New Method for the Fusion of Multichannel Microscopy Images</a>," + * Microscopy Research and Technique, vol. 65, no. 1-2, pp. 33-42, September + * 2004. + * </p> + * <p> + * More information: http://bigwww.epfl.ch/demo/edf/index.html + * </p> + * <p> + * Other relevant information are available at: http://bigwww.epfl.ch/ + * </p> + * <hr> + * You'll be free to use this software for research purposes, but you should not + * redistribute it without our consent. In addition, we expect you to include a + * citation or acknowledgement whenever you present or publish results that are + * based on it. + */ + +public class ComplexWaveFilter { + + /** + * real lowpass filter. + */ + public double h[]; + + /** + * real highpass filter. + */ + public double g[]; + + /** + * imaginary lowpass filter. + */ + public double hi[]; + /** + * imaginary highpass filter. + */ + public double gi[]; + + /** + * The constructor generates the 4 filters for a giving length. + * + * @param length + * length of the filter, 6, 14 or 22 + */ + ComplexWaveFilter(int length) { + switch (length) { + + case 6: + // Complex Daubechies + // Real lowpass filter + h = new double[6]; + h[0] = -0.0662912607; + h[1] = 0.1104854346; + h[2] = 0.6629126074; + h[3] = 0.6629126074; + h[4] = 0.1104854346; + h[5] = -0.0662912607; + + // Real highpass filter + g = new double[6]; + g[5] = 0.0662912607; + g[4] = 0.1104854346; + g[3] = -0.6629126074; + g[2] = 0.6629126074; + g[1] = -0.1104854346; + g[0] = -0.0662912607; + + // imaginary lowpass filter + hi = new double[6]; + hi[0] = -0.0855816496; + hi[1] = -0.0855816496; + hi[2] = 0.1711632992; + hi[3] = 0.1711632992; + hi[4] = -0.0855816496; + hi[5] = -0.0855816496; + + // Imaginary highpass filter + gi = new double[6]; + gi[5] = -0.0855816496; + gi[4] = 0.0855816496; + gi[3] = 0.1711632992; + gi[2] = -0.1711632992; + gi[1] = -0.0855816496; + gi[0] = 0.0855816496; + break; + + case 14: + // Complex Daubechies + // Real lowpass filter + h = new double[14]; + h[0] = 0.0049120149; + h[1] = -0.0054111299; + h[2] = -0.0701089996; + h[3] = -0.0564377788; + h[4] = 0.1872348173; + h[5] = 0.3676385056; + h[6] = 0.2792793518; + h[7] = 0.2792793518; + h[8] = 0.3676385056; + h[9] = 0.1872348173; + h[10] = -0.0564377788; + h[11] = -0.0701089996; + h[12] = -0.0054111299; + h[13] = 0.0049120149; + + // Real highpass filter + g = new double[14]; + g[13] = -0.0049120149; + g[12] = -0.0054111299; + g[11] = 0.0701089996; + g[10] = -0.0564377788; + g[9] = -0.1872348173; + g[8] = 0.3676385056; + g[7] = -0.2792793518; + g[6] = 0.2792793518; + g[5] = -0.3676385056; + g[4] = 0.1872348173; + g[3] = 0.0564377788; + g[2] = -0.0701089996; + g[1] = 0.0054111299; + g[0] = 0.0049120149; + + // imaginary lowpass filter + hi = new double[14]; + hi[0] = 0.0018464710; + hi[1] = 0.0143947836; + hi[2] = 0.0079040001; + hi[3] = -0.1169376946; + hi[4] = -0.2596312614; + hi[5] = -0.0475928095; + hi[6] = 0.4000165107; + hi[7] = 0.4000165107; + hi[8] = -0.0475928095; + hi[9] = -0.2596312614; + hi[10] = -0.1169376946; + hi[11] = 0.0079040001; + hi[12] = 0.0143947836; + hi[13] = 0.0018464710; + + // Imaginary highpass filter + gi = new double[14]; + gi[13] = 0.0018464710; + gi[12] = -0.0143947836; + gi[11] = 0.0079040001; + gi[10] = 0.1169376946; + gi[9] = -0.2596312614; + gi[8] = 0.0475928095; + gi[7] = 0.4000165107; + gi[6] = -0.4000165107; + gi[5] = -0.0475928095; + gi[4] = 0.2596312614; + gi[3] = -0.1169376946; + gi[2] = -0.0079040001; + gi[1] = 0.0143947836; + gi[0] = -0.0018464710; + break; + + case 22: + // Complex Daubechies + // Real lowpass filter + h = new double[22]; + h[0] = -0.0002890832; + h[1] = -0.0000935982; + h[2] = 0.0059961342; + h[3] = 0.0122232015; + h[4] = -0.0243700791; + h[5] = -0.1092940542; + h[6] = -0.0918847036; + h[7] = 0.1540094645; + h[8] = 0.4014277015; + h[9] = 0.3153022916; + h[10] = 0.0440795062; + h[11] = 0.0440795062; + h[12] = 0.3153022916; + h[13] = 0.4014277015; + h[14] = 0.1540094645; + h[15] = -0.0918847036; + h[16] = -0.1092940542; + h[17] = -0.0243700791; + h[18] = 0.0122232015; + h[19] = 0.0059961342; + h[20] = -0.0000935982; + h[21] = -0.0002890832; + + // Real highpass filter + g = new double[22]; + g[21] = 0.0002890832; + g[20] = -0.0000935982; + g[19] = -0.0059961342; + g[18] = 0.0122232015; + g[17] = 0.0243700791; + g[16] = -0.1092940542; + g[15] = 0.0918847036; + g[14] = 0.1540094645; + g[13] = -0.4014277015; + g[12] = 0.3153022916; + g[11] = -0.0440795062; + g[10] = 0.0440795062; + g[9] = -0.3153022916; + g[8] = 0.4014277015; + g[7] = -0.1540094645; + g[6] = -0.0918847036; + g[5] = 0.1092940542; + g[4] = -0.0243700791; + g[3] = -0.0122232015; + g[2] = 0.0059961342; + g[1] = 0.0000935982; + g[0] = -0.0002890832; + + // imaginary lowpass filter + hi = new double[22]; + hi[0] = 0.0000211708; + hi[1] = -0.0012780664; + hi[2] = -0.0029648612; + hi[3] = 0.0144283733; + hi[4] = 0.0503067404; + hi[5] = -0.0044659104; + hi[6] = -0.1999654035; + hi[7] = -0.2603015239; + hi[8] = 0.0013800055; + hi[9] = 0.2232934469; + hi[10] = 0.1795460286; + hi[11] = 0.1795460286; + hi[12] = 0.2232934469; + hi[13] = 0.0013800055; + hi[14] = -0.2603015239; + hi[15] = -0.1999654035; + hi[16] = -0.0044659104; + hi[17] = 0.0503067404; + hi[18] = 0.0144283733; + hi[19] = -0.0029648612; + hi[20] = -0.0012780664; + hi[21] = 0.0000211708; + + // Imaginary highpass filter + gi = new double[22]; + gi[21] = 0.0000211708; + gi[20] = 0.0012780664; + gi[19] = -0.0029648612; + gi[18] = -0.0144283733; + gi[17] = 0.0503067404; + gi[16] = 0.0044659104; + gi[15] = -0.1999654035; + gi[14] = 0.2603015239; + gi[13] = 0.0013800055; + gi[12] = -0.2232934469; + gi[11] = 0.1795460286; + gi[10] = -0.1795460286; + gi[9] = 0.2232934469; + gi[8] = -0.0013800055; + gi[7] = -0.2603015239; + gi[6] = 0.1999654035; + gi[5] = -0.0044659104; + gi[4] = -0.0503067404; + gi[3] = 0.0144283733; + gi[2] = 0.0029648612; + gi[1] = -0.0012780664; + gi[0] = -0.0000211708; + break; + + default: + throw (new RuntimeException("Invalid length")); + } + + } + +} \ No newline at end of file diff --git a/src/bilib/src/wavelets/ComplexWavelet.java b/src/bilib/src/wavelets/ComplexWavelet.java new file mode 100644 index 0000000000000000000000000000000000000000..3cf90e1caea05ddc337d47ce2b4a430a8306ed02 --- /dev/null +++ b/src/bilib/src/wavelets/ComplexWavelet.java @@ -0,0 +1,509 @@ +package wavelets; + +/** + * This class generate the complex wavelets filter. + * <hr> + * <p> + * <b>Organisation</b>: <a href="http://bigwww.epfl.ch">Biomedical Imaging + * Group</a> (BIG), Ecole Polytechnique Federale de Lausanne (EPFL), Lausanne, + * Switzerland + * </p> + * <p> + * <b>Authors</b>: Jesse Berent, Daniel Sage + * </p> + * <p> + * <b>Reference</b>: B. Forster, D. Van De Ville, J. Berent, D. Sage, M. Unser, + * "<a href="http://bigwww.epfl.ch/publications/forster0404.html + * ">Complex Wavelets for Extended Depth-of-Field: A New Method for the Fusion of Multichannel Microscopy Images</a>," + * Microscopy Research and Technique, vol. 65, no. 1-2, pp. 33-42, September + * 2004. + * </p> + * <p> + * More information: http://bigwww.epfl.ch/demo/edf/index.html + * </p> + * <p> + * Other relevant information are available at: http://bigwww.epfl.ch/ + * </p> + * <hr> + * You'll be free to use this software for research purposes, but you should not + * redistribute it without our consent. In addition, we expect you to include a + * citation or acknowledgement whenever you present or publish results that are + * based on it. + */ + +public class ComplexWavelet { + + /** + * This public method computes the complex wavelets transform of a given + * image and a given number of scale. + * + * @param in + * input image + * @param n + * number of scale + * @param length + * @return the wavelets coefficients + */ + static public ImageAccess[] analysis(ImageAccess in, int n, int length) { + + // Compute the size to the fine and coarse levels + int nxfine = in.getWidth(); + int nyfine = in.getHeight(); + + // Declare the object image + ImageAccess sub1; + ImageAccess sub2; + ImageAccess sub3; + ImageAccess sub4; + ImageAccess subre; + ImageAccess subim; + ImageAccess outRe; + ImageAccess outIm; + + // Initialization + int nx = nxfine; + int ny = nyfine; + outRe = in.duplicate(); + outIm = in.duplicate(); + + int re = 0; + int im = 1; + + // From fine to coarse main loop + // first iteration + + subre = new ImageAccess(nx, ny); + sub1 = new ImageAccess(nx, ny); + sub2 = new ImageAccess(nx, ny); + + // Copy in[] into image[] + outRe.getSubImage(0, 0, subre); + + // Apply the Wavelet splitting + sub1 = split(subre, re, re, length); + sub2 = split(subre, im, im, length); + + sub1.subtract(sub1, sub2); + + // Put the result image[] into in[] + outRe.putSubImage(0, 0, sub1); + + // Apply the Wavelet splitting + sub1 = split(subre, re, im, length); + sub2 = split(subre, im, re, length); + + sub1.add(sub1, sub2); + + outIm.putSubImage(0, 0, sub1); + + // Reduce the size by a factor of 2 + nx = nx / 2; + ny = ny / 2; + + for (int i = 1; i < n; i++) { + + // Create a new image array of size [nx,ny] + subre = new ImageAccess(nx, ny); + subim = new ImageAccess(nx, ny); + sub1 = new ImageAccess(nx, ny); + sub2 = new ImageAccess(nx, ny); + sub3 = new ImageAccess(nx, ny); + sub4 = new ImageAccess(nx, ny); + + // Copy in[] into image[] + outRe.getSubImage(0, 0, subre); + outIm.getSubImage(0, 0, subim); + + sub1 = split(subre, re, re, length); + sub2 = split(subre, im, im, length); + sub3 = split(subim, re, im, length); + sub4 = split(subim, im, re, length); + + sub1.subtract(sub1, sub2); + sub1.subtract(sub1, sub3); + sub1.subtract(sub1, sub4); + + outRe.putSubImage(0, 0, sub1); + + sub1 = split(subre, re, im, length); + sub2 = split(subre, im, re, length); + sub3 = split(subim, re, re, length); + sub4 = split(subim, im, im, length); + + sub1.add(sub1, sub2); + sub1.add(sub1, sub3); + sub1.subtract(sub1, sub4); + + outIm.putSubImage(0, 0, sub1); + + // Reduce the size by a factor of 2 + nx = nx / 2; + ny = ny / 2; + } + ImageAccess[] outComplex = new ImageAccess[2]; + outComplex[0] = outRe.duplicate(); + outComplex[1] = outIm.duplicate(); + return outComplex; + } + + /** + * Perform 1 iteration of the wavelet transformation of an ImageObject. The + * algorithm use the separability of the wavelet transformation. The result + * of the computation is put in the ImageObject calling this method. + * + * @param in + * an ImageAcess object provided by ImageJ + */ + static private ImageAccess split(ImageAccess in, int type1, int type2, int length) { + int nx = in.getWidth(); + int ny = in.getHeight(); + ImageAccess out = new ImageAccess(nx, ny); + + ComplexWaveFilter wf = new ComplexWaveFilter(length); + + if (nx >= 1) { + double rowin[] = new double[nx]; + double rowout[] = new double[nx]; + for (int y = 0; y < ny; y++) { + in.getRow(y, rowin); + + if (type1 == 0) + split_1D(rowin, rowout, wf.h, wf.g); + + if (type1 == 1) + split_1D(rowin, rowout, wf.hi, wf.gi); + + out.putRow(y, rowout); + } + } + else { + // out.copy(in); + out = in.duplicate(); + } + + if (ny > 1) { + double colin[] = new double[ny]; + double colout[] = new double[ny]; + for (int x = 0; x < nx; x++) { + out.getColumn(x, colin); + + if (type2 == 0) + split_1D(colin, colout, wf.h, wf.g); + + if (type2 == 1) + split_1D(colin, colout, wf.hi, wf.gi); + + out.putColumn(x, colout); + } + } + + return out; + } + + /** + * Perform 1 iteration of the wavelet transformation of a 1D vector using + * the wavelet transformation. The output vector has the same size of the + * input vector and it contains first the low pass part of the wavelet + * transform and then the high pass part of the wavelet transformation. + * + * @param vin + * input, a double 1D vector + * @param vout + * output, a double 1D vector + * @param h + * input, a double 1D vector, lowpass filter + * @param g + * input, a double 1D vector, highpass filter + */ + static private void split_1D(double vin[], double vout[], double h[], double g[]) { + int n = vin.length; + int n2 = n / 2; + int nh = h.length; + int ng = g.length; + + double voutL[] = new double[n]; + double voutH[] = new double[n]; + double pix; + int j1; + + for (int i = 0; i < n; i++) { + pix = 0.0; + for (int k = 0; k < nh; k++) { // Low pass part + j1 = i + k - (nh / 2); + if (j1 < 0) { // Periodic conditions + while (j1 < n) + j1 = n + j1; + j1 = (j1) % n; + } + if (j1 >= n) { // Periodic conditions + j1 = (j1) % n; + } + pix = pix + h[k] * vin[j1]; + } + voutL[i] = pix; + } + + for (int i = 0; i < n; i++) { + pix = 0.0; + for (int k = 0; k < ng; k++) { // Low pass part + j1 = i + k - (ng / 2); + if (j1 < 0) { // Periodic conditions + while (j1 < n) + j1 = n + j1; + j1 = (j1) % n; + } + if (j1 >= n) { // Periodic conditions + j1 = (j1) % n; + } + pix = pix + g[k] * vin[j1]; + } + voutH[i] = pix; + } + + for (int k = 0; k < n2; k++) + vout[k] = voutL[2 * k]; + for (int k = n2; k < n; k++) + vout[k] = voutH[2 * k - n]; + + } + + /** + * Perform an inverse wavelet transformation of the ImageObject calling this + * method with n scale. The size of image should be a interger factor of 2 + * at the power n. The input is the results of a wavelet transformation. The + * result is the reconstruction. It is put in the ImageObject calling this + * method. + * + * @param inRe + * the real part of the wavelets coefficients + * @param inIm + * the imaginary part of the wavelets coefficients + * @param n + * a integer value giving the number of scale + * @param length + * @return the reconstructed image + */ + + static public ImageAccess[] synthesis(ImageAccess inRe, ImageAccess inIm, int n, int length) { + // Compute the size to the fine and coarse levels + int div = (int) Math.pow(2.0, (double) (n - 1)); + int nxcoarse = inRe.getWidth() / div; + int nycoarse = inRe.getHeight() / div; + + // Declare the object image + ImageAccess subre, subim, sub1, sub2, sub3, sub4; + ImageAccess outRe; + ImageAccess outIm; + + // Initialisazion + int nx = nxcoarse; + int ny = nycoarse; + + outRe = inRe.duplicate(); + outIm = inIm.duplicate(); + + int re = 0; + int im = 1; + + // From fine to coarse main loop + for (int i = 0; i < n; i++) { + // Create a new image array of size [nx,ny] + subre = new ImageAccess(nx, ny); + subim = new ImageAccess(nx, ny); + sub1 = new ImageAccess(nx, ny); + sub2 = new ImageAccess(nx, ny); + sub3 = new ImageAccess(nx, ny); + sub4 = new ImageAccess(nx, ny); + // Copy in[] into image[] + outRe.getSubImage(0, 0, subre); + outIm.getSubImage(0, 0, subim); + + // Apply the Wavelet splitting + sub1 = merge(subre, re, re, length); + sub2 = merge(subre, im, im, length); + sub3 = merge(subim, re, im, length); + sub4 = merge(subim, im, re, length); + + sub1.subtract(sub1, sub2); + sub1.add(sub1, sub3); + sub1.add(sub1, sub4); + + outRe.putSubImage(0, 0, sub1); + + // Apply the Wavelet splitting + sub1 = merge(subre, re, im, length); + sub2 = merge(subre, im, re, length); + sub3 = merge(subim, re, re, length); + sub4 = merge(subim, im, im, length); + + sub3.subtract(sub3, sub1); + sub3.subtract(sub3, sub2); + sub3.subtract(sub3, sub4); + outIm.putSubImage(0, 0, sub3); + // Enlarge the size by a factor of 2 + nx = nx * 2; + ny = ny * 2; + + } + ImageAccess[] ReconstComplex = new ImageAccess[2]; + ReconstComplex[0] = outRe.duplicate(); + ReconstComplex[1] = outIm.duplicate(); + return ReconstComplex; + } + + /** + * Perform 1 iteration of the inverse wavelet transformation of an + * ImageObject. The algorithm use the separability of the wavelet + * transformation. The result of the computation is put in the ImageAccess + * calling this method. + * + * @param in + * an ImageAcess object provided by ImageJ + * @param type1 + * @param type2 + * @param length + * @return merge + */ + static private ImageAccess merge(ImageAccess in, int type1, int type2, int length) { + int nx = in.getWidth(); + int ny = in.getHeight(); + ImageAccess out = new ImageAccess(nx, ny); + ComplexWaveFilter wf = new ComplexWaveFilter(length); + + if (nx >= 1) { + double rowin[] = new double[nx]; + double rowout[] = new double[nx]; + for (int y = 0; y < ny; y++) { + in.getRow(y, rowin); + + if (type1 == 0) + merge_1D(rowin, rowout, wf.h, wf.g); + if (type1 == 1) { + merge_1D(rowin, rowout, wf.hi, wf.gi); + } + out.putRow(y, rowout); + } + } + else { + out = in.duplicate(); + } + + if (ny > 1) { + double colin[] = new double[ny]; + double colout[] = new double[ny]; + for (int x = 0; x < nx; x++) { + out.getColumn(x, colin); + + if (type2 == 0) + merge_1D(colin, colout, wf.h, wf.g); + if (type2 == 1) { + merge_1D(colin, colout, wf.hi, wf.gi); + } + out.putColumn(x, colout); + } + } + return out; + } + + /** + * Perform 1 iteration of the inverse wavelet transformation of a 1D vector + * using the Spline wavelet transformation. The output vector has the same + * size of the input vector and it contains the reconstruction of the input + * signal. The input vector constains first the low pass part of the wavelet + * transform and then the high pass part of the wavelet transformation. + * + * @param vin + * input, a double 1D vector + * @param vout + * output, a double 1D vector + * @param h + * input, a double 1D vector, lowpass filter + * @param g + * input, a double 1D vector, highpass filter + */ + static private void merge_1D(double vin[], double vout[], double h[], double g[]) { + int n = vin.length; + int n2 = n / 2; + int nh = h.length; + int ng = g.length; + int j1; + + double pix; + + // Upsampling + + double vinL[] = new double[n]; + double vinH[] = new double[n]; + for (int k = 0; k < n; k++) { + vinL[k] = 0; + vinH[k] = 0; + } + + for (int k = 0; k < n2; k++) { + vinL[2 * k] = vin[k]; + vinH[2 * k] = vin[k + n2]; + } + + // filtering + + for (int i = 0; i < n; i++) { + pix = 0.0; + for (int k = 0; k < nh; k++) { // Low pass part + j1 = i - k + (nh / 2); + if (j1 < 0) { // Periodic conditions + while (j1 < n) + j1 = n + j1; + j1 = (j1) % n; + } + if (j1 >= n) { // Periodic conditions + j1 = (j1) % n; + } + pix = pix + h[k] * vinL[j1]; + } + vout[i] = pix; + } + + for (int i = 0; i < n; i++) { + pix = 0.0; + for (int k = 0; k < ng; k++) { // High pass part + j1 = i - k + (ng / 2); + if (j1 < 0) { // Periodic conditions + while (j1 < n) + j1 = n + j1; + j1 = (j1) % n; + } + if (j1 >= n) { // Periodic conditions + j1 = (j1) % n; + } + pix = pix + g[k] * vinH[j1]; + } + vout[i] = vout[i] + pix; + } + } + + /** + * This method computes the modulus from a real ImageAccess and a imaginary + * ImageAccess objects. + * + * @param inRe + * @param inIm + * @return modulus + */ + static public ImageAccess modulus(ImageAccess inRe, ImageAccess inIm) { + int nx = inRe.getWidth(); + int ny = inRe.getHeight(); + double m, r, i; + ImageAccess modulus = new ImageAccess(nx, ny); + int x, y; + for (x = 0; x < nx; x++) { + for (y = 0; y < ny; y++) { + r = inRe.getPixel(x, y); + i = inIm.getPixel(x, y); + m = Math.sqrt((r * r) + (i * i)); + modulus.putPixel(x, y, m); + } + } + return modulus; + } + +} diff --git a/src/bilib/src/wavelets/ImageAccess.java b/src/bilib/src/wavelets/ImageAccess.java new file mode 100644 index 0000000000000000000000000000000000000000..cbb36346c990901f3383cbff1a1aaa6d16f8dba4 --- /dev/null +++ b/src/bilib/src/wavelets/ImageAccess.java @@ -0,0 +1,1354 @@ +package wavelets; + +import ij.ImagePlus; +import ij.process.ByteProcessor; +import ij.process.ColorProcessor; +import ij.process.FloatProcessor; +import ij.process.ImageProcessor; + +/** + * ImageAccess is an interface layer to facilitate the access to the pixels of + * ImageJ images. Methods of ImageAccess provides an easy and robust way to + * access to the pixels of images. The data are stored in a double array. Many + * methods get/put allows to access to the data. If the user try to access + * outside of the image, the mirror boundary conditions are applied. + * <hr> + * <p> + * <b>Organisation</b>: <a href="http://bigwww.epfl.ch">Biomedical Imaging + * Group</a> (BIG), Ecole Polytechnique Federale de Lausanne (EPFL), Lausanne, + * Switzerland + * </p> + * <p> + * <b>Authors</b>: Daniel Sage + * </p> + * <p> + * <b>Reference</b>: D. Sage, M. Unser, "<a + * href="http://bigwww.epfl.ch/publications/sage0303.html">Teaching + * Image-Processing Programming in Java</a>," IEEE Signal Processing + * Magazine, vol. 20, no. 6, pp. 43-52, November 2003. + * </p> + * <p> + * More information: http://bigwww.epfl.ch/teaching/iplabsite/index.php + * </p> + * <p> + * Other relevant information are available at: http://bigwww.epfl.ch/ + * </p> + * <hr> + * You'll be free to use this software for research purposes, but you should not + * redistribute it without our consent. In addition, we expect you to include a + * citation or acknowledgement whenever you present or publish results that are + * based on it. + */ + +public class ImageAccess { + public static final int PATTERN_SQUARE_3x3 = 0; + public static final int PATTERN_CROSS_3x3 = 1; + + private double pixels[] = null; // store the pixel data + private int nx = 0; // size in X axis + private int ny = 0; // size in Y axis + private int size = 0; // size = nx*ny + + /** + * Creates a new ImageAccess object from a 2D double array of pixels. The + * size of the array determines the size of the image. + * + * @param array + * an array of pixel (2D) + */ + public ImageAccess(double[][] array) { + if (array == null) + throw new ArrayStoreException("Constructor: array == null."); + this.ny = array[0].length; + this.nx = array.length; + this.size = nx * ny; + pixels = new double[size]; + int k = 0; + for (int j = 0; j < ny; j++) + for (int i = 0; i < nx; i++) + pixels[k++] = array[i][j]; + } + + /** + * Creates a new object of the class ImageAccess from an ImageProcessor + * object. + * + * ImageProcessor object contains the image data, the size and the type of + * the image. The ImageProcessor is provided by ImageJ, it should by a + * 8-bit, 16-bit. + * + * @param ip + * an ImageProcessor object provided by ImageJ + */ + public ImageAccess(ImageProcessor ip) { + if (ip == null) + throw new ArrayStoreException("Constructor: ImageProcessor == null."); + nx = ip.getWidth(); + ny = ip.getHeight(); + size = nx * ny; + pixels = new double[size]; + if (ip.getPixels() instanceof byte[]) { + byte[] bsrc = (byte[]) ip.getPixels(); + for (int k = 0; k < size; k++) + pixels[k] = (double) (bsrc[k] & 0xFF); + + } + else if (ip.getPixels() instanceof short[]) { + short[] ssrc = (short[]) ip.getPixels(); + for (int k = 0; k < size; k++) + pixels[k] = (double) (ssrc[k] & 0xFFFF); + } + else if (ip.getPixels() instanceof float[]) { + float[] fsrc = (float[]) ip.getPixels(); + for (int k = 0; k < size; k++) + pixels[k] = (double) fsrc[k]; + } + else { + throw new ArrayStoreException("Constructor: Unexpected image type."); + } + } + + /** + * Creates a new object of the class ImageAccess from an ColorProcessor + * object. + * + * ImageProcessor object contains the image data, the size and the type of + * the image. The ColorProcessor is provided by ImageJ, The ImageAccess + * contains one plane (red, green or blue) selected with the colorPlane + * parameter. + * + * @param cp + * an ColorProcessor object + * @param colorPlane + * index of the color plane 0, 1 or 2 + */ + public ImageAccess(ColorProcessor cp, int colorPlane) { + if (cp == null) + throw new ArrayStoreException("Constructor: ColorProcessor == null."); + if (colorPlane < 0) + throw new ArrayStoreException("Constructor: colorPlane < 0."); + if (colorPlane > 2) + throw new ArrayStoreException("Constructor: colorPlane > 2."); + nx = cp.getWidth(); + ny = cp.getHeight(); + size = nx * ny; + pixels = new double[size]; + byte[] r = new byte[size]; + byte[] g = new byte[size]; + byte[] b = new byte[size]; + cp.getRGB(r, g, b); + if (colorPlane == 0) + for (int k = 0; k < size; k++) + pixels[k] = (double) (r[k] & 0xFF); + else if (colorPlane == 1) + for (int k = 0; k < size; k++) + pixels[k] = (double) (g[k] & 0xFF); + else if (colorPlane == 2) + for (int k = 0; k < size; k++) + pixels[k] = (double) (b[k] & 0xFF); + } + + /** + * Creates a new object of the class ImageAccess. + * + * The size of the image are given as parameter. The data pixels are empty + * and are not initialized. + * + * @param nx + * the size of the image along the X-axis + * @param ny + * the size of the image along the Y-axis + */ + public ImageAccess(int nx, int ny) { + if (nx < 1) + throw new ArrayStoreException("Constructor: nx < 1."); + if (ny < 1) + throw new ArrayStoreException("Constructor: ny < 1."); + this.nx = nx; + this.ny = ny; + size = nx * ny; + pixels = new double[size]; + } + + /** + * Return the width of the image. + * + * @return the image width + */ + public int getWidth() { + return nx; + } + + /** + * Return the height of the image. + * + * @return the image height + */ + public int getHeight() { + return ny; + } + + /** + * Return the maximum value of ImageAccess. + * + * @return the maximum value + */ + public double getMaximum() { + double maxi = pixels[0]; + for (int i = 1; i < size; i++) + if (pixels[i] > maxi) + maxi = pixels[i]; + return maxi; + } + + /** + * Return the minimum value of ImageAccess. + * + * @return the minimum value + */ + public double getMinimum() { + double mini = pixels[0]; + for (int i = 1; i < size; i++) + if (pixels[i] < mini) + mini = pixels[i]; + return mini; + } + + /** + * Return the mean value of ImageAccess. + * + * @return the mean value + */ + public double getMean() { + double mean = 0.0; + for (int i = 0; i < size; i++) + mean += pixels[i]; + mean /= (double) (size); + return mean; + } + + /** + * Returns a copy of the pixel data organize in a 2D array. + * + * @return the 2D double array + */ + public double[][] getArrayPixels() { + double[][] array = new double[nx][ny]; + int k = 0; + for (int j = 0; j < ny; j++) + for (int i = 0; i < nx; i++) + array[i][j] = pixels[k++]; + return array; + } + + /** + * Returns a reference to the pixel data in double (1D). + * + * @return the 1D double array + */ + public double[] getPixels() { + return pixels; + } + + /** + * Create a FloatProcessor from the pixel data. The double values of the + * pixel are simply casted in float. + * + * @return the FloatProcessor + */ + public FloatProcessor createFloatProcessor() { + FloatProcessor fp = new FloatProcessor(nx, ny); + float[] fsrc = new float[size]; + for (int k = 0; k < size; k++) + fsrc[k] = (float) (pixels[k]); + fp.setPixels(fsrc); + return fp; + } + + /** + * Create a ByteProcessor from the pixel data. The double values of the + * pixel are clipped in the [0..255] range. + * + * @return the ByteProcessor + */ + public ByteProcessor createByteProcessor() { + ByteProcessor bp = new ByteProcessor(nx, ny); + byte[] bsrc = new byte[size]; + double p; + for (int k = 0; k < size; k++) { + p = pixels[k]; + if (p < 0) + p = 0.0; + if (p > 255.0) + p = 255.0; + bsrc[k] = (byte) p; + } + bp.setPixels(bsrc); + return bp; + } + + /** + * Create a new ImageAccess object by duplication of the current the + * ImageAccess object. + * + * @return a new ImageAccess object + **/ + public ImageAccess duplicate() { + ImageAccess ia = new ImageAccess(nx, ny); + for (int i = 0; i < size; i++) + ia.pixels[i] = this.pixels[i]; + return ia; + } + + /** + * An ImageAccess object calls this method for getting the gray level of a + * selected pixel. + * + * Mirror border conditions are applied. + * + * @param x + * input, the integer x-coordinate of a pixel + * @param y + * input, the integer y-coordinate of a pixel + * @return the gray level of the pixel (double) + */ + public double getPixel(int x, int y) { + int periodx = 2 * nx - 2; + int periody = 2 * ny - 2; + if (x < 0) { + while (x < 0) + x += periodx; // Periodize + if (x >= nx) + x = periodx - x; // Symmetrize + } + else if (x >= nx) { + while (x >= nx) + x -= periodx; // Periodize + if (x < 0) + x = -x; // Symmetrize + } + + if (y < 0) { + while (y < 0) + y += periody; // Periodize + if (y >= ny) + y = periody - y; // Symmetrize + } + else if (y >= ny) { + while (y >= ny) + y -= periody; // Periodize + if (y < 0) + y = -y; // Symmetrize + } + return pixels[x + y * nx]; + } + + /** + * An ImageAccess object calls this method for getting the gray level of a + * selected pixel using a bilinear interpolation. The coordinates can be + * given in double and the bilinear interpolation is applied the find the + * gray level. + * + * Mirror border conditions are applied. + * + * @param x + * input, the double x-coordinate of a pixel + * @param y + * input, the double y-coordinate of a pixel + * @return the gray level of the pixel (double) + */ + public double getInterpolatedPixel(double x, double y) { + if (Double.isNaN(x)) + return 0; + if (Double.isNaN(y)) + return 0; + + if (x < 0) { + int periodx = 2 * nx - 2; + while (x < 0) + x += periodx; // Periodize + if (x >= nx) + x = periodx - x; // Symmetrize + } + else if (x >= nx) { + int periodx = 2 * nx - 2; + while (x >= nx) + x -= periodx; // Periodize + if (x < 0) + x = -x; // Symmetrize + } + + if (y < 0) { + int periody = 2 * ny - 2; + while (y < 0) + y += periody; // Periodize + if (y >= ny) + y = periody - y; // Symmetrize + } + else if (y >= ny) { + int periody = 2 * ny - 2; + while (y >= ny) + y -= periody; // Periodize + if (y < 0) + y = -y; // Symmetrize + } + int i; + if (x >= 0.0) + i = (int) x; + else { + final int iAdd = (int) x - 1; + i = ((int) (x - (double) iAdd) + iAdd); + } + int j; + if (y >= 0.0) + j = (int) y; + else { + final int iAdd = (int) y - 1; + j = ((int) (y - (double) iAdd) + iAdd); + } + + double dx = x - (double) i; + double dy = y - (double) j; + int di, dj; + if (i >= nx - 1) + di = -1; + else + di = 1; + int index = i + j * nx; + double v00 = pixels[index]; + double v10 = pixels[index + di]; + if (j >= ny - 1) + index -= nx; + else + index += nx; + double v01 = pixels[index]; + double v11 = pixels[index + di]; + return (dx * (v11 * dy - v10 * (dy - 1.0)) - (dx - 1.0) * (v01 * dy - v00 * (dy - 1.0))); + } + + /** + * An ImageAccess object calls this method for getting a whole column of the + * image. + * + * The column should already created with the correct size [ny]. + * + * @param x + * input, the integer x-coordinate of a column + * @param column + * output, an array of the type double + */ + public void getColumn(int x, double[] column) { + if (x < 0) + throw new IndexOutOfBoundsException("getColumn: x < 0."); + if (x >= nx) + throw new IndexOutOfBoundsException("getColumn: x >= nx."); + if (column == null) + throw new ArrayStoreException("getColumn: column == null."); + if (column.length != ny) + throw new ArrayStoreException("getColumn: column.length != ny."); + for (int i = 0; i < ny; i++) { + column[i] = pixels[x]; + x += nx; + } + } + + /** + * An ImageAccess object calls this method for getting a part of column. The + * starting point is given by the y parameter and the ending determine by + * the size of the column parameter. The column parameter should already + * created. + * + * @param x + * input, the integer x-coordinate of a column + * @param y + * input, starting point + * @param column + * output, an array of the type double + */ + public void getColumn(int x, int y, double[] column) { + if (x < 0) + throw new IndexOutOfBoundsException("getColumn: x < 0."); + if (x >= nx) + throw new IndexOutOfBoundsException("getColumn: x >= nx."); + if (column == null) + throw new ArrayStoreException("getColumn: column == null."); + int by = column.length; + if (y >= 0) + if (y < ny - by - 1) { + int index = y * nx + x; + for (int i = 0; i < by; i++) { + column[i] = pixels[index]; + index += nx; + } + return; + } + // Getting information outside of the image + int yt[] = new int[by]; + for (int k = 0; k < by; k++) { + int ya = y + k; + int periody = 2 * ny - 2; + while (ya < 0) + ya += periody; // Periodize + while (ya >= ny) { + ya = periody - ya; // Symmetrize + if (ya < 0) + ya = -ya; + } + yt[k] = ya; + } + int index = 0; + for (int i = 0; i < by; i++) { + index = yt[i] * nx + x; + column[i] = pixels[index]; + } + } + + /** + * An ImageAccess object calls this method for getting a whole row of the + * image. + * + * The row should already created with the correct size [nx]. + * + * @param y + * input, the integer y-coordinate of a row + * @param row + * output, an array of the type double + */ + public void getRow(int y, double[] row) { + if (y < 0) + throw new IndexOutOfBoundsException("getRow: y < 0."); + if (y >= ny) + throw new IndexOutOfBoundsException("getRow: y >= ny."); + if (row == null) + throw new ArrayStoreException("getColumn: row == null."); + if (row.length != nx) + throw new ArrayStoreException("getColumn: row.length != nx."); + y *= nx; + for (int i = 0; i < nx; i++) + row[i] = pixels[y++]; + } + + /** + * An ImageAccess object calls this method for getting a part of row. The + * starting point is given by the y parameter and the ending determine by + * the size of the row parameter. The row parameter should already created. + * + * @param x + * input, starting point + * @param y + * input, the integer y-coordinate of a row + * @param row + * output, an array of the type double + */ + public void getRow(int x, int y, double[] row) { + if (y < 0) + throw new IndexOutOfBoundsException("getRow: y < 0."); + if (y >= ny) + throw new IndexOutOfBoundsException("getRow: y >= ny."); + if (row == null) + throw new ArrayStoreException("getRow: row == null."); + int bx = row.length; + if (x >= 0) + if (x < nx - bx - 1) { + int index = y * nx + x; + for (int i = 0; i < bx; i++) { + row[i] = pixels[index++]; + } + return; + } + int periodx = 2 * nx - 2; + int xt[] = new int[bx]; + for (int k = 0; k < bx; k++) { + int xa = x + k; + while (xa < 0) + xa += periodx; // Periodize + while (xa >= nx) { + xa = periodx - xa; // Symmetrize + if (xa < 0) + xa = -xa; + } + xt[k] = xa; + } + int somme = 0; + int index = y * nx; + for (int i = 0; i < bx; i++) { + somme = index + xt[i]; + row[i] = pixels[somme]; + } + } + + /** + * An ImageAccess object calls this method for getting a neighborhood + * arround a pixel position. + * + * The neigh parameter should already created. The size of the array + * determines the neighborhood block. + * + * <br> + * Mirror border conditions are applied. <br> + * <br> + * The pixel value of (x-n/2, y-n/2) is put into neigh[0][0] <br> + * ... <br> + * The pixel value of (x+n/2, y+n/2) is put into neigh[n-1][n-1] <br> + * <br> + * For example if neigh is a double[4][4]: <br> + * The pixel value of (x-1, y-1) is put into neigh[0][0] <br> + * The pixel value of (x , y ) is put into neigh[1][1] <br> + * The pixel value of (x, y+1) is put into neigh[1][2] <br> + * The pixel value of (x+1, y-2) is put into neigh[2][0] <br> + * ... <br> + * For example if neigh is a double[5][5]: <br> + * The pixel value of (x-2, y-2) is put into neigh[0][0] <br> + * The pixel value of (x-1, y-1) is put into neigh[1][1] <br> + * The pixel value of (x , y ) is put into neigh[2][2] <br> + * The pixel value of (x, y+1) is put into neigh[2][3] <br> + * The pixel value of (x+2, y-2) is put into neigh[4][0] + * + * @param x + * the integer x-coordinate of a selected central pixel + * @param y + * the integer y-coordinate of a selected central pixel + * @param neigh + * output, a 2D array s + */ + public void getNeighborhood(int x, int y, double neigh[][]) { + int bx = neigh.length; + int by = neigh[0].length; + int bx2 = (bx - 1) / 2; + int by2 = (by - 1) / 2; + if (x >= bx2) + if (y >= by2) + if (x < nx - bx2 - 1) + if (y < ny - by2 - 1) { + int index = (y - by2) * nx + (x - bx2); + for (int j = 0; j < by; j++) { + for (int i = 0; i < bx; i++) { + neigh[i][j] = pixels[index++]; + } + index += (nx - bx); + } + return; + } + int xt[] = new int[bx]; + for (int k = 0; k < bx; k++) { + int xa = x + k - bx2; + int periodx = 2 * nx - 2; + while (xa < 0) + xa += periodx; // Periodize + while (xa >= nx) { + xa = periodx - xa; // Symmetrize + if (xa < 0) + xa = -xa; + } + xt[k] = xa; + } + int yt[] = new int[by]; + for (int k = 0; k < by; k++) { + int ya = y + k - by2; + int periody = 2 * ny - 2; + while (ya < 0) + ya += periody; // Periodize + while (ya >= ny) { + ya = periody - ya; // Symmetrize + if (ya < 0) + ya = -ya; + } + yt[k] = ya; + } + int sum = 0; + for (int j = 0; j < by; j++) { + int index = yt[j] * nx; + for (int i = 0; i < bx; i++) { + sum = index + xt[i]; + neigh[i][j] = pixels[sum]; + } + } + } + + /** + * An ImageAccess object calls this method for getting a neighborhood of a + * predefined pattern around a selected pixel (x,y). <br> + * The available patterns are: <br> + * - a 3*3 block: PATTERN_SQUARE_3x3 (8-connect) <br> + * - a 3*3 cross: PATTERN_CROSS_3x3 (4-connect) <br> + * <br> + * Mirror border conditions are applied. <br> + * The pixel is arranged in a 1D array according the following rules: <br> + * <br> + * If the pattern is PATTERN_SQUARE_3x3 (8-connect) <br> + * The pixel value of (x-1, y-1) are put into neigh[0] <br> + * The pixel value of (x , y-1) are put into neigh[1] <br> + * The pixel value of (x+1, y-1) are put into neigh[2] <br> + * The pixel value of (x-1, y ) are put into neigh[3] <br> + * The pixel value of (x , y ) are put into neigh[4] <br> + * The pixel value of (x+1, y ) are put into neigh[5] <br> + * The pixel value of (x-1, y+1) are put into neigh[6] <br> + * The pixel value of (x , y+1) are put into neigh[7] <br> + * The pixel value of (x+1, y+1) are put into neigh[8] <br> + * <br> + * If the pattern is PATTERN_CROSS_3x3 (4-connect) <br> + * The pixel value of (x , y-1) are put into neigh[0] <br> + * The pixel value of (x-1, y ) are put into neigh[1] <br> + * The pixel value of (x , y ) are put into neigh[2] <br> + * The pixel value of (x+1, y ) are put into neigh[3] <br> + * The pixel value of (x , y+1) are put into neigh[4] <br> + * <br> + * The neigh should already created as a double array of 9 elements for the + * PATTERN_SQUARE_3x3 or 5 elements for the PATTERN_CROSS_3x3. + * + * @param x + * x-coordinate of a selected central pixel + * @param y + * y-coordinate of a selected central pixel + * @param neigh + * output, an array consisting of 9 or 5 elements + * @param pattern + * PATTERN_SQUARE_3x3 or PATTERN_CROSS_3x3. + */ + public void getPattern(int x, int y, double neigh[], int pattern) { + if (neigh == null) + throw new ArrayStoreException("getPattern: neigh == null."); + switch (pattern) { + case PATTERN_SQUARE_3x3: + if (neigh.length != 9) + throw new ArrayStoreException("getPattern: neigh.length != 9."); + getPatternSquare3x3(x, y, neigh); + break; + case PATTERN_CROSS_3x3: + if (neigh.length != 5) + throw new ArrayStoreException("getPattern: neigh.length != 5"); + getPatternCross3x3(x, y, neigh); + break; + default: + throw new ArrayStoreException("getPattern: unexpected pattern."); + } + } + + /** + * An ImageAccess object calls this method for getting a 3x3 neighborhood of + * 8-connected pixels around a selected pixel. + * + * @param x + * input, the integer x-coordinate of a selected central pixel + * @param y + * input, the integer y-coordinate of a selected central pixel + * @param neigh + * output, an array consisting of 9 elements of the type double + */ + private void getPatternSquare3x3(int x, int y, double neigh[]) { + if (x >= 1) + if (y >= 1) + if (x < nx - 1) + if (y < ny - 1) { + int index = (y - 1) * nx + (x - 1); + neigh[0] = pixels[index++]; + neigh[1] = pixels[index++]; + neigh[2] = pixels[index]; + index += (nx - 2); + neigh[3] = pixels[index++]; + neigh[4] = pixels[index++]; + neigh[5] = pixels[index]; + index += (nx - 2); + neigh[6] = pixels[index++]; + neigh[7] = pixels[index++]; + neigh[8] = pixels[index]; + return; + } + int x1 = x - 1; + int x2 = x; + int x3 = x + 1; + int y1 = y - 1; + int y2 = y; + int y3 = y + 1; + if (x == 0) + x1 = x3; + if (y == 0) + y1 = y3; + if (x == nx - 1) + x3 = x1; + if (y == ny - 1) + y3 = y1; + int offset = y1 * nx; + neigh[0] = pixels[offset + x1]; + neigh[1] = pixels[offset + x2]; + neigh[2] = pixels[offset + x3]; + offset = y2 * nx; + neigh[3] = pixels[offset + x1]; + neigh[4] = pixels[offset + x2]; + neigh[5] = pixels[offset + x3]; + offset = y3 * nx; + neigh[6] = pixels[offset + x1]; + neigh[7] = pixels[offset + x2]; + neigh[8] = pixels[offset + x3]; + } + + /** + * An ImageAccess object calls this method for getting a 3x3 neighborhood of + * 4-connected pixels around a selected pixel. + * + * @param x + * input, the integer x-coordinate of a selected central pixel + * @param y + * input, the integer y-coordinate of a selected central pixel + * @param neigh + * output, an array consisting of 5 elements of the type double + */ + private void getPatternCross3x3(int x, int y, double neigh[]) { + if (x >= 1) + if (y >= 1) + if (x < nx - 1) + if (y < ny - 1) { + int index = (y - 1) * nx + x; + neigh[0] = pixels[index]; + index += (nx - 1); + neigh[1] = pixels[index++]; + neigh[2] = pixels[index++]; + neigh[3] = pixels[index]; + index += (nx - 1); + neigh[4] = pixels[index]; + return; + } + int x1 = x - 1; + int x2 = x; + int x3 = x + 1; + int y1 = y - 1; + int y2 = y; + int y3 = y + 1; + if (x == 0) + x1 = x3; + if (y == 0) + y1 = y3; + if (x == nx - 1) + x3 = x1; + if (y == ny - 1) + y3 = y1; + int offset = y1 * nx; + neigh[0] = pixels[offset + x2]; + offset = y2 * nx; + neigh[1] = pixels[offset + x1]; + neigh[2] = pixels[offset + x2]; + neigh[3] = pixels[offset + x3]; + offset = y3 * nx; + neigh[4] = pixels[offset + x2]; + } + + /** + * An ImageAccess object calls this method to get a sub-image with the upper + * left corner in the coordinate (x,y). + * + * The sub-image ouptut should be already created. + * + * @param x + * x-coordinate in the source image + * @param y + * y-coordinate in the source image + * @param output + * an ImageAccess object with the sub-image; + */ + public void getSubImage(int x, int y, ImageAccess output) { + if (output == null) + throw new ArrayStoreException("getSubImage: output == null."); + if (x < 0) + throw new ArrayStoreException("getSubImage: Incompatible image size"); + if (y < 0) + throw new ArrayStoreException("getSubImage: Incompatible image size"); + if (x >= nx) + throw new ArrayStoreException("getSubImage: Incompatible image size"); + if (y >= ny) + throw new ArrayStoreException("getSubImage: Incompatible image size"); + int nxcopy = output.getWidth(); + int nycopy = output.getHeight(); + double[][] neigh = new double[nxcopy][nycopy]; + int nx2 = (nxcopy - 1) / 2; + int ny2 = (nycopy - 1) / 2; + this.getNeighborhood(x + nx2, y + ny2, neigh); + output.putArrayPixels(neigh); + } + + /** + * An ImageAccess object calls this method in order a value of the gray + * level to be put to a position inside it given by the coordinates. + * + * @param x + * input, the integer x-coordinate of a pixel + * @param y + * input, the integer y-coordinate of a pixel + * @param value + * input, a value of the gray level of the type double + */ + public void putPixel(int x, int y, double value) { + if (x < 0) + return; + if (x >= nx) + return; + if (y < 0) + return; + if (y >= ny) + return; + pixels[x + y * nx] = value; + } + + /** + * An ImageAccess object calls this method to put a whole column in a + * specified position into the image. + * + * @param x + * input, the integer x-coordinate of a column + * @param column + * input, an array of the type double + */ + public void putColumn(int x, double[] column) { + if (x < 0) + throw new IndexOutOfBoundsException("putColumn: x < 0."); + if (x >= nx) + throw new IndexOutOfBoundsException("putColumn: x >= nx."); + if (column == null) + throw new ArrayStoreException("putColumn: column == null."); + if (column.length != ny) + throw new ArrayStoreException("putColumn: column.length != ny."); + for (int i = 0; i < ny; i++) { + pixels[x] = column[i]; + x += nx; + } + } + + /** + * An ImageAccess object calls this method to put a part of column into the + * image. The starting poisition in given by y and the ending position is + * determined by the size of the column array. + * + * @param x + * input, the integer x-coordinate of a column + * @param y + * input, the integer y-coordinate of a column + * @param column + * input, an array of the type double + */ + public void putColumn(int x, int y, double[] column) { + if (x < 0) + throw new IndexOutOfBoundsException("putColumn: x < 0."); + if (x >= nx) + throw new IndexOutOfBoundsException("putColumn: x >= nx."); + if (column == null) + throw new ArrayStoreException("putColumn: column == null."); + int by = column.length; + int index = y * nx + x; + int top = 0; + int bottom = 0; + if (y >= 0) { + if (y < ny - by) + bottom = by; + else + bottom = -y + ny; + for (int i = top; i < bottom; i++) { + pixels[index] = column[i]; + index += nx; + } + return; + } + else { + index = x; + top = -y; + if (y < ny - by) + bottom = by; + else + bottom = -y + ny; + for (int i = top; i < bottom; i++) { + pixels[index] = column[i]; + index += nx; + } + } + } + + /** + * An ImageAccess object calls this method to put a whole row in a specified + * position into the image. + * + * @param y + * input, the integer y-coordinate of a row + * @param row + * input, an array of the type double + */ + public void putRow(int y, double[] row) { + if (y < 0) + throw new IndexOutOfBoundsException("putRow: y < 0."); + if (y >= ny) + throw new IndexOutOfBoundsException("putRow: y >= ny."); + if (row == null) + throw new ArrayStoreException("putRow: row == null."); + if (row.length != nx) + throw new ArrayStoreException("putRow: row.length != nx."); + y *= nx; + for (int i = 0; i < nx; i++) { + pixels[y++] = row[i]; + } + + } + + /** + * An ImageAccess object calls this method to put a part of row into the + * image. The starting poisition in given by x and the ending position is + * determined by the size of the row array. + * + * @param x + * input, the integer x-coordinate of a column + * @param y + * input, the integer y-coordinate of a row + * @param row + * input, an array of the type double + */ + public void putRow(int x, int y, double[] row) { + if (y < 0) + throw new IndexOutOfBoundsException("putRow: y < 0."); + if (y >= ny) + throw new IndexOutOfBoundsException("putRow: y >= ny."); + if (row == null) + throw new ArrayStoreException("putRow: row == null."); + int bx = row.length; + int index = y * nx + x; + int left = 0; + int right = 0; + if (x >= 0) { + if (x < nx - bx) + right = bx; + else + right = -x + nx; + + for (int i = left; i < right; i++) { + pixels[index++] = row[i]; + } + return; + } + else { + index = y * nx; + left = -x; + + if (x < nx - bx) + right = bx; + else + right = -x + nx; + + for (int i = left; i < right; i++) { + pixels[index++] = row[i]; + } + } + } + + /** + * An ImageAccess object calls this method in order to put an 2D array of + * double in an ImageAccess. + * + * @param array + * input, the double array + */ + public void putArrayPixels(double[][] array) { + if (array == null) + throw new IndexOutOfBoundsException("putArrayPixels: array == null."); + int bx = array.length; + int by = array[0].length; + if (bx * by != size) + throw new IndexOutOfBoundsException("putArrayPixels: imcompatible size."); + int k = 0; + for (int j = 0; j < by; j++) + for (int i = 0; i < bx; i++) + pixels[k++] = array[i][j]; + } + + /** + * An ImageAccess object calls this method to put a sub-image with the upper + * left corner in the coordinate (x,y). + * + * The sub-image input should be already created. + * + * @param x + * x-coordinate in the source image + * @param y + * y-coordinate in the source image + * @param input + * an ImageAccess object that we want to put; + */ + public void putSubImage(int x, int y, ImageAccess input) { + if (input == null) + throw new ArrayStoreException("putSubImage: input == null."); + if (x < 0) + throw new IndexOutOfBoundsException("putSubImage: x < 0."); + if (y < 0) + throw new IndexOutOfBoundsException("putSubImage: y < 0."); + if (x >= nx) + throw new IndexOutOfBoundsException("putSubImage: x >= nx."); + if (y >= ny) + throw new IndexOutOfBoundsException("putSubImage: y >= ny."); + int nxcopy = input.getWidth(); + int nycopy = input.getHeight(); + // Reduces the size of the area to copy if it is too large + if (x + nxcopy > nx) + nxcopy = nx - x; + if (y + nycopy > ny) + nycopy = ny - y; + // Copies lines per lines + double[] dsrc = input.getPixels(); + for (int j = 0; j < nycopy; j++) + System.arraycopy(dsrc, j * nxcopy, pixels, (j + y) * nx + x, nxcopy); + } + + /** + * An ImageAccess object calls this method to set a constant value to all + * pixels of the image. + * + * @param constant + * a constant value + */ + public void setConstant(double constant) { + for (int k = 0; k < size; k++) + pixels[k] = constant; + } + + /** + * Stretches the contrast inside an image so that the gray levels are in the + * range 0 to 255. + */ + public void normalizeContrast() { + double minGoal = 0.0; + double maxGoal = 255.0; + // Search the min and max + double minImage = getMinimum(); + double maxImage = getMaximum(); + // Compute the parameter to rescale the gray levels + double a; + if (minImage - maxImage == 0) { + a = 1.0; + minImage = (maxGoal - minGoal) / 2.0; + } + else + a = (maxGoal - minGoal) / (maxImage - minImage); + for (int i = 0; i < size; i++) { + pixels[i] = (float) (a * (pixels[i] - minImage) + minGoal); + } + } + + /** + * Display an image at a specific position (x, y). + * + * @param title + * a string for the title + * @param loc + * Point for the location + */ + public void show(String title, java.awt.Point loc) { + FloatProcessor fp = createFloatProcessor(); + fp.resetMinAndMax(); + ImagePlus impResult = new ImagePlus(title, fp); + impResult.show(); + ij.gui.ImageWindow window = impResult.getWindow(); + window.setLocation(loc.x, loc.y); + impResult.show(); + } + + /** + * Display an image. + * + * @param title + * a string for the title of the window + */ + public void show(String title) { + FloatProcessor fp = createFloatProcessor(); + fp.resetMinAndMax(); + ImagePlus impResult = new ImagePlus(title, fp); + impResult.show(); + } + + /** + * Compute the absolute value. + */ + public void abs() { + for (int k = 0; k < size; k++) + pixels[k] = Math.abs(pixels[k]); + } + + /** + * Compute the square root of an ImageAccess. + */ + public void sqrt() { + for (int k = 0; k < size; k++) { + pixels[k] = Math.sqrt(pixels[k]); + } + } + + /** + * Raised an ImageAccess object to the power a. + * + * @param a + * input + */ + public void pow(final double a) { + for (int k = 0; k < size; k++) { + pixels[k] = Math.pow(pixels[k], a); + } + } + + /** + * An ImageAccess object calls this method for adding a constant to each + * pixel. + * + * @param constant + * a constant to be added + */ + public void add(double constant) { + for (int k = 0; k < size; k++) + pixels[k] += constant; + } + + /** + * An ImageAccess object calls this method for multiplying a constant to + * each pixel. + * + * @param constant + * a constant to be multiplied + */ + public void multiply(final double constant) { + for (int k = 0; k < size; k++) + pixels[k] *= constant; + } + + /** + * An ImageAccess object calls this method for adding a constant to each + * pixel. + * + * @param constant + * a constant to be subtracted + */ + public void subtract(final double constant) { + for (int k = 0; k < size; k++) + pixels[k] -= constant; + } + + /** + * An ImageAccess object calls this method for dividing a constant to each + * pixel. + * + * @param constant + * a constant to be divided + */ + public void divide(final double constant) { + if (constant == 0.0) + throw new ArrayStoreException("divide: Divide by 0"); + for (int k = 0; k < size; k++) + pixels[k] /= constant; + } + + /** + * An ImageAccess object calls this method for adding two ImageAccess + * objects. + * + * [this = im1 + im2] + * + * The resulting ImageAccess and the two operands should have the same size. + * + * @param im1 + * an ImageAccess object to be added + * @param im2 + * an ImageAccess object to be added + */ + public void add(ImageAccess im1, ImageAccess im2) { + if (im1.getWidth() != nx) + throw new ArrayStoreException("add: incompatible size."); + if (im1.getHeight() != ny) + throw new ArrayStoreException("add: incompatible size."); + if (im2.getWidth() != nx) + throw new ArrayStoreException("add: incompatible size."); + if (im2.getHeight() != ny) + throw new ArrayStoreException("add: incompatible size."); + double[] doubleOperand1 = im1.getPixels(); + double[] doubleOperand2 = im2.getPixels(); + for (int k = 0; k < size; k++) + pixels[k] = doubleOperand1[k] + doubleOperand2[k]; + } + + /** + * An ImageAccess object calls this method for multiplying two ImageAccess + * objects. + * + * The resulting ImageAccess and the two operands should have the same size. + * + * [this = im1 * im2] + * + * @param im1 + * an ImageAccess object to be multiplied + * @param im2 + * an ImageAccess object to be multiplied + */ + + public void multiply(ImageAccess im1, ImageAccess im2) { + if (im1.getWidth() != nx) + throw new ArrayStoreException("multiply: incompatible size."); + if (im1.getHeight() != ny) + throw new ArrayStoreException("multiply: incompatible size."); + if (im2.getWidth() != nx) + throw new ArrayStoreException("multiply: incompatible size."); + if (im2.getHeight() != ny) + throw new ArrayStoreException("multiply: incompatible size."); + double[] doubleOperand1 = im1.getPixels(); + double[] doubleOperand2 = im2.getPixels(); + for (int k = 0; k < size; k++) + pixels[k] = doubleOperand1[k] * doubleOperand2[k]; + } + + /** + * An ImageAccess object calls this method for subtracting two ImageAccess + * objects. + * + * The resulting ImageAccess and the two operands should have the same size. + * + * [this = im1 - im2] + * + * @param im1 + * an ImageAccess object to be subtracted + * @param im2 + * an ImageAccess object to be subtracted + */ + + public void subtract(ImageAccess im1, ImageAccess im2) { + if (im1.getWidth() != nx) + throw new ArrayStoreException("subtract: incompatible size."); + if (im1.getHeight() != ny) + throw new ArrayStoreException("subtract: incompatible size."); + if (im2.getWidth() != nx) + throw new ArrayStoreException("subtract: incompatible size."); + if (im2.getHeight() != ny) + throw new ArrayStoreException("subtract: incompatible size."); + double[] doubleOperand1 = im1.getPixels(); + double[] doubleOperand2 = im2.getPixels(); + for (int k = 0; k < size; k++) + pixels[k] = doubleOperand1[k] - doubleOperand2[k]; + } + + /** + * An ImageAccess object calls this method for dividing two ImageAccess + * objects. + * + * [this = im1 / im2] + * + * The resulting ImageAccess and the two operands should have the same size. + * + * @param im1 + * numerator + * @param im2 + * denominator + */ + + public void divide(ImageAccess im1, ImageAccess im2) { + if (im1.getWidth() != nx) + throw new ArrayStoreException("divide: incompatible size."); + if (im1.getHeight() != ny) + throw new ArrayStoreException("divide: incompatible size."); + if (im2.getWidth() != nx) + throw new ArrayStoreException("divide: incompatible size."); + if (im2.getHeight() != ny) + throw new ArrayStoreException("divide: incompatible size."); + double[] doubleOperand1 = im1.getPixels(); + double[] doubleOperand2 = im2.getPixels(); + for (int k = 0; k < size; k++) + pixels[k] = doubleOperand1[k] / doubleOperand2[k]; + } + +} diff --git a/src/bilib/src/wavelets/WaveSpline.java b/src/bilib/src/wavelets/WaveSpline.java new file mode 100644 index 0000000000000000000000000000000000000000..9d16d4a91829cbc8625e730e68b9cc2eeaecab65 --- /dev/null +++ b/src/bilib/src/wavelets/WaveSpline.java @@ -0,0 +1,423 @@ +package wavelets; + +/** + * Spline wavelets transformation + * <hr> + * <p> + * <b>Organisation</b>: <a href="http://bigwww.epfl.ch">Biomedical Imaging + * Group</a> (BIG), Ecole Polytechnique Federale de Lausanne (EPFL), Lausanne, + * Switzerland + * </p> + * <p> + * <b>Authors</b>: Daniel Sage + * </p> + * <p> + * <b>Reference</b>: D. Sage, M. Unser, "<a + * href="http://bigwww.epfl.ch/publications/sage0303.html">Teaching + * Image-Processing Programming in Java</a>," IEEE Signal Processing + * Magazine, vol. 20, no. 6, pp. 43-52, November 2003. + * </p> + * <p> + * More information: http://bigwww.epfl.ch/teaching/iplabsite/index.php + * </p> + * <p> + * Other relevant information are available at: http://bigwww.epfl.ch/ + * </p> + * <hr> + * You'll be free to use this software for research purposes, but you should not + * redistribute it without our consent. In addition, we expect you to include a + * citation or acknowledgement whenever you present or publish results that are + * based on it. + */ + +public class WaveSpline { + + /** + * Perform an wavelet transformation of the ImageObject calling this method + * with n scale. The size of image should be a interger factor of 2 at the + * power n. The input is an image. The result is the wavelet coefficients. + * It is put in the ImageObject calling this method. + * + * @param in + * an ImageAcess object provided by ImageJ + * @param n + * a integer value giving the number of scale + */ + static public ImageAccess analysis(ImageAccess in, int order, int n) { + + // Compute the size to the fine and coarse levels + int div = (int) Math.pow(2.0, (double) (n - 1)); + int nxfine = in.getWidth(); + int nyfine = in.getHeight(); + int nxcoarse = nxfine / div; + int nycoarse = nyfine / div; + + // Declare the object image + ImageAccess sub; + + // Initialization + int nx = nxfine; + int ny = nyfine; + ImageAccess out = in.duplicate(); + + // From fine to coarse main loop + for (int i = 0; i < n; i++) { + + // Create a new image array of size [nx,ny] + sub = new ImageAccess(nx, ny); + + // Copy in[] into image[] + out.getSubImage(0, 0, sub); + + // Apply the Wavelet splitting + sub = split(sub, order); + + // Put the result image[] into in[] + out.putSubImage(0, 0, sub); + + // Reduce the size by a factor of 2 + nx = nx / 2; + ny = ny / 2; + } + return out; + } + + /** + * Perform 1 iteration of the wavelet transformation of an ImageObject. The + * algorithm use the separability of the wavelet transformation. The result + * of the computation is put in the ImageObject calling this method. + * + * @param in + * an ImageAcess object provided by ImageJ + */ + static private ImageAccess split(ImageAccess in, int order) { + int nx = in.getWidth(); + int ny = in.getHeight(); + ImageAccess out = new ImageAccess(nx, ny); + + WaveSplineFilter wf = new WaveSplineFilter(order); + + if (nx >= 1) { + double rowin[] = new double[nx]; + double rowout[] = new double[nx]; + for (int y = 0; y < ny; y++) { + in.getRow(y, rowin); + split_1D(rowin, rowout, wf.h, wf.g); + out.putRow(y, rowout); + } + } + else { + // out.copy(in); + out = in.duplicate(); + } + + if (ny > 1) { + double colin[] = new double[ny]; + double colout[] = new double[ny]; + for (int x = 0; x < nx; x++) { + out.getColumn(x, colin); + split_1D(colin, colout, wf.h, wf.g); + out.putColumn(x, colout); + } + } + + return out; + } + + /** + * Perform 1 iteration of the wavelet transformation of a 1D vector using + * the spline wavelet transformation. The output vector has the same size of + * the input vector and it contains first the low pass part of the wavelet + * transform and then the high pass part of the wavelet transformation. + * + * @param vin + * input, a double 1D vector + * @param vout + * output, a double 1D vector + * @param h + * input, a double 1D vector, lowpass filter + * @param g + * input, a double 1D vector, highpass filter + */ + static private void split_1D(double vin[], double vout[], double h[], double g[]) { + int n = vin.length; + int n2 = n / 2; + int nh = h.length; + int ng = g.length; + + // /////////////////////////////////////////// + // Order is 0 -> Haar Transform + // /////////////////////////////////////////// + if ((nh <= 1) || (ng <= 1)) { + double sqrt2 = Math.sqrt(2); + int j; + for (int i = 0; i < n2; i++) { + j = 2 * i; + vout[i] = (vin[j] + vin[j + 1]) / sqrt2; + vout[i + n2] = (vin[j] - vin[j + 1]) / sqrt2; + } + return; + } + + // /////////////////////////////////////////// + // Order is higher than 0 + // /////////////////////////////////////////// + double pix; + int j, k, j1, j2; + int period = 2 * n - 2; // period for mirror boundary conditions + + for (int i = 0; i < n2; i++) { + j = i * 2; + pix = vin[j] * h[0]; + for (k = 1; k < nh; k++) { // Low pass part + j1 = j - k; + if (j1 < 0) { // Mirror conditions + while (j1 < 0) + j1 += period; // Periodize + if (j1 >= n) + j1 = period - j1; // Symmetrize + } + j2 = j + k; + if (j2 >= n) { // Mirror conditions + while (j2 >= n) + j2 -= period; // Periodize + if (j2 < 0) + j2 = -j2; // Symmetrize + } + pix = pix + h[k] * (vin[j1] + vin[j2]); + } + vout[i] = pix; + + j = j + 1; + pix = vin[j] * g[0]; // High pass part + for (k = 1; k < ng; k++) { + j1 = j - k; + if (j1 < 0) { // Mirror conditions + while (j1 < 0) + j1 += period; // Periodize + if (j1 >= n) + j1 = period - j1; // Symmetrize + } + j2 = j + k; + if (j2 >= n) { // Mirror conditions + while (j2 >= n) + j2 -= period; // Periodize + if (j2 < 0) + j2 = -j2; // Symmetrize + } + pix = pix + g[k] * (vin[j1] + vin[j2]); + } + vout[i + n2] = pix; + } + } + + /** + * Perform an inverse wavelet transformation of the ImageObject calling this + * method with n scale. The size of image should be a interger factor of 2 + * at the power n. The input is the results of a wavelet transformation. The + * result is the reconstruction. It is put in the ImageObject calling this + * method. + * + * @param in + * an ImageAcess object provided by ImageJ + * @param n + * a integer value giving the number of scale + */ + + static public ImageAccess synthesis(ImageAccess in, int order, int n) { + // Compute the size to the fine and coarse levels + int div = (int) Math.pow(2.0, (double) (n - 1)); + int nxcoarse = in.getWidth() / div; + int nycoarse = in.getHeight() / div; + + // Declare the object image + ImageAccess sub; + + // Initialisazion + int nx = nxcoarse; + int ny = nycoarse; + ImageAccess out = in.duplicate(); + + // From fine to coarse main loop + for (int i = 0; i < n; i++) { + + // Create a new image array of size [nx,ny] + sub = new ImageAccess(nx, ny); + + // Copy in[] into image[] + out.getSubImage(0, 0, sub); + + // Apply the Wavelet splitting + sub = merge(sub, order); + + // Put the result image[] into in[] + out.putSubImage(0, 0, sub); + // Reduce the size by a factor of 2 + nx = nx * 2; + ny = ny * 2; + } + return out; + } + + /** + * Perform 1 iteration of the inverse wavelet transformation of an + * ImageObject. The algorithm use the separability of the wavelet + * transformation. The result of the computation is put in the ImageObject + * calling this method. + * + * @param in + * an ImageAcess object provided by ImageJ + */ + static private ImageAccess merge(ImageAccess in, int order) { + int nx = in.getWidth(); + int ny = in.getHeight(); + ImageAccess out = new ImageAccess(nx, ny); + WaveSplineFilter wf = new WaveSplineFilter(order); + + if (nx >= 1) { + int nx2 = nx / 2; + double rowin[] = new double[nx]; + double rowout[] = new double[nx]; + for (int y = 0; y < ny; y++) { + in.getRow(y, rowin); + merge_1D(rowin, rowout, wf.h, wf.g); + out.putRow(y, rowout); + } + } + else { + out = in.duplicate(); + } + + if (ny > 1) { + int ny2 = ny / 2; + double colin[] = new double[ny]; + double colout[] = new double[ny]; + for (int x = 0; x < nx; x++) { + out.getColumn(x, colin); + merge_1D(colin, colout, wf.h, wf.g); + out.putColumn(x, colout); + } + } + return out; + } + + /** + * Perform 1 iteration of the inverse wavelet transformation of a 1D vector + * using the Spline wavelet transformation. The output vector has the same + * size of the input vector and it contains the reconstruction of the input + * signal. The input vector constains first the low pass part of the wavelet + * transform and then the high pass part of the wavelet transformation. + * + * @param vin + * input, a double 1D vector + * @param vout + * output, a double 1D vector + * @param h + * input, a double 1D vector, lowpass filter + * @param g + * input, a double 1D vector, highpass filter + */ + static private void merge_1D(double vin[], double vout[], double h[], double g[]) { + int n = vin.length; + int n2 = n / 2; + int nh = h.length; + int ng = g.length; + + // /////////////////////////////////////////// + // Order is 0 -> Haar Transform + // /////////////////////////////////////////// + if ((nh <= 1) || (ng <= 1)) { + double sqrt2 = Math.sqrt(2); + for (int i = 0; i < n2; i++) { + vout[2 * i] = (vin[i] + vin[i + n2]) / sqrt2; + vout[2 * i + 1] = (vin[i] - vin[i + n2]) / sqrt2; + } + return; + } + + // /////////////////////////////////////////// + // Order is higher than 0 + // /////////////////////////////////////////// + double pix1, pix2; + int j, k, kk, i1, i2; + int k01 = (nh / 2) * 2 - 1; + int k02 = (ng / 2) * 2 - 1; + + int period = 2 * n2 - 1; // period for mirror boundary conditions + + for (int i = 0; i < n2; i++) { + j = 2 * i; + pix1 = h[0] * vin[i]; + for (k = 2; k < nh; k += 2) { + i1 = i - (k / 2); + if (i1 < 0) { + i1 = (-i1) % period; + if (i1 >= n2) + i1 = period - i1; + } + i2 = i + (k / 2); + if (i2 > n2 - 1) { + i2 = i2 % period; + if (i2 >= n2) + i2 = period - i2; + } + pix1 = pix1 + h[k] * (vin[i1] + vin[i2]); + } + + pix2 = 0.; + for (k = -k02; k < ng; k += 2) { + kk = Math.abs(k); + i1 = i + (k - 1) / 2; + if (i1 < 0) { + i1 = (-i1 - 1) % period; + if (i1 >= n2) + i1 = period - 1 - i1; + } + if (i1 >= n2) { + i1 = i1 % period; + if (i1 >= n2) + i1 = period - 1 - i1; + } + pix2 = pix2 + g[kk] * vin[i1 + n2]; + } + + vout[j] = pix1 + pix2; + + j = j + 1; + pix1 = 0.; + for (k = -k01; k < nh; k += 2) { + kk = Math.abs(k); + i1 = i + (k + 1) / 2; + if (i1 < 0) { + i1 = (-i1) % period; + if (i1 >= n2) + i1 = period - i1; + } + if (i1 >= n2) { + i1 = (i1) % period; + if (i1 >= n2) + i1 = period - i1; + } + pix1 = pix1 + h[kk] * vin[i1]; + } + pix2 = g[0] * vin[i + n2]; + for (k = 2; k < ng; k += 2) { + i1 = i - (k / 2); + if (i1 < 0) { + i1 = (-i1 - 1) % period; + if (i1 >= n2) + i1 = period - 1 - i1; + } + i2 = i + (k / 2); + if (i2 > n2 - 1) { + i2 = i2 % period; + if (i2 >= n2) + i2 = period - 1 - i2; + } + pix2 = pix2 + g[k] * (vin[i1 + n2] + vin[i2 + n2]); + } + vout[j] = pix1 + pix2; + } + } + +} diff --git a/src/bilib/src/wavelets/WaveSplineFilter.java b/src/bilib/src/wavelets/WaveSplineFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..767390e15bd0519628454f0600d1fe87934c7592 --- /dev/null +++ b/src/bilib/src/wavelets/WaveSplineFilter.java @@ -0,0 +1,181 @@ +package wavelets; + +/** + * Spline wavelets transformation + * <hr> + * <p> + * <b>Organisation</b>: <a href="http://bigwww.epfl.ch">Biomedical Imaging + * Group</a> (BIG), Ecole Polytechnique Federale de Lausanne (EPFL), Lausanne, + * Switzerland + * </p> + * <p> + * <b>Authors</b>: Daniel Sage + * </p> + * <p> + * <b>Reference</b>: D. Sage, M. Unser, "<a + * href="http://bigwww.epfl.ch/publications/sage0303.html">Teaching + * Image-Processing Programming in Java</a>," IEEE Signal Processing + * Magazine, vol. 20, no. 6, pp. 43-52, November 2003. + * </p> + * <p> + * More information: http://bigwww.epfl.ch/teaching/iplabsite/index.php + * </p> + * <p> + * Other relevant information are available at: http://bigwww.epfl.ch/ + * </p> + * <hr> + * You'll be free to use this software for research purposes, but you should not + * redistribute it without our consent. In addition, we expect you to include a + * citation or acknowledgement whenever you present or publish results that are + * based on it. + */ + +public class WaveSplineFilter { + + /** + * real lowpass filter. + */ + public double h[]; + + /** + * real highpass filter. + */ + public double g[]; + + WaveSplineFilter(int order) { + switch (order) { + + case 0: + h = new double[1]; + h[0] = Math.sqrt(2.0); + break; + + case 1: + h = new double[47]; + h[0] = 0.81764640621546; + h[1] = 0.39729708810751; + h[2] = -0.06910098743038; + h[3] = -0.05194534825542; + h[4] = 0.01697104840045; + h[5] = 0.00999059568192; + h[6] = -0.00388326235731; + h[7] = -0.00220195129177; + h[8] = 0.00092337104427; + h[9] = 0.00051163604209; + h[10] = -0.00022429633694; + h[11] = -0.00012268632858; + h[12] = 0.00005535633860; + h[13] = 0.00003001119291; + h[14] = -0.00001381880394; + h[15] = -0.00000744435611; + h[16] = 0.00000347980027; + h[17] = 0.00000186561005; + h[18] = -0.00000088225856; + h[19] = -0.00000047122304; + h[20] = 0.00000022491351; + h[21] = 0.00000011976480; + h[22] = -0.00000005759525; + h[23] = -0.00000003059265; + h[24] = 0.00000001480431; + h[25] = 0.00000000784714; + h[26] = -0.00000000381742; + h[27] = -0.00000000201987; + h[28] = 0.00000000098705; + h[29] = 0.00000000052147; + h[30] = -0.00000000025582; + h[31] = -0.00000000013497; + h[32] = 0.00000000006644; + h[33] = 0.00000000003501; + h[34] = -0.00000000001729; + h[35] = -0.00000000000910; + h[36] = 0.00000000000451; + h[37] = 0.00000000000237; + h[38] = -0.00000000000118; + h[39] = -0.00000000000062; + h[40] = 0.00000000000031; + h[41] = 0.00000000000016; + h[42] = -0.00000000000008; + h[43] = -0.00000000000004; + h[44] = 0.00000000000002; + h[45] = 0.00000000000001; + break; + + case 3: + double temp[] = { 0.76613005375980, 0.43392263358931, -0.05020172467149, -0.11003701838811, 0.03208089747022, 0.04206835144072, -0.01717631549201, -0.01798232098097, + 0.00868529481309, 0.00820147720600, -0.00435383945777, -0.00388242526560, 0.00218671237015, 0.00188213352389, -0.00110373982039, -0.00092719873146, 0.00055993664336, + 0.00046211522752, -0.00028538371867, -0.00023234729403, 0.00014604186978, 0.00011762760216, -0.00007499842461, -0.00005987934057, 0.00003863216129, 0.00003062054907, + -0.00001995254847, -0.00001571784835, 0.00001032898225, 0.00000809408097, -0.00000535805976 - 0.00000417964096, 0.00000278450629, 0.00000216346143, -0.00000144942177, + -0.00000112219704, 0.00000075557065, 0.00000058316635, -0.00000039439119, -0.00000030355006, 0.00000020610937, 0.00000015823692, -0.00000010783016, -0.00000008259641, + 0.00000005646954, 0.00000004316539, -0.00000002959949, -0.00000002258313, 0.00000001552811, 0.00000001182675, -0.00000000815248, -0.00000000619931, 0.00000000428324, + 0.00000000325227, -0.00000000225188, -0.00000000170752, 0.00000000118465, 0.00000000089713, -0.00000000062357, -0.00000000047167, 0.00000000032841, 0.00000000024814, + -0.00000000017305, -0.00000000013062, 0.00000000009123, 0.00000000006879, -0.00000000004811, -0.00000000003625, 0.00000000002539, 0.00000000001911, -0.00000000001340, + -0.00000000001008, 0.00000000000708, 0.00000000000532, -0.00000000000374, -0.00000000000281, 0.00000000000198, 0.00000000000148, -0.00000000000104, -0.00000000000078, + 0.00000000000055, 0.00000000000041, -0.00000000000029, -0.00000000000022, 0.00000000000015, 0.00000000000012, -0.00000000000008 - 0.00000000000006, 0.00000000000004, + 0.00000000000003, -0.00000000000002, -0.00000000000002, 0.00000000000001, 0.00000000000001, -0.00000000000001, -0.00000000000000 }; + h = temp; + break; + + case 5: + h = new double[42]; + h[0] = 0.74729; + h[1] = 0.4425; + h[2] = -0.037023; + h[3] = -0.12928; + h[4] = 0.029477; + h[5] = 0.061317; + h[6] = -0.021008; + h[7] = -0.032523; + h[8] = 0.014011; + h[9] = 0.01821; + h[10] = -0.0090501; + h[11] = -0.010563; + h[12] = 0.0057688; + h[13] = 0.0062796; + h[14] = -0.0036605; + h[15] = -0.0037995; + h[16] = 0.0023214; + h[17] = 0.0023288; + h[18] = -0.0014738; + h[19] = -0.0014414; + h[20] = 0.00093747; + h[21] = 0.00089889; + h[22] = -0.00059753; + h[23] = -0.00056398; + h[24] = 0.00038165; + h[25] = 0.00035559; + h[26] = -0.00024423; + h[27] = -0.00022512; + h[28] = 0.00015658; + h[29] = 0.00014301; + h[30] = -0.00010055; + h[31] = -9.1113e-05; + h[32] = 6.4669e-05; + h[33] = 5.8198e-05; + h[34] = -4.1649e-05; + h[35] = -3.7256e-05; + h[36] = 2.729e-05; + h[37] = 2.458e-05; + h[38] = -2.2593e-05; + h[39] = -3.5791e-05; + h[40] = -1.7098e-05; + h[41] = -2.9619e-06; + break; + } + + g = new double[h.length]; + if (order > 0) { + g[0] = h[0]; + for (int k = 1; k < h.length; k++) { + if ((k / 2) * 2 == k) + g[k] = h[k]; + else + g[k] = -h[k]; + } + } + else { + g[0] = -h[0]; + } + + } + +} \ No newline at end of file diff --git a/src/src/eigenpsf/AdvancedSettingsPanel.java b/src/src/eigenpsf/AdvancedSettingsPanel.java index 68abe9e94e5c1aedf64182a752ecae5bc5ed0f08..c48457a1f0d4cb39de0e8acf702a452ee2b7e1b6 100644 --- a/src/src/eigenpsf/AdvancedSettingsPanel.java +++ b/src/src/eigenpsf/AdvancedSettingsPanel.java @@ -21,7 +21,6 @@ import eigenpsf.gui.SpinnerInfoRangeInteger; public class AdvancedSettingsPanel extends JPanel implements ChangeListener, KeyListener, ItemListener { - private SpinnerInfoRangeDouble spnQuantile = new SpinnerInfoRangeDouble(Params.quantile, 0.01, 1000, 0.1, "Threshold to discard bad beads from the quality score (see related column in the result table).", "http://bigwww.epfl.ch/"); private SpinnerInfoRangeInteger spnNumberPoints = new SpinnerInfoRangeInteger(Params.nthin, 1, 100, 1, "Number of thin-plate splines used to model the global background. The smaller it is, the smoother the estimated background will be..", "http://bigwww.epfl.ch/"); private SpinnerInfoRangeInteger spnScaleBack = new SpinnerInfoRangeInteger(Params.scaleBack, 1, 100, 1, "Data reduction factor to speed up computation (e.g., if set to 2, then the estimation of the global background will be performed on two-times subsampled images)", "http://bigwww.epfl.ch/"); private SpinnerInfoRangeDouble spnScaleMin = new SpinnerInfoRangeDouble(Params.smin, 0.1, 10, 0.1, "Minimum scaling factor of the basis used in SIFT detection.", "http://bigwww.epfl.ch/"); @@ -95,11 +94,7 @@ public class AdvancedSettingsPanel extends JPanel implements ChangeListener, Key i++; pn1.place(i, 0, 4, 1, "<html> <b> Compute EigenPSF </b> </html>"); i++; - pn1.place(i, 0, 4, 1, new JSeparator()); - i++; - pn1.place(i, 1,"Quality threshold"); - pn1.place(i, 2,spnQuantile); - pn1.place(i, 3,spnQuantile.info); + pn1.place(i, 0, 4, 1, new JSeparator()); i++; pn1.place(i, 1,"Beads normalization"); pn1.place(i, 2,cmbNormalization); @@ -190,7 +185,7 @@ public class AdvancedSettingsPanel extends JPanel implements ChangeListener, Key setLayout(new BorderLayout()); add(pn1, BorderLayout.CENTER); - spnQuantile.addChangeListener(this); + //spnQuantile.addChangeListener(this); spnNumberPoints.addChangeListener(this); spnScaleBack.addChangeListener(this); spnScaleMin.addChangeListener(this); @@ -199,7 +194,7 @@ public class AdvancedSettingsPanel extends JPanel implements ChangeListener, Key spnNbBasis.addChangeListener(this); cmbNormalization.addItemListener(this); - spnQuantile.addKeyListener(this); + //spnQuantile.addKeyListener(this); spnNumberPoints.addKeyListener(this); spnScaleBack.addKeyListener(this); spnScaleMin.addKeyListener(this); @@ -229,7 +224,6 @@ public class AdvancedSettingsPanel extends JPanel implements ChangeListener, Key private void updateParams() { try { - Params.quantile = spnQuantile.get(); Params.nthin = spnNumberPoints.get(); //Params.nthin2D = spnNumberPoints.get(); //Params.nthin3D = spnNumberPoints.get(); @@ -256,7 +250,7 @@ public class AdvancedSettingsPanel extends JPanel implements ChangeListener, Key private void setGUI() { try { - spnQuantile.set(Params.quantile); + //spnQuantile.set(Params.quantile); spnNumberPoints.set(Params.nthin); //spnNumberPoints.set(Params.nthin2D); //spnNumberPoints.set(Params.nthin3D); diff --git a/src/src/eigenpsf/Constants.java b/src/src/eigenpsf/Constants.java index 533af14bfc2cfcce1ab567995d97693796f45bab..b581c6af14cc74dcf5b0504b59431e80e0b4c710 100644 --- a/src/src/eigenpsf/Constants.java +++ b/src/src/eigenpsf/Constants.java @@ -5,7 +5,7 @@ public class Constants { static final public String title = "(c) CNRS and BIG EPFL"; static final public String name = "Eigen PSF"; static final public String version = "0.3"; - static final public String url = "http://bigwww.epfl.ch/"; + static final public String url = "https://gitlab.irit.fr/mambo/eigenpsf-extractor"; static final public String copyright = "(c) CNRS and BIG EPFL"; } diff --git a/src/src/eigenpsf/SettingsDialog.java b/src/src/eigenpsf/SettingsDialog.java index e11e0587635fb2d7710012ef3b2db8872459b9d9..a6d124fdd76b9bf3e1cebefd6b90ba7ca313f082 100644 --- a/src/src/eigenpsf/SettingsDialog.java +++ b/src/src/eigenpsf/SettingsDialog.java @@ -49,6 +49,8 @@ public class SettingsDialog extends JDialog implements ActionListener, KeyListen private SpinnerRangeInteger spnPSFZ = new SpinnerRangeInteger(Params.psf_visible_width[2], 1, 9999, 2); private JRadioButton bn2D = new JRadioButton("2D", true); private JRadioButton bn3D = new JRadioButton("3D"); + private SpinnerInfoRangeDouble spnQuantile = new SpinnerInfoRangeDouble(Params.quantile, 0.01, 1000, 0.1, "Threshold to discard bad beads from the quality score (see related column in the result table).", "http://bigwww.epfl.ch/"); + private JButton bnGetROI = new JButton("Get ROI"); private JTabbedPane tab = new JTabbedPane(); @@ -138,23 +140,18 @@ public class SettingsDialog extends JDialog implements ActionListener, KeyListen i++; pn.place(i, 0, 4, 1, new JSeparator()); i++; - pn.place(i, 0, 4, 1, "<html><b>Modality</b></html>"); - pn.place(i, 1, cmbModality); - pn.place(i, 2, bn2D); - pn.place(i, 3, bn3D); + pn.place(i, 0, 4, 1, "<html><b>2D/3D</b></html>"); + //pn.place(i, 1, cmbModality); + pn.place(i, 1, bn2D); + pn.place(i, 2, bn3D); i++; - pn.place(i, 0, "PSF Support (XY)"); + pn.place(i, 0, "PSF Support XY (px)"); pn.place(i, 1, spnPSFXY); - pn.place(i, 2, "px"); - pn.place(i, 3, bnGetROI); + pn.place(i, 2, bnGetROI); i++; - pn.place(i, 0, "PSF Support (Z)"); + pn.place(i, 0, "PSF Support Z (nb slices)"); pn.place(i, 1, spnPSFZ); - pn.place(i, 2, 2, 1, "number of slices"); - i++; - pn.place(i, 0, "Eigen Components"); - pn.place(i, 1, spnNbEigen); - pn.place(i, 2, spnNbEigen.info); + i++; pn.place(i, 0, 4, 1, new JSeparator()); @@ -163,12 +160,26 @@ public class SettingsDialog extends JDialog implements ActionListener, KeyListen i++; pn.place(i, 0, 4, 1, new JSeparator()); i++; - pn.place(i, 0, "<html><b>Detection Threshold</b></html>"); + pn.place(i, 0, "Detection Threshold"); //pn.place(i, 1, 3, 1, cmbDetection); //i++; //pn.place(i, 1, "Threshold"); pn.place(i, 1, spnThreshold); pn.place(i, 2, spnThreshold.info); + i++; + pn.place(i, 0, 4, 1, new JSeparator()); + i++; + pn.place(i, 0, 4, 1, "<html> <b> Compute EigenPSF </b> </html>"); + i++; + pn.place(i, 0, 4, 1, new JSeparator()); + i++; + pn.place(i, 0, "Eigen Components"); + pn.place(i, 1, spnNbEigen); + pn.place(i, 2, spnNbEigen.info); + i++; + pn.place(i, 0,"Quality threshold"); + pn.place(i, 1,spnQuantile); + pn.place(i, 2,spnQuantile.info); //i++; //pn.place(i, 0, "<html><b>Registration</b></html>"); @@ -250,6 +261,7 @@ public class SettingsDialog extends JDialog implements ActionListener, KeyListen Params.thresholdDetection = spnThreshold.get(); Params.NeigenElements = spnNbEigen.get(); Params.dim = bn2D.isSelected() ? 2 : 3; + Params.quantile = spnQuantile.get(); } catch (Exception ex) { } } diff --git a/src/src/eigenpsf/processing/Processing.java b/src/src/eigenpsf/processing/Processing.java index c4b416ef94c306375109ed0767c79f83af7085f1..7c8afb80559c0a52855fecbc6807ad61e1f2b05c 100644 --- a/src/src/eigenpsf/processing/Processing.java +++ b/src/src/eigenpsf/processing/Processing.java @@ -117,6 +117,7 @@ public class Processing { // HyperMatrix tmp2 = large_patch.getPatch(center,Params.psf_visible_width); //tmp2.display("Before register patch",null); shift = reg_meth.process(large_patch); // Register patch + //System.out.printf("%f | %f | %f \n", shift[0],shift[1],shift[2]); // -- Update patch position double xx = patch.xp + shift[0]; double yy = patch.yp + shift[1]; @@ -124,28 +125,28 @@ public class Processing { patch.xp = (int) Math.round(xx); patch.yp = (int) Math.round(yy); patch.zp = (int) Math.round(zz); - patch.x = patch.xp - xx; - patch.y = patch.yp - yy; - patch.z = patch.zp - zz; + patch.x = xx - patch.xp; + patch.y = yy - patch.yp; + patch.z = zz - patch.zp; // -- Extract and store patch - int[] shift_fl = { (int) Math.round(shift[0]) + center[0], - (int) Math.round(shift[1]) + center[1], (int) Math.round(shift[2]) + center[2] }; + int[] shift_fl = { center[0] + (int) Math.round(shift[0]), + center[1] + (int) Math.round(shift[1]) , center[2] + (int) Math.round(shift[2]) }; patch.data = large_patch.getPatch(shift_fl, Params.psf_visible_width); //patch.data.display("After register patch",null); // -- Preprocess patch for SVD //project.patchesForSvd.add(large_patch.imtranslate(patch.x, patch.y, patch.z) // .getPatch(shift_fl, Params.psf_visible_width).normalize()); - patch.data_register = large_patch.imtranslate(patch.x, patch.y, patch.z).getPatch(shift_fl, Params.psf_visible_width).normalize(); + patch.data_register = large_patch.imtranslate(-patch.x, -patch.y,- patch.z).getPatch(shift_fl, Params.psf_visible_width).normalize(); //project.patchesForSvd.get(project.patchesForSvd.size()-1).display("After translation patch",null); } } } // Prune bad beads + project.isPreprocessed = true; pruneBeads(project); Log.progress("End Preprocess patches", 100); - project.isPreprocessed = true; } public static void pruneBeads(Project project) { diff --git a/src/src/eigenpsf/project/MainDialog.java b/src/src/eigenpsf/project/MainDialog.java index ea4f79349103d78500ca67eedf8795a47773260c..578b1bcff1ea022386cc30bbf9e2f61bf3a682bb 100644 --- a/src/src/eigenpsf/project/MainDialog.java +++ b/src/src/eigenpsf/project/MainDialog.java @@ -7,7 +7,10 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; +import java.io.BufferedWriter; import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; import javax.swing.BorderFactory; @@ -23,12 +26,19 @@ import eigenpsf.Constants; import eigenpsf.Log; import eigenpsf.Params; import eigenpsf.SettingsDialog; +import eigenpsf.data.HyperMatrix; import eigenpsf.filemanager.IO; import eigenpsf.gui.WalkBar; import eigenpsf.lib.Loader; import eigenpsf.processing.ProcessingPanel; +import eigenpsf.stack.Patch; import eigenpsf.stack.ZStack; +import eigenpsf.stack.Patches; +import ij.IJ; +import ij.ImagePlus; import ij.gui.GUI; +import ij.process.Blitter; +import ij.process.ImageProcessor; public class MainDialog extends JDialog implements ActionListener, WindowListener { @@ -92,7 +102,7 @@ public class MainDialog extends JDialog implements ActionListener, WindowListene @Override public void actionPerformed(ActionEvent e) { - if (e.getSource() == toolbar.bnReset) { + /*if (e.getSource() == toolbar.bnReset) { int ret = JOptionPane.showConfirmDialog(null, "Do you want to clear all the project?", "Warning", JOptionPane.YES_NO_OPTION); if (ret == JOptionPane.YES_OPTION) { project.reset(); @@ -101,10 +111,11 @@ public class MainDialog extends JDialog implements ActionListener, WindowListene Log.clear(); } } - else if (e.getSource() == toolbar.bnSetting) { + else */ + if (e.getSource() == toolbar.bnSetting) { settingsDialog.setVisible(true); } - else if (e.getSource() == toolbar.bnOpen) { + /*else if (e.getSource() == toolbar.bnOpen) { project.path = IO.browseOpenProject(project.path); String filename = project.path + File.separator + "listfiles.csv"; File file = new File(filename); @@ -116,12 +127,109 @@ public class MainDialog extends JDialog implements ActionListener, WindowListene else { Log.write(project.path + " is empty"); } - } + }*/ else if (e.getSource() == toolbar.bnSave) { project.path = IO.browseSaveProject(project.path); - if (project.path != null) + if (project.path != null) { project.save(project.path); - + pnProcessing.table.update(project); + + File file = new File(project.path + File.separator + "patchesTable.csv"); + try { + System.out.printf("Coucou"); + BufferedWriter buffer = new BufferedWriter(new FileWriter(file)); + int nrows = pnProcessing.table.getRowCount(); + int ncols = pnProcessing.table.getColumnCount(); + System.out.printf("Coucou-1"); + String row = ""; + //for (int c = 0; c < ncols; c++) + // row += pnProcessing.table.columns.get(c).getHeader() + (c == ncols - 1 ? "" : "\t "); + //buffer.write(row + "\n"); + // Add header manually ... + buffer.write("Image name \t ID \t X \t Y \t Z \t Quality \t Dist \t Max \t Valid \n"); + + for (int r = 0; r < nrows; r++) { + row = ""; + for (int c = 0; c < ncols; c++) { + Object O = pnProcessing.table.getModel().getValueAt(r, c); + row += O + (c == ncols - 1 ? "" : "\t "); + } + buffer.write(row + "\n"); + } + buffer.close(); + } + catch (Exception ex) { + System.out.println(ex); + } + + int[] sz; + if (Params.dim == 2) { + sz = new int[] { Params.psf_visible_width[0], Params.psf_visible_width[1],1 }; + } + else { + sz = new int[] { Params.psf_visible_width[0], Params.psf_visible_width[1], Params.psf_visible_width[2] }; + } + Patches sel = project.getAllPatchesSortedByGlobId(); + ImagePlus imp_raw = IJ.createHyperStack("Raw Patches", sz[0], sz[1], 1, sz[2], sel.size(), 32); + ImagePlus imp_process = IJ.createHyperStack("Processed Patches", sz[0], sz[1], 1, sz[2], sel.size(), 32); + ImagePlus imp_back = IJ.createHyperStack("Background Patches", sz[0], sz[1], 1, sz[2], sel.size(), 32); + ImagePlus imp_proj = IJ.createHyperStack("Projected Patches", sz[0], sz[1], 1, sz[2], sel.size(), 32); + int i = 1; + for (Patch patch : sel) { + int pos[]; + if (Params.dim == 2) { + pos = new int[] { patch.xp, patch.yp, 0}; + } + else { + pos = new int[] { patch.xp, patch.yp, patch.zp }; + } + HyperMatrix im = patch.stack.getHyperMatrix(); + ImagePlus p_raw = HyperMatrix.HyperMatrix2ImagePlus(im.getPatch(pos, sz)); + ImagePlus p_back = HyperMatrix.HyperMatrix2ImagePlus(im.getPatch(pos, sz).sub(patch.data)); + ImagePlus p_proj = HyperMatrix.HyperMatrix2ImagePlus(project.eigen.projPatch(patch)); + ImagePlus p_process; + if (project.isPreprocessed) + p_process = HyperMatrix.HyperMatrix2ImagePlus(patch.data_register); + else + p_process = HyperMatrix.HyperMatrix2ImagePlus(patch.data); + if (p_raw != null) { + for (int z = 1; z <= Math.min(p_raw.getNSlices(), sz[2]); z++) { + // Raw + ImageProcessor ip = p_raw.getStack().getProcessor(z); + imp_raw.setPositionWithoutUpdate(1, z, i); + ImageProcessor op = imp_raw.getProcessor(); + op.copyBits(ip, 0, 0, Blitter.COPY); + // Processed + ip = p_process.getStack().getProcessor(z); + imp_process.setPositionWithoutUpdate(1, z, i); + op = imp_process.getProcessor(); + op.copyBits(ip, 0, 0, Blitter.COPY); + // Back + ip = p_back.getStack().getProcessor(z); + imp_back.setPositionWithoutUpdate(1, z, i); + op = imp_back.getProcessor(); + op.copyBits(ip, 0, 0, Blitter.COPY); + // Proj + ip = p_proj.getStack().getProcessor(z); + imp_proj.setPositionWithoutUpdate(1, z, i); + op = imp_proj.getProcessor(); + op.copyBits(ip, 0, 0, Blitter.COPY); + } + } + i++; + } + ij.IJ.save(imp_raw,project.path + File.separator + "RawPatches.tif"); + ij.IJ.save(imp_process,project.path + File.separator + "ProcessedPatches.tif"); + ij.IJ.save(imp_back,project.path + File.separator + "BackgroundPatches.tif"); + ij.IJ.save(imp_proj,project.path + File.separator + "ProjectedPatches.tif"); + + + ImagePlus eig = HyperMatrix.HyperMatrix2ImagePlus(project.eigen.eigenElements); + ij.IJ.save(eig,project.path + File.separator + "EigenPSF.tif"); + + + + } } else if (e.getSource() == bnAdd) { diff --git a/src/src/eigenpsf/project/Toolbar.java b/src/src/eigenpsf/project/Toolbar.java index 27355cae8a949501962f4d20a7aec415550d402d..95b990a6f54a7462bca7d7acc28d89ac2834dc96 100644 --- a/src/src/eigenpsf/project/Toolbar.java +++ b/src/src/eigenpsf/project/Toolbar.java @@ -47,15 +47,15 @@ public class Toolbar extends JToolBar implements ActionListener { public Toolbar(MainDialog main) { this.setFloatable(false); JPanel tool1 = new JPanel(new GridLayout(1, 7, 0, 0)); - tool1.add(bnReset); - tool1.add(bnOpen); + //tool1.add(bnReset); + //tool1.add(bnOpen); tool1.add(bnSave); tool1.add(new JSeparator(SwingConstants.VERTICAL)); tool1.add(bnSetting); tool1.add(new JSeparator(SwingConstants.VERTICAL)); JPanel tool2 = new JPanel(new GridLayout(1, 4, 0, 0)); - tool2.add(bnGit); + //tool2.add(bnGit); tool2.add(bnHelp); tool2.add(bnAbout); setBorder(BorderFactory.createEtchedBorder()); @@ -65,13 +65,13 @@ public class Toolbar extends JToolBar implements ActionListener { add(new JLabel(""), BorderLayout.CENTER); add(tool2, BorderLayout.EAST); - bnReset.addActionListener(main); - bnOpen.addActionListener(main); + //bnReset.addActionListener(main); + //bnOpen.addActionListener(main); bnSave.addActionListener(main); bnSetting.addActionListener(main); bnAbout.addActionListener(this); bnHelp.addActionListener(this); - bnGit.addActionListener(this); + //bnGit.addActionListener(this); } @Override @@ -82,8 +82,8 @@ public class Toolbar extends JToolBar implements ActionListener { if (e.getSource() == bnHelp) WebBrowser.open(Constants.url); - if (e.getSource() == bnGit) - WebBrowser.open(Constants.url); + //if (e.getSource() == bnGit) + // WebBrowser.open(Constants.url); } public void showAbout() { diff --git a/src/src/eigenpsf/stack/Patch.java b/src/src/eigenpsf/stack/Patch.java index 52e4a607e292a5423a848e06fabf49522b4702ea..d7140f0886dea3c9c14a7c43dc85cf528dfc7d8c 100644 --- a/src/src/eigenpsf/stack/Patch.java +++ b/src/src/eigenpsf/stack/Patch.java @@ -1,7 +1,10 @@ package eigenpsf.stack; import java.awt.Point; + +import eigenpsf.Params; import eigenpsf.data.HyperMatrix; +import ij.ImagePlus; public class Patch { @@ -70,4 +73,5 @@ public class Patch { public String toString() { return "(id: " + id + " x:" + xp + " y:" + yp + ")"; } + } diff --git a/todo.txt b/todo.txt index 5291133b67d8cbbf7299a24165ac5c6ae0a532e9..da3223d26d9a25fdc30db8cf75b336bc3f08c069 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,3 @@ -* unvalid -> invalid (dans la table) * Option de sauvegarde de la table comme fichier json, xslx,.. *