]> Creatis software - STMS.git/commitdiff
First Relase on creatis's public git!
authorgrenier <grenier@im-tg-mure-srv.creatis.insa-lyon.fr>
Fri, 7 Jul 2017 15:48:35 +0000 (17:48 +0200)
committergrenier <grenier@im-tg-mure-srv.creatis.insa-lyon.fr>
Fri, 7 Jul 2017 15:48:35 +0000 (17:48 +0200)
Comments, examples and readme will come!

Parsers are not uptodate with new arguments  outputImageExtension

116 files changed:
CMakeLists.txt [new file with mode: 0755]
Data/Images/G1/Mask.nii.gz [new file with mode: 0644]
Data/Images/G1/ROI_1.nii.gz [new file with mode: 0644]
Data/Images/G1/ROI_2.nii.gz [new file with mode: 0644]
Data/Images/G1/ROI_3.nii.gz [new file with mode: 0644]
Data/Images/G1/ROI_4.nii.gz [new file with mode: 0644]
Data/Images/G1/ROI_5.nii.gz [new file with mode: 0644]
Data/Images/G1/ROI_6.nii.gz [new file with mode: 0644]
Data/Images/G1/ROI_7.nii.gz [new file with mode: 0644]
Data/Images/G1/ROI_8.nii.gz [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_1.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_10.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_11.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_12.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_13.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_14.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_15.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_16.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_17.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_18.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_19.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_2.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_20.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_21.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_22.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_23.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_24.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_25.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_26.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_27.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_28.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_29.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_3.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_30.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_31.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_32.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_33.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_34.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_35.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_36.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_37.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_38.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_39.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_4.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_40.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_41.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_42.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_43.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_44.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_45.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_46.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_47.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_48.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_49.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_5.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_50.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_51.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_52.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_53.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_54.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_55.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_6.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_7.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_8.nii [new file with mode: 0644]
Data/Images/P1_NiiPerf/Perf_9.nii [new file with mode: 0644]
Data/Images/Simu/Mask.nii [new file with mode: 0644]
Data/Images/Simu/Mask.nii.gz [new file with mode: 0644]
Data/Images/Simu/Simu1.nii [new file with mode: 0644]
Data/Images/Simu/Simu1.nii.gz [new file with mode: 0644]
Data/Images/Simu/Simu2.nii [new file with mode: 0644]
Data/Images/Simu/Simu2.nii.gz [new file with mode: 0644]
Data/Images/Simu/Simu3.nii [new file with mode: 0644]
Data/Images/Simu/Simu3.nii.gz [new file with mode: 0644]
Data/Images/Simu/Simu4.nii [new file with mode: 0644]
Data/Images/Simu/Simu4.nii.gz [new file with mode: 0644]
Data/Images/Simu/Simu5.nii [new file with mode: 0644]
Data/Images/Simu/Simu5.nii.gz [new file with mode: 0644]
Data/Images/Simu/Simu6.nii [new file with mode: 0644]
Data/Images/Simu/Simu6.nii.gz [new file with mode: 0644]
Data/Images/Simu/Simu7.nii [new file with mode: 0644]
Data/Images/Simu/Simu7.nii.gz [new file with mode: 0644]
Data/Images/Simu/Simu8.nii [new file with mode: 0644]
Data/Images/Simu/Simu8.nii.gz [new file with mode: 0644]
Data/Parsers/G1_Parser.xml [new file with mode: 0644]
Data/Parsers/P1_NiiPerf.xml [new file with mode: 0644]
Data/Parsers/Simu_Parser.xml [new file with mode: 0644]
Data/Parsers/Simu_Parser_RP.xml [new file with mode: 0644]
Lib/CMakeLists.txt [new file with mode: 0755]
Lib/PrePostProcessing/CMakeLists.txt [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis.h [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis.hxx [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis_Spine.h [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis_Spine.hxx [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet.h [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet.txx [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet_Spine.h [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet_Spine.txx [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence.h [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence.txx [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence_Spine.h [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence_Spine.txx [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_XMLFileParser.h [new file with mode: 0755]
Lib/PrePostProcessing/itkSTMS_XMLFileParser.hxx [new file with mode: 0755]
Lib/SpatioTemporalMeanShift/CMakeLists.txt [new file with mode: 0755]
Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS.h [new file with mode: 0755]
Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS.txx [new file with mode: 0755]
Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS_Spine.h [new file with mode: 0755]
Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS_Spine.txx [new file with mode: 0755]
Licence_CeCILL-C_V1-en.txt [new file with mode: 0644]
Licence_CeCILL_V2.1-en.txt [new file with mode: 0644]
Src/CMakeLists.txt [new file with mode: 0755]
Src/STMS_GrayLevelFiltering.cxx [new file with mode: 0755]
Src/STMS_GrayLevelFiltering_Spine.cxx [new file with mode: 0755]
Src/test_ArgumentsAnalysis.cxx [new file with mode: 0755]
Src/test_ArgumentsAnalysis_Spine.cxx [new file with mode: 0755]
Src/test_parseXML.cxx [new file with mode: 0755]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..8035012
--- /dev/null
@@ -0,0 +1,74 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+#MARK_AS_ADVANCED( FORCE CMAKE_BACKWARDS_COMPATIBILITY )
+
+# for CMake 2.6 corrected behaviour (see "cmake --help-policy CMP0003")
+IF(COMMAND cmake_policy AND ${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 4)
+  CMAKE_POLICY(SET CMP0003 NEW)
+  CMAKE_POLICY(SET CMP0005 NEW)
+  CMAKE_POLICY(SET CMP0011 NEW) 
+ENDIF(COMMAND cmake_policy AND ${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 4)
+
+CMAKE_POLICY(SET CMP0048 NEW)
+
+#foreach(p
+#    CMP0025 # CMake 3.0
+#    CMP0042 # CMake 3.0
+#    CMP0054 # CMake 3.1
+#    CMP0056 # CMake 3.2
+#    CMP0058 # CMake 3.3
+#    )
+#  if(POLICY ${p})
+#    cmake_policy(SET ${p} NEW)
+#  endif()
+#endforeach()
+
+# The project version
+SET(PROJECT_VERSION_MAJOR 1)
+SET(PROJECT_VERSION_MINOR 1)
+SET(PROJECT_VERSION_PATCH 0)
+
+SET(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
+
+SET(STMS_VERSION_MAJOR 1)
+SET(STMS_VERSION_MINOR 1)
+SET(STMS_VERSION_PATCH 0)
+
+SET(STMS_VERSION "${STMS_VERSION_MAJOR}.${STMS_VERSION_MINOR}.${STMS_VERSION_PATCH}")
+SET(STMS_VERSION_DATE "25/03/2015")
+
+
+
+#project(STMS)
+project(STMS
+       VERSION
+       LANGUAGES C CXX)
+
+# Mode Release
+OPTION(CMAKE_BUILD_TYPE "Debug Release" Release)
+
+# Mode debug
+#OPTION(CMAKE_BUILD_TYPE "Debug Release" Debug)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -Wall -fopenmp -Ofast" CACHE STRING " Flags for compile" FORCE)
+
+FIND_PACKAGE(ITK REQUIRED)
+INCLUDE(${ITK_USE_FILE})
+
+IF("${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}")
+   MESSAGE(FATAL_ERROR "Building in the source tree is not allowed !! Quit; remove the file 'CMakeCache.txt' and the folder 'CMakeFiles' and build outside the sources")
+ENDIF("${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}")
+
+SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+OPTION(BUILD_SHARED_LIBRARIES "OFF to obtain Static execatables" OFF)
+#SET(CMAKE_EXE_LINKER_FLAGS "-static")
+
+
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/Lib/PrePostProcessing)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/Lib/SpatioTemporalMeanShift)
+
+add_subdirectory(Lib)
+add_subdirectory(Src)
+
+
+
diff --git a/Data/Images/G1/Mask.nii.gz b/Data/Images/G1/Mask.nii.gz
new file mode 100644 (file)
index 0000000..1e800dc
Binary files /dev/null and b/Data/Images/G1/Mask.nii.gz differ
diff --git a/Data/Images/G1/ROI_1.nii.gz b/Data/Images/G1/ROI_1.nii.gz
new file mode 100644 (file)
index 0000000..68c8bce
Binary files /dev/null and b/Data/Images/G1/ROI_1.nii.gz differ
diff --git a/Data/Images/G1/ROI_2.nii.gz b/Data/Images/G1/ROI_2.nii.gz
new file mode 100644 (file)
index 0000000..99abf74
Binary files /dev/null and b/Data/Images/G1/ROI_2.nii.gz differ
diff --git a/Data/Images/G1/ROI_3.nii.gz b/Data/Images/G1/ROI_3.nii.gz
new file mode 100644 (file)
index 0000000..4e70034
Binary files /dev/null and b/Data/Images/G1/ROI_3.nii.gz differ
diff --git a/Data/Images/G1/ROI_4.nii.gz b/Data/Images/G1/ROI_4.nii.gz
new file mode 100644 (file)
index 0000000..afbe690
Binary files /dev/null and b/Data/Images/G1/ROI_4.nii.gz differ
diff --git a/Data/Images/G1/ROI_5.nii.gz b/Data/Images/G1/ROI_5.nii.gz
new file mode 100644 (file)
index 0000000..5ca703d
Binary files /dev/null and b/Data/Images/G1/ROI_5.nii.gz differ
diff --git a/Data/Images/G1/ROI_6.nii.gz b/Data/Images/G1/ROI_6.nii.gz
new file mode 100644 (file)
index 0000000..4972e39
Binary files /dev/null and b/Data/Images/G1/ROI_6.nii.gz differ
diff --git a/Data/Images/G1/ROI_7.nii.gz b/Data/Images/G1/ROI_7.nii.gz
new file mode 100644 (file)
index 0000000..ae05e92
Binary files /dev/null and b/Data/Images/G1/ROI_7.nii.gz differ
diff --git a/Data/Images/G1/ROI_8.nii.gz b/Data/Images/G1/ROI_8.nii.gz
new file mode 100644 (file)
index 0000000..02aa41a
Binary files /dev/null and b/Data/Images/G1/ROI_8.nii.gz differ
diff --git a/Data/Images/P1_NiiPerf/Perf_1.nii b/Data/Images/P1_NiiPerf/Perf_1.nii
new file mode 100644 (file)
index 0000000..cf1607f
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_1.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_10.nii b/Data/Images/P1_NiiPerf/Perf_10.nii
new file mode 100644 (file)
index 0000000..8b918c1
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_10.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_11.nii b/Data/Images/P1_NiiPerf/Perf_11.nii
new file mode 100644 (file)
index 0000000..84343d0
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_11.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_12.nii b/Data/Images/P1_NiiPerf/Perf_12.nii
new file mode 100644 (file)
index 0000000..16b76de
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_12.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_13.nii b/Data/Images/P1_NiiPerf/Perf_13.nii
new file mode 100644 (file)
index 0000000..872695a
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_13.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_14.nii b/Data/Images/P1_NiiPerf/Perf_14.nii
new file mode 100644 (file)
index 0000000..58d483a
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_14.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_15.nii b/Data/Images/P1_NiiPerf/Perf_15.nii
new file mode 100644 (file)
index 0000000..14d82fb
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_15.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_16.nii b/Data/Images/P1_NiiPerf/Perf_16.nii
new file mode 100644 (file)
index 0000000..b847c0e
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_16.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_17.nii b/Data/Images/P1_NiiPerf/Perf_17.nii
new file mode 100644 (file)
index 0000000..a3787f5
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_17.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_18.nii b/Data/Images/P1_NiiPerf/Perf_18.nii
new file mode 100644 (file)
index 0000000..782434a
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_18.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_19.nii b/Data/Images/P1_NiiPerf/Perf_19.nii
new file mode 100644 (file)
index 0000000..e3bc304
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_19.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_2.nii b/Data/Images/P1_NiiPerf/Perf_2.nii
new file mode 100644 (file)
index 0000000..80f3da0
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_2.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_20.nii b/Data/Images/P1_NiiPerf/Perf_20.nii
new file mode 100644 (file)
index 0000000..944ed2d
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_20.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_21.nii b/Data/Images/P1_NiiPerf/Perf_21.nii
new file mode 100644 (file)
index 0000000..9d5b4a5
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_21.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_22.nii b/Data/Images/P1_NiiPerf/Perf_22.nii
new file mode 100644 (file)
index 0000000..c87b2ff
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_22.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_23.nii b/Data/Images/P1_NiiPerf/Perf_23.nii
new file mode 100644 (file)
index 0000000..40ca9b6
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_23.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_24.nii b/Data/Images/P1_NiiPerf/Perf_24.nii
new file mode 100644 (file)
index 0000000..74dbb98
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_24.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_25.nii b/Data/Images/P1_NiiPerf/Perf_25.nii
new file mode 100644 (file)
index 0000000..3fa32d4
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_25.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_26.nii b/Data/Images/P1_NiiPerf/Perf_26.nii
new file mode 100644 (file)
index 0000000..1d7df1d
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_26.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_27.nii b/Data/Images/P1_NiiPerf/Perf_27.nii
new file mode 100644 (file)
index 0000000..6800198
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_27.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_28.nii b/Data/Images/P1_NiiPerf/Perf_28.nii
new file mode 100644 (file)
index 0000000..f3da9a6
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_28.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_29.nii b/Data/Images/P1_NiiPerf/Perf_29.nii
new file mode 100644 (file)
index 0000000..2593bef
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_29.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_3.nii b/Data/Images/P1_NiiPerf/Perf_3.nii
new file mode 100644 (file)
index 0000000..8a1d687
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_3.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_30.nii b/Data/Images/P1_NiiPerf/Perf_30.nii
new file mode 100644 (file)
index 0000000..f4b243d
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_30.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_31.nii b/Data/Images/P1_NiiPerf/Perf_31.nii
new file mode 100644 (file)
index 0000000..bc7a08c
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_31.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_32.nii b/Data/Images/P1_NiiPerf/Perf_32.nii
new file mode 100644 (file)
index 0000000..84b005a
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_32.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_33.nii b/Data/Images/P1_NiiPerf/Perf_33.nii
new file mode 100644 (file)
index 0000000..ceda7f0
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_33.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_34.nii b/Data/Images/P1_NiiPerf/Perf_34.nii
new file mode 100644 (file)
index 0000000..9dd4e46
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_34.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_35.nii b/Data/Images/P1_NiiPerf/Perf_35.nii
new file mode 100644 (file)
index 0000000..399fd13
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_35.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_36.nii b/Data/Images/P1_NiiPerf/Perf_36.nii
new file mode 100644 (file)
index 0000000..fe8d7f9
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_36.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_37.nii b/Data/Images/P1_NiiPerf/Perf_37.nii
new file mode 100644 (file)
index 0000000..ac3cf4e
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_37.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_38.nii b/Data/Images/P1_NiiPerf/Perf_38.nii
new file mode 100644 (file)
index 0000000..09d1e88
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_38.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_39.nii b/Data/Images/P1_NiiPerf/Perf_39.nii
new file mode 100644 (file)
index 0000000..5e5bb7a
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_39.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_4.nii b/Data/Images/P1_NiiPerf/Perf_4.nii
new file mode 100644 (file)
index 0000000..e72a284
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_4.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_40.nii b/Data/Images/P1_NiiPerf/Perf_40.nii
new file mode 100644 (file)
index 0000000..24bd7e6
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_40.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_41.nii b/Data/Images/P1_NiiPerf/Perf_41.nii
new file mode 100644 (file)
index 0000000..a6ddf53
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_41.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_42.nii b/Data/Images/P1_NiiPerf/Perf_42.nii
new file mode 100644 (file)
index 0000000..6eaff03
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_42.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_43.nii b/Data/Images/P1_NiiPerf/Perf_43.nii
new file mode 100644 (file)
index 0000000..2976e7a
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_43.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_44.nii b/Data/Images/P1_NiiPerf/Perf_44.nii
new file mode 100644 (file)
index 0000000..42dfdbf
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_44.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_45.nii b/Data/Images/P1_NiiPerf/Perf_45.nii
new file mode 100644 (file)
index 0000000..3ff5be9
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_45.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_46.nii b/Data/Images/P1_NiiPerf/Perf_46.nii
new file mode 100644 (file)
index 0000000..141c9a9
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_46.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_47.nii b/Data/Images/P1_NiiPerf/Perf_47.nii
new file mode 100644 (file)
index 0000000..98d4976
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_47.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_48.nii b/Data/Images/P1_NiiPerf/Perf_48.nii
new file mode 100644 (file)
index 0000000..6705b2e
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_48.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_49.nii b/Data/Images/P1_NiiPerf/Perf_49.nii
new file mode 100644 (file)
index 0000000..278ca55
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_49.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_5.nii b/Data/Images/P1_NiiPerf/Perf_5.nii
new file mode 100644 (file)
index 0000000..4886cdd
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_5.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_50.nii b/Data/Images/P1_NiiPerf/Perf_50.nii
new file mode 100644 (file)
index 0000000..f3c3d15
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_50.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_51.nii b/Data/Images/P1_NiiPerf/Perf_51.nii
new file mode 100644 (file)
index 0000000..7d185bf
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_51.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_52.nii b/Data/Images/P1_NiiPerf/Perf_52.nii
new file mode 100644 (file)
index 0000000..cfdda9e
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_52.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_53.nii b/Data/Images/P1_NiiPerf/Perf_53.nii
new file mode 100644 (file)
index 0000000..b8cc8e5
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_53.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_54.nii b/Data/Images/P1_NiiPerf/Perf_54.nii
new file mode 100644 (file)
index 0000000..15c6ee8
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_54.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_55.nii b/Data/Images/P1_NiiPerf/Perf_55.nii
new file mode 100644 (file)
index 0000000..9233b18
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_55.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_6.nii b/Data/Images/P1_NiiPerf/Perf_6.nii
new file mode 100644 (file)
index 0000000..bf2bd31
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_6.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_7.nii b/Data/Images/P1_NiiPerf/Perf_7.nii
new file mode 100644 (file)
index 0000000..99240a4
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_7.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_8.nii b/Data/Images/P1_NiiPerf/Perf_8.nii
new file mode 100644 (file)
index 0000000..ac316f7
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_8.nii differ
diff --git a/Data/Images/P1_NiiPerf/Perf_9.nii b/Data/Images/P1_NiiPerf/Perf_9.nii
new file mode 100644 (file)
index 0000000..cb5820c
Binary files /dev/null and b/Data/Images/P1_NiiPerf/Perf_9.nii differ
diff --git a/Data/Images/Simu/Mask.nii b/Data/Images/Simu/Mask.nii
new file mode 100644 (file)
index 0000000..d15f366
Binary files /dev/null and b/Data/Images/Simu/Mask.nii differ
diff --git a/Data/Images/Simu/Mask.nii.gz b/Data/Images/Simu/Mask.nii.gz
new file mode 100644 (file)
index 0000000..1a77548
Binary files /dev/null and b/Data/Images/Simu/Mask.nii.gz differ
diff --git a/Data/Images/Simu/Simu1.nii b/Data/Images/Simu/Simu1.nii
new file mode 100644 (file)
index 0000000..17bc445
Binary files /dev/null and b/Data/Images/Simu/Simu1.nii differ
diff --git a/Data/Images/Simu/Simu1.nii.gz b/Data/Images/Simu/Simu1.nii.gz
new file mode 100644 (file)
index 0000000..09c01b0
Binary files /dev/null and b/Data/Images/Simu/Simu1.nii.gz differ
diff --git a/Data/Images/Simu/Simu2.nii b/Data/Images/Simu/Simu2.nii
new file mode 100644 (file)
index 0000000..b3a85d8
Binary files /dev/null and b/Data/Images/Simu/Simu2.nii differ
diff --git a/Data/Images/Simu/Simu2.nii.gz b/Data/Images/Simu/Simu2.nii.gz
new file mode 100644 (file)
index 0000000..0c91b8b
Binary files /dev/null and b/Data/Images/Simu/Simu2.nii.gz differ
diff --git a/Data/Images/Simu/Simu3.nii b/Data/Images/Simu/Simu3.nii
new file mode 100644 (file)
index 0000000..11221bb
Binary files /dev/null and b/Data/Images/Simu/Simu3.nii differ
diff --git a/Data/Images/Simu/Simu3.nii.gz b/Data/Images/Simu/Simu3.nii.gz
new file mode 100644 (file)
index 0000000..5ef5fdd
Binary files /dev/null and b/Data/Images/Simu/Simu3.nii.gz differ
diff --git a/Data/Images/Simu/Simu4.nii b/Data/Images/Simu/Simu4.nii
new file mode 100644 (file)
index 0000000..7b2e555
Binary files /dev/null and b/Data/Images/Simu/Simu4.nii differ
diff --git a/Data/Images/Simu/Simu4.nii.gz b/Data/Images/Simu/Simu4.nii.gz
new file mode 100644 (file)
index 0000000..d457ba8
Binary files /dev/null and b/Data/Images/Simu/Simu4.nii.gz differ
diff --git a/Data/Images/Simu/Simu5.nii b/Data/Images/Simu/Simu5.nii
new file mode 100644 (file)
index 0000000..1681377
Binary files /dev/null and b/Data/Images/Simu/Simu5.nii differ
diff --git a/Data/Images/Simu/Simu5.nii.gz b/Data/Images/Simu/Simu5.nii.gz
new file mode 100644 (file)
index 0000000..3eacd8c
Binary files /dev/null and b/Data/Images/Simu/Simu5.nii.gz differ
diff --git a/Data/Images/Simu/Simu6.nii b/Data/Images/Simu/Simu6.nii
new file mode 100644 (file)
index 0000000..fd59f8a
Binary files /dev/null and b/Data/Images/Simu/Simu6.nii differ
diff --git a/Data/Images/Simu/Simu6.nii.gz b/Data/Images/Simu/Simu6.nii.gz
new file mode 100644 (file)
index 0000000..bc22430
Binary files /dev/null and b/Data/Images/Simu/Simu6.nii.gz differ
diff --git a/Data/Images/Simu/Simu7.nii b/Data/Images/Simu/Simu7.nii
new file mode 100644 (file)
index 0000000..cb6a3ce
Binary files /dev/null and b/Data/Images/Simu/Simu7.nii differ
diff --git a/Data/Images/Simu/Simu7.nii.gz b/Data/Images/Simu/Simu7.nii.gz
new file mode 100644 (file)
index 0000000..0382cb9
Binary files /dev/null and b/Data/Images/Simu/Simu7.nii.gz differ
diff --git a/Data/Images/Simu/Simu8.nii b/Data/Images/Simu/Simu8.nii
new file mode 100644 (file)
index 0000000..ab9ce7c
Binary files /dev/null and b/Data/Images/Simu/Simu8.nii differ
diff --git a/Data/Images/Simu/Simu8.nii.gz b/Data/Images/Simu/Simu8.nii.gz
new file mode 100644 (file)
index 0000000..09c01b0
Binary files /dev/null and b/Data/Images/Simu/Simu8.nii.gz differ
diff --git a/Data/Parsers/G1_Parser.xml b/Data/Parsers/G1_Parser.xml
new file mode 100644 (file)
index 0000000..b281562
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+       experimentPath     : Absolute path to the folder containing all the experiment data
+       imageExtension     : Extension of the image files. There is no default value, has to be specified.
+       commonRoot         : The beginning of the image file names has to be the same. The images should be noted "commonRoot"+"timePoint"+"imageExtension"
+
+       ### listInput ###
+       inputFolder        : Folder containing the input image sequence
+       numberOfTimePoints : Number of time points in the sequence. The time points should be comprised between 1 and numberOfTimePoints.
+       maskImage          : Specify a mask image if you want to process STMS only with the mask pixel values. It has to be stored in the "Mask" folder and to be a binary image (0/1). Set tu null if no mask.
+
+       ### listOutput ###
+       outputFolder        : Folder containing the output image sequence
+       commonRoot         : The beginning of the image file names has to be the same. The images will be saved as "commonRoot"+"timePoint"+"scaleParameters"+"imageExtension"
+-->
+
+<STMS_ProcessInfo
+       experimentPath="/run/media/mure/HDD/Recherche/These/CVS/Mure/Dev/Cpp/itkSTMS/Data/Images/"
+       imageExtension=".nii.gz" >
+<!--
+       <listInput
+               inputFolder="G1/"
+               commonRoot="ROI_"
+               maskImage="Mask"
+       />
+-->
+
+       <listInput
+               inputFolder="G1/"
+               commonRoot="ROI_"
+               maskImage="null"
+       />
+
+       <listOutput
+               outputFolder="G1_Outputs/"
+               commonRoot="G1_STMS_"
+       />
+</STMS_ProcessInfo>
diff --git a/Data/Parsers/P1_NiiPerf.xml b/Data/Parsers/P1_NiiPerf.xml
new file mode 100644 (file)
index 0000000..87d1bcc
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+       experimentPath     : Absolute path to the folder containing all the experiment data
+       imageExtension     : Extension of the image files. There is no default value, has to be specified.
+       commonRoot         : The beginning of the image file names has to be the same. The images should be noted "commonRoot"+"timePoint"+"imageExtension"
+
+       ### listInput ###
+       inputFolder        : Folder containing the input image sequence
+       maskImage          : Specify a mask image if you want to process STMS only with the mask pixel values. It has to be stored in the "Mask" folder and to be a binary image (0/1). Set tu null if no mask.
+
+       ### listOutput ###
+       outputFolder        : Folder containing the output image sequence
+       commonRoot         : The beginning of the image file names has to be the same. The images will be saved as "commonRoot"+"timePoint"+"scaleParameters"+"imageExtension"
+-->
+
+<STMS_ProcessInfo
+       experimentPath="/run/media/mure/HDD/Recherche/These/Repositories/Mure/Dev/Cpp/itkSTMS/Data/Images/"
+       imageExtension=".nii.gz" >
+
+       <listInput
+               inputFolder="P1_NiiPerf/"
+               commonRoot="Perf_"
+               maskImage="null"
+       />
+
+       <listOutput
+               outputFolder="P1_NiiPerf-out/"
+               commonRoot="P1-Perf_"
+       />
+</STMS_ProcessInfo>
diff --git a/Data/Parsers/Simu_Parser.xml b/Data/Parsers/Simu_Parser.xml
new file mode 100644 (file)
index 0000000..12ff779
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+       experimentPath     : Absolute path to the folder containing all the experiment data
+       imageExtension     : Extension of the image files. There is no default value, has to be specified.
+       commonRoot         : The beginning of the image file names has to be the same. The images should be noted "commonRoot"+"timePoint"+"imageExtension"
+
+       ### listInput ###
+       inputFolder        : Folder containing the input image sequence
+       numberOfTimePoints : Number of time points in the sequence. The time points should be comprised between 1 and numberOfTimePoints.
+       maskImage          : Specify a mask image if you want to process STMS only with the mask pixel values. It has to be stored in the "Mask" folder and to be a binary image (0/1). Set tu null if no mask.
+
+       ### listOutput ###
+       outputFolder        : Folder containing the output image sequence
+       commonRoot         : The beginning of the image file names has to be the same. The images will be saved as "commonRoot"+"timePoint"+"scaleParameters"+"imageExtension"
+-->
+
+<STMS_ProcessInfo
+       experimentPath="/run/media/mure/HDD/Recherche/These/Repositories/Mure/Dev/Cpp/itkSTMS/Data/Images/"
+       imageExtension=".nii.gz" >
+
+       <listInput
+               inputFolder="Simu/"
+               commonRoot="Simu"
+               maskImage="null"
+       />
+
+       <listOutput
+               outputFolder="Simu_Outputs/"
+               commonRoot="Simu_STMS_"
+       />
+</STMS_ProcessInfo>
diff --git a/Data/Parsers/Simu_Parser_RP.xml b/Data/Parsers/Simu_Parser_RP.xml
new file mode 100644 (file)
index 0000000..11a5117
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+       experimentPath     : Absolute path to the folder containing all the experiment data
+       imageExtension     : Extension of the image files. There is no default value, has to be specified.
+       commonRoot         : The beginning of the image file names has to be the same. The images should be noted "commonRoot"+"timePoint"+"imageExtension"
+
+       ### listInput ###
+       inputFolder        : Folder containing the input image sequence
+       numberOfTimePoints : Number of time points in the sequence. The time points should be comprised between 1 and numberOfTimePoints.
+       maskImage          : Specify a mask image if you want to process STMS only with the mask pixel values. It has to be stored in the "Mask" folder and to be a binary image (0/1). Set tu null if no mask.
+
+       ### listOutput ###
+       outputFolder        : Folder containing the output image sequence
+       commonRoot         : The beginning of the image file names has to be the same. The images will be saved as "commonRoot"+"timePoint"+"scaleParameters"+"imageExtension"
+-->
+
+<STMS_ProcessInfo
+       experimentPath="../../itkSTMS/Data/Images/"
+       imageExtension=".nii.gz" >
+
+       <listInput
+               inputFolder="Simu/"
+               commonRoot="Simu"
+               maskImage="null"
+       />
+
+       <listOutput
+               outputFolder="Simu_Outputs/"
+               commonRoot="Simu_STMS_"
+       />
+</STMS_ProcessInfo>
diff --git a/Lib/CMakeLists.txt b/Lib/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..addfa61
--- /dev/null
@@ -0,0 +1,2 @@
+SUBDIRS(SpatioTemporalMeanShift)
+SUBDIRS(PrePostProcessing)
diff --git a/Lib/PrePostProcessing/CMakeLists.txt b/Lib/PrePostProcessing/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..cc8c3db
--- /dev/null
@@ -0,0 +1,87 @@
+#----------------------------------------------------------------------------
+# USER! : SET THE NAME OF YOUR LIBRARY
+# (Replace 'MyLib' by your own library name)
+
+#############################
+SET ( LIBRARY_NAME   PrePostProcessing )
+#############################
+
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES A USER OPTION IN CMAKE
+OPTION ( BUILD_${LIBRARY_NAME}  "Build ${LIBRARY_NAME} library ?" ON)
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+IF ( BUILD_${LIBRARY_NAME} )
+#----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # BUILD LIBRARY
+  #----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # LIBRARY HEADERS (TO BE INSTALLED)
+  # EITHER LIST ALL .h, *.txx IN CURRENT DIR USING NEXT LINE:
+
+  FILE(GLOB ${LIBRARY_NAME}_HEADERS "*.h" "*.txx" "*.hxx")
+  
+  # OR MANUALLY LIST YOUR HEADERS WITH NEXT COMMAND
+  #  SET ( ${LIBRARY_NAME}_HEADERS
+  #
+  #      )
+  #----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # LIBRARY SOURCES (TO BE COMPILED)
+  # EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+
+  FILE(GLOB ${LIBRARY_NAME}_SOURCES *.cxx *.cpp *.cc ${${LIBRARY_NAME}_HEADERS})
+
+  # OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+  #  SET ( ${LIBRARY_NAME}_SOURCES 
+  #   
+  #      )
+  #----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # LIBRARY DEPENDENCIES (LIBRARIES TO LINK WITH)
+  #
+  # USER! : Uncomment the Libraries you need
+  #
+  SET ( ${LIBRARY_NAME}_LINK_LIBRARIES
+  #    ${crea_LIBRARIES}
+  #    ${WXWIDGETS_LIBRARIES}
+  #    ${KWWidgets_LIBRARIES}
+  #    ${VTK_LIBRARIES}
+  #    ${ITK_LIBRARIES}
+  #    ${GDCM_LIBRARIES}
+  #    ${BOOST_LIBRARIES}
+
+  # If this library must link against other libraries 
+  # USER! : Add here any extra Library you need
+
+      )
+  #----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # MACRO WHICH DOES ALL THE JOB : BUILD AND INSTALL
+
+  # USER! : The default is to create a Dynamic Library.
+  # if you need to create a static library
+  # comment out the following line :
+
+  #CREA_ADD_LIBRARY( ${LIBRARY_NAME} )
+
+  # and uncomment the 2 lines hereafter:
+
+   ADD_LIBRARY(${LIBRARY_NAME} STATIC  ${${LIBRARY_NAME}_SOURCES})
+   TARGET_LINK_LIBRARIES(${LIBRARY_NAME} ${${LIBRARY_NAME}_LINK_LIBRARIES} )
+   SET_TARGET_PROPERTIES(${LIBRARY_NAME} PROPERTIES LINKER_LANGUAGE C)
+
+  #
+  #----------------------------------------------------------------------------
+
+  #---------------------------------------------------------------------------
+ENDIF ( BUILD_${LIBRARY_NAME} )
diff --git a/Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis.h b/Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis.h
new file mode 100755 (executable)
index 0000000..46bc56c
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ #
+ #  File        : itkSTMS_ArgumentsAnalysis.h
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+
+#ifndef itkSTMS_ArgumentsAnalysis_H
+#define itkSTMS_ArgumentsAnalysis_H
+
+#include <getopt.h>
+#include <string>
+
+namespace itkSTMS
+{
+    static struct option long_options[] =
+    {
+        {"expDescription", required_argument, 0, 'd'},
+        {"imageDimension", required_argument, 0, 'i'},
+        {"numTimePoints",  required_argument, 0, 'n'},
+        {"startTimePoint", required_argument, 0, 's'},
+        {"xScale",         required_argument, 0, 'x'},
+        {"yScale",         required_argument, 0, 'y'},
+        {"zScale",         required_argument, 0, 'z'},
+        {"rScale",         required_argument, 0, 'r'},
+        {"epsilon",        required_argument, 0, 'e'},
+        {"maxIt",          required_argument, 0, 'm'},
+        {"merge",          no_argument      , 0, 'g'},
+        {"help",           no_argument      , 0, 'h'},
+        {0, 0, 0, 0}
+    };
+
+    struct ParamsAnalysisOutputType
+    {
+        std::string  expDescription;
+        float        spScales[3];
+        float        rScale;
+        float        epsilon;
+        unsigned int maxIt;
+        unsigned int dim;
+        unsigned int numTimePoints;
+        unsigned int startTimePoint;
+        bool         merge;
+        std::string help;
+        bool        isOk;
+    };
+
+
+    class itkSTMS_ArgumentsAnalysis{
+
+    public:
+        itkSTMS_ArgumentsAnalysis(int argc, char **argv);
+        void Update();
+        void ParametersDisplay();
+        void ParametersAnalysisInfo();
+        void CheckProvidedParameters();
+        inline ParamsAnalysisOutputType* GetSTMSParams(){ return &readParams; }
+
+    private:
+        ParamsAnalysisOutputType readParams;
+        int    argc;
+        char **argv;
+
+    };
+} // end of namespace itkSTMS
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSTMS_ArgumentsAnalysis.hxx"
+#endif
+
+#endif // itkSTMS_ArgumentsAnalysis_H
diff --git a/Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis.hxx b/Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis.hxx
new file mode 100755 (executable)
index 0000000..b3e5c88
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ #
+ #  File        : itkSTMS_ArgumentsAnalysis.hxx
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_ArgumentsAnalysis_HXX
+#define itkSTMS_ArgumentsAnalysis_HXX
+
+#include <iomanip>
+#include <string>
+#include "itkSTMS_ArgumentsAnalysis.h"
+
+namespace itkSTMS
+{
+itkSTMS_ArgumentsAnalysis::itkSTMS_ArgumentsAnalysis(int argc, char **argv)
+{
+    readParams.expDescription = "";
+    readParams.numTimePoints  = 0;
+    readParams.startTimePoint = 1;
+    readParams.epsilon        = 0.01;
+    readParams.maxIt          = 100 ;
+    readParams.spScales[0]    = 1.0;
+    readParams.spScales[1]    = 1.0;
+    readParams.spScales[2]    = 1.0;
+    readParams.rScale         = 1.0;
+    readParams.dim            = 3;
+    readParams.merge          = false;
+    readParams.help           = "";
+    readParams.isOk           = false;
+
+    this->argc = argc;
+    this->argv = argv;
+}
+
+void itkSTMS_ArgumentsAnalysis::ParametersDisplay()
+{
+    std::cout << std::endl <<
+                 std::setw(29) << std::left << "Experiment description"       << ": " << readParams.expDescription << std::endl;
+    std::cout << std::setw(29) << std::left << "Image dimension"              << ": " << readParams.dim            << std::endl;
+    std::cout << std::setw(29) << std::left << "Number of time-points"        << ": " << readParams.numTimePoints  << std::endl;
+    std::cout << std::setw(29) << std::left << "Staring time point"           << ": " << readParams.startTimePoint << std::endl;
+    std::cout << std::setw(29) << std::left << "X scale"                      << ": " << readParams.spScales[0]    << std::endl;
+    std::cout << std::setw(29) << std::left << "Y scale"                      << ": " << readParams.spScales[1]    << std::endl;
+    std::cout << std::setw(29) << std::left << "Z scale"                      << ": " << readParams.spScales[2]    << std::endl;
+    std::cout << std::setw(29) << std::left << "Range scale"                  << ": " << readParams.rScale         << std::endl;
+    std::cout << std::setw(29) << std::left << "Epsilon"                      << ": " << readParams.epsilon        << std::endl;
+    std::cout << std::setw(29) << std::left << "Maximum number of iterations" << ": " << readParams.maxIt          << std::endl;
+    std::cout << std::setw(29) << std::left << "Samples merging"              << ": " << readParams.merge          << std::endl << std::endl;
+}
+
+void itkSTMS_ArgumentsAnalysis::ParametersAnalysisInfo()
+{
+    std::cout << std::endl <<
+                 std::setw(17) << std::left << "--expDescription" << ": Path to the XML file used to generate the image sequence." << std::endl;
+    std::cout << std::setw(17) << std::left << "--imageDimension" << ": Number of spatial components. (Default 3)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--numTimePoints"  << ": Number of time-points." << std::endl;
+    std::cout << std::setw(17) << std::left << "--startTimePoint" << ": Starting time point (default is 0)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--xScale"         << ": Spatial scale used for the x axis. (Default 1.0)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--yScale"         << ": Spatial scale used for the z axis. (Default 1.0)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--zScale"         << ": Spatial scale used for the z axis. Optional when using 2D images. (Default 1.0)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--rScale"         << ": Range scale used to set the tolerance on the infinity norm. (Default 1.0)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--epsilon"        << ": Stopping criteria of the STM-S procedure. Minimum global displacement of the samples. (Default 0.01)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--maxIt"          << ": Maximum number of iterations of the STM-S procedure. (Default 100)" << std::endl << std::endl;
+    std::cout << std::setw(17) << std::left << "--merge"          << ": Specify if the samples are merged during the STMS procedure. No merging by default, no argument is needed after --merge." << std::endl << std::endl;
+    std::cout << std::setw(17) << std::left << "--help"           << ": Usage help" << std::endl << std::endl;
+}
+
+
+void itkSTMS_ArgumentsAnalysis::CheckProvidedParameters(){
+
+    if( readParams.expDescription != "")
+        readParams.isOk = true;
+}
+
+void itkSTMS_ArgumentsAnalysis::Update()
+{
+    int c;
+    bool first_it = true;
+    while (1)
+    {
+        /* getopt_long stores the option index here. */
+        int option_index = 0;
+
+        c = getopt_long (argc, argv, "d:i::n:x::y::z::r::e::m::g::h::s::",
+                         long_options, &option_index);
+
+        std::string str;
+
+        switch (c)
+        {
+        case 'd':
+            readParams.expDescription = std::string(optarg);
+            break;
+
+        case 'i':
+            str = std::string(optarg);
+            readParams.dim = (unsigned int)std::stoi( str );
+            break;
+
+        case 'n':
+            str = std::string(optarg);
+            readParams.numTimePoints = (unsigned int)std::stoi( str );
+            break;
+
+       case 's':
+            str = std::string(optarg);
+            readParams.startTimePoint = (unsigned int)std::stoi( str );
+            break;
+
+        case 'x':
+            str = std::string(optarg);
+            readParams.spScales[0] = std::stof( str );
+            break;
+
+        case 'y':
+            str = std::string(optarg);
+            readParams.spScales[1] = std::stof( str );
+            break;
+
+        case 'z':
+            str = std::string(optarg);
+            readParams.spScales[2] = std::stof( str );
+            break;
+
+        case 'r':
+            str = std::string(optarg);
+            readParams.rScale = std::stof( str );
+            break;
+
+        case 'e':
+            str = std::string(optarg);
+            readParams.epsilon = std::stof( str );
+            break;
+
+        case 'm':
+           str = std::string(optarg);
+            readParams.maxIt = (unsigned int)std::stoi( str );
+            break;
+
+        case 'g':
+            readParams.merge = true;
+            break;
+
+        case 'h':
+            std::cout << std::endl << "Usage help:";
+            ParametersAnalysisInfo();
+            std::exit( EXIT_SUCCESS );
+            break;
+
+        case '?':
+            std::cout << std::endl << "Usage help:";
+            ParametersAnalysisInfo();
+            std::exit( EXIT_FAILURE );
+            break;
+        }
+
+        if( (c==-1) & first_it )
+        {
+            std::cout << std::endl << "Usage help:";
+            ParametersAnalysisInfo();
+            std::exit( EXIT_SUCCESS );
+        }
+
+        first_it = false;
+
+        /* Detect the end of the options. */
+        if ( (c==-1) & !first_it )
+        {
+            break;
+        }
+    }
+
+    CheckProvidedParameters();
+    if( readParams.isOk )
+    {
+        ParametersDisplay();
+    }
+    else
+    {
+        std::cout << std::endl << "All required parameters are not provided";
+        ParametersAnalysisInfo();
+        std::exit( EXIT_FAILURE );
+    }
+}
+
+} // end of namespace itkSTMS
+#endif // itkSTMS_ArgumentsAnalysis_HXX
diff --git a/Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis_Spine.h b/Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis_Spine.h
new file mode 100755 (executable)
index 0000000..b45d631
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ #
+ #  File        : itkSTMS_ArgumentsAnalysis_Spine.h
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_ArgumentsAnalysisSpine_H
+#define itkSTMS_ArgumentsAnalysisSpine_H
+
+#include <getopt.h>
+#include <string>
+#include <list>
+
+namespace itkSTMS_Spine
+{
+    static struct option long_options[] =
+    {
+        {"image",          required_argument, 0, 'd'},
+        {"mask",           required_argument, 0, 'l'},
+        {"outFolder",      required_argument, 0, 'o'},
+        {"imageDimension", required_argument, 0, 'i'},
+        {"imageExtension", required_argument, 0, 'q'},
+        {"xScale",         required_argument, 0, 'x'},
+        {"yScale",         required_argument, 0, 'y'},
+        {"zScale",         required_argument, 0, 'z'},
+        {"rScale",         required_argument, 0, 'r'},
+        {"epsilon",        required_argument, 0, 'e'},
+        {"maxIt",          required_argument, 0, 'm'},
+        {"merge",          no_argument      , 0, 'g'},
+        {"help",           no_argument      , 0, 'h'},
+        {0, 0, 0, 0}
+    };
+
+    struct ParamsAnalysisOutputType
+    {
+        std::list<std::string>  images;
+        std::string  mask;
+        std::string  outFolder;
+        float        spScales[3];
+        float        rScale;
+        float        epsilon;
+        unsigned int maxIt;
+        unsigned int dim;
+        unsigned int numTimePoints;
+        bool         merge;
+        std::string  imageExtension;
+
+        std::string help;
+        bool        isOk;
+    };
+
+
+    class itkSTMS_ArgumentsAnalysis{
+
+    public:
+        itkSTMS_ArgumentsAnalysis(int argc, char **argv);
+        void Update();
+        void ParametersDisplay();
+        void ParametersAnalysisInfo();
+        void CheckProvidedParameters();
+        inline ParamsAnalysisOutputType* GetSTMSParams(){ return &readParams; }
+
+    private:
+        ParamsAnalysisOutputType readParams;
+        int    argc;
+        char **argv;
+
+    };
+} // end of namespace itkSTMS
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSTMS_ArgumentsAnalysis_Spine.hxx"
+#endif
+
+#endif // itkSTMS_ArgumentsAnalysisSpine_H
diff --git a/Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis_Spine.hxx b/Lib/PrePostProcessing/itkSTMS_ArgumentsAnalysis_Spine.hxx
new file mode 100755 (executable)
index 0000000..4c63098
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ #
+ #  File        : itkSTMS_ArgumentsAnalysis_Spine.hxx
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_ArgumentsAnalysisSpine_HXX
+#define itkSTMS_ArgumentsAnalysisSpine_HXX
+
+#include<iostream>
+#include <iomanip>
+#include<string>
+#include "itkSTMS_ArgumentsAnalysis_Spine.h"
+
+namespace itkSTMS_Spine
+{
+itkSTMS_ArgumentsAnalysis::itkSTMS_ArgumentsAnalysis(int argc, char **argv)
+{
+    readParams.numTimePoints  = 0;
+    readParams.epsilon        = 0.01;
+    readParams.maxIt          = 100 ;
+    readParams.spScales[0]    = 1.0;
+    readParams.spScales[1]    = 1.0;
+    readParams.spScales[2]    = 1.0;
+    readParams.rScale         = 1.0;
+    readParams.dim            = 3;
+    readParams.merge          = false;
+    readParams.help           = "";
+    readParams.mask           = "";
+    readParams.outFolder      = "";
+    readParams.isOk           = false;
+    readParams.imageExtension = ".nii.gz";
+
+    this->argc = argc;
+    this->argv = argv;
+}
+
+void itkSTMS_ArgumentsAnalysis::ParametersDisplay()
+{
+    std::cout << std::endl <<
+                 std::setw(29) << std::left << "Image dimension"              << ": " << readParams.dim            << std::endl;
+    std::cout << std::setw(29) << std::left << "Mask image"                   << ": " << readParams.mask           << std::endl;
+    std::cout << std::setw(29) << std::left << "Output folder"                << ": " << readParams.outFolder      << std::endl;
+    std::cout << std::setw(29) << std::left << "Nb of time-points"            << ": " << readParams.numTimePoints  << std::endl;
+    std::cout << std::setw(29) << std::left << "X scale"                      << ": " << readParams.spScales[0]    << std::endl;
+    std::cout << std::setw(29) << std::left << "Y scale"                      << ": " << readParams.spScales[1]    << std::endl;
+    std::cout << std::setw(29) << std::left << "Z scale"                      << ": " << readParams.spScales[2]    << std::endl;
+    std::cout << std::setw(29) << std::left << "Range scale"                  << ": " << readParams.rScale         << std::endl;
+    std::cout << std::setw(29) << std::left << "Epsilon"                      << ": " << readParams.epsilon        << std::endl;
+    std::cout << std::setw(29) << std::left << "Maximum number of iterations" << ": " << readParams.maxIt          << std::endl;
+    std::cout << std::setw(29) << std::left << "Images extension"             << ": " << readParams.imageExtension << std::endl;
+    std::cout << std::setw(29) << std::left << "Samples merging"              << ": " << readParams.merge          << std::endl << std::endl;
+}
+
+void itkSTMS_ArgumentsAnalysis::ParametersAnalysisInfo()
+{
+    std::cout << std::endl <<
+                 std::setw(17) << std::left << "--image         " << ": Path to an image of the sequence." << std::endl;
+    std::cout << std::setw(17) << std::left << "--mask"           << ": Binary mask image (optional)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--outFolder"      << ": Output images folder" << std::endl;
+    std::cout << std::setw(17) << std::left << "--imageDimension" << ": Number of spatial components. (Default 3)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--imageExtension" << ": Extension of the images. (Default .nii.gz)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--xScale"         << ": Spatial scale used for the x axis. (Default 1.0)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--yScale"         << ": Spatial scale used for the z axis. (Default 1.0)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--zScale"         << ": Spatial scale used for the z axis. Optional when using 2D images. (Default 1.0)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--rScale"         << ": Range scale used to set the tolerance on the infinity norm. (Default 1.0)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--epsilon"        << ": Stopping criteria of the STM-S procedure. Minimum global displacement of the samples. (Default 0.01)" << std::endl;
+    std::cout << std::setw(17) << std::left << "--maxIt"          << ": Maximum number of iterations of the STM-S procedure. (Default 100)" << std::endl << std::endl;
+    std::cout << std::setw(17) << std::left << "--merge"          << ": Specify if the samples are merged during the STMS procedure. No merging by default, no argument is needed after --merge." << std::endl << std::endl;
+    std::cout << std::setw(17) << std::left << "--help"           << ": Usage help" << std::endl << std::endl;
+}
+
+
+void itkSTMS_ArgumentsAnalysis::CheckProvidedParameters(){
+
+    if( !readParams.images.empty() & !readParams.outFolder.empty())
+        readParams.isOk = true;
+}
+
+void itkSTMS_ArgumentsAnalysis::Update()
+{
+    int c;
+    bool first_it = true;
+    while (1)
+    {
+        /* getopt_long stores the option index here. */
+        int option_index = 0;
+
+        c = getopt_long (argc, argv, "d:l::o:i::x::y::z::r::e::m::g::h::q::",
+                         long_options, &option_index);
+
+        std::string str;
+
+        switch (c)
+        {
+        case 'd':
+            readParams.images.push_back( std::string(optarg) );
+            break;
+
+        case 'q':
+            readParams.imageExtension = std::string(optarg);
+            break;
+
+        case 'l':
+            readParams.mask = std::string(optarg);
+            break;
+
+        case 'o':
+            readParams.outFolder = std::string(optarg);
+            break;
+
+        case 'i':
+            str = std::string(optarg);
+            readParams.dim = (unsigned int)std::stoi( str );
+            break;
+
+        case 'x':
+            str = std::string(optarg);
+            readParams.spScales[0] = std::stof( str );
+            break;
+
+        case 'y':
+            str = std::string(optarg);
+            readParams.spScales[1] = std::stof( str );
+            break;
+
+        case 'z':
+            str = std::string(optarg);
+            readParams.spScales[2] = std::stof( str );
+            break;
+
+        case 'r':
+            str = std::string(optarg);
+            readParams.rScale = std::stof( str );
+            break;
+
+        case 'e':
+            str = std::string(optarg);
+            readParams.epsilon = std::stof( str );
+            break;
+
+        case 'm':
+           str = std::string(optarg);
+            readParams.maxIt = (unsigned int)std::stoi( str );
+            break;
+
+        case 'g':
+            readParams.merge = true;
+            break;
+
+        case 'h':
+            std::cout << std::endl << "Usage help:";
+            ParametersAnalysisInfo();
+            std::exit( EXIT_SUCCESS );
+            break;
+
+        case '?':
+            std::cout << std::endl << "Usage help:";
+            ParametersAnalysisInfo();
+            std::exit( EXIT_FAILURE );
+            break;
+        }
+
+        if( (c==-1) & first_it )
+        {
+            std::cout << std::endl << "Usage help:";
+            ParametersAnalysisInfo();
+            std::exit( EXIT_SUCCESS );
+        }
+
+        first_it = false;
+
+        /* Detect the end of the options. */
+        if ( (c==-1) & !first_it )
+        {
+            break;
+        }
+    }
+
+    CheckProvidedParameters();
+    if( readParams.isOk )
+    {
+        readParams.numTimePoints = (unsigned int)readParams.images.size();
+        ParametersDisplay();
+    }
+    else
+    {
+        std::cout << std::endl << "All required parameters are not provided";
+        ParametersAnalysisInfo();
+        std::exit( EXIT_FAILURE );
+    }
+}
+
+} // end of namespace itkSTMS
+#endif // itkSTMS_ArgumentsAnalysisSpine_HXX
diff --git a/Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet.h b/Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet.h
new file mode 100755 (executable)
index 0000000..b0eed2b
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ #
+ #  File        : itkSTMS_ImageSequenceToTemporalSet.h
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_ImageSequenceToTemporalSet_h
+#define itkSTMS_ImageSequenceToTemporalSet_h
+
+#include <string>
+#include <vector>
+//#include <array>
+
+#include "itkImage.h"
+#include "itkSTMS_XMLFileParser.h"
+#include "itkSTMS_ArgumentsAnalysis.h"
+#include "itkImageFileReader.h"
+#include "itkImageRegionConstIteratorWithIndex.h"
+#include "itkMinimumMaximumImageCalculator.h"
+
+#ifndef STMS_NUMBERING_FORM_ONE
+#define STMS_NUMBERING_FORM_ONE "1"
+#endif
+
+namespace itkSTMS
+{
+    template < class ImageType, class MaskImageType >
+    class itkSTMS_ImageSequenceToTemporalSet
+    {
+
+    public:
+        // Reader typedefs
+        typedef itk::ImageFileReader< ImageType >      ReaderType;
+        typedef typename ReaderType::Pointer           ReaderPointer;
+        typedef itk::ImageFileReader< MaskImageType >  MaskReaderType;
+        typedef typename MaskReaderType::Pointer       MaskReaderPointer;
+
+        // Mask processing typedefs
+        typedef itk::MinimumMaximumImageCalculator< MaskImageType >
+                MinMaxCalculatorType;
+        typedef typename MinMaxCalculatorType::Pointer MinMaxCalculatorPointer;
+
+        // Iterator typedefs
+        typedef itk::ImageRegionConstIteratorWithIndex< ImageType >     IteratorType;
+        typedef itk::ImageRegionConstIteratorWithIndex< MaskImageType > MaskIteratorType;
+
+        // Sample set typedefs
+        typedef unsigned int                            IndexType;
+        typedef float                                   SpatialType;
+        typedef typename ImageType::PixelType           PixelType;
+
+        typedef typename ImageType::Pointer             ImagePointer;
+        typedef typename ImageType::ConstPointer        ImageConstPointer;
+        typedef typename ImageType::SizeType            SizeType;
+
+        typedef std::vector< SpatialType >              SpatialVectorType;
+        typedef std::vector< PixelType >                RangeVectorType;
+
+        typedef std::vector< IndexType >                IndexSampleSetType;
+        typedef std::vector< SpatialVectorType >        SpatialSampleSetType;
+        typedef std::vector< RangeVectorType >          RangeSampleSetType;
+
+        // Mask image typedefs
+        typedef typename MaskImageType::PixelType       MaskPixelType;
+        typedef typename MaskImageType::Pointer         MaskImagePointer;
+        typedef typename MaskImageType::ConstPointer    MaskImageConstPointer;
+
+        // Methods
+        itkSTMS_ImageSequenceToTemporalSet( itkSTMS::ParamsAnalysisOutputType* stmsParameters );
+        inline ~itkSTMS_ImageSequenceToTemporalSet(){ delete xmlParser; }
+
+        void GenerateDataSets();
+
+        inline IndexSampleSetType*   GetIndexSet  (){ return &indexSet;   }
+        inline IndexSampleSetType*   GetClassSet  (){ return &classSet;   }
+        inline IndexSampleSetType*   GetMergingSet(){ return &mergingSet; }
+        inline IndexSampleSetType*   GetWeightsSet(){ return &weightsSet; }
+        inline SpatialSampleSetType* GetSpatialSet(){ return &spatialSet; }
+        inline RangeSampleSetType*   GetRangeSet  (){ return &rangeSet;   }
+
+        inline itkSTMS::ParserOutputType* GetExperimentDescription(){ return expDescription; }
+
+    private:
+        // Attributes
+        itkSTMS::itkSTMS_XMLFileParser*    xmlParser;
+        itkSTMS::ParserOutputType*         expDescription;
+        itkSTMS::ParamsAnalysisOutputType* stmsParameters;
+
+        IndexSampleSetType      indexSet,
+                                classSet,
+                                mergingSet,
+                                weightsSet;
+        SpatialSampleSetType    spatialSet;
+        RangeSampleSetType      rangeSet;
+
+        MaskPixelType           maskValue;
+        MaskImagePointer        mask;
+        MaskReaderPointer       mReader;
+        MinMaxCalculatorPointer MinMaxCalculator;
+        std::string             maskPath;
+        MaskIteratorType        mIt;
+
+    };  // end of class itkSTMS_ImageSequenceToTemporalSet
+} // end of namespace itkstms
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSTMS_ImageSequenceToTemporalSet.txx"
+#endif
+
+#endif
diff --git a/Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet.txx b/Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet.txx
new file mode 100755 (executable)
index 0000000..8b361d5
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ #
+ #  File        : itkSTMS_ImageSequenceToTemporalSet.txx
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_ImageSequenceToTemporalSet_txx
+#define itkSTMS_ImageSequenceToTemporalSet_txx
+
+#include <string> 
+#include "itkSTMS_ImageSequenceToTemporalSet.h"
+#include "itkSTMS_XMLFileParser.h"
+#include "itkSTMS_ArgumentsAnalysis.h"
+#include "itkFancyString.h"
+
+
+namespace itkSTMS
+{
+
+template < class ImageType, class MaskImageType >
+itkSTMS_ImageSequenceToTemporalSet < ImageType, MaskImageType >
+::itkSTMS_ImageSequenceToTemporalSet( ParamsAnalysisOutputType* stmsParameters )
+{
+    // Get experiments parameters given by the user
+    this->stmsParameters = stmsParameters;
+
+    // XML file parsing
+    xmlParser = new itkSTMS::itkSTMS_XMLFileParser();
+    xmlParser->SetFileName( this->stmsParameters->expDescription );
+    xmlParser->Update();
+
+    expDescription = xmlParser->GetXMLParams();
+
+    // If a mask image is specified ==> instanciation of a mask iterator (region with the highest value in the mask)
+    if( expDescription->maskImage != "null" )
+    {
+        mask = MaskImageType::New();
+        mReader = MaskReaderType::New();
+        MinMaxCalculator = MinMaxCalculatorType::New();
+
+        maskPath = expDescription->experimentPath+expDescription->inputFolder+expDescription->maskImage+expDescription->imageExtension;
+        mReader->SetFileName( maskPath );
+        mReader->Update();
+        mask = mReader->GetOutput();
+
+        MinMaxCalculator->SetImage( mask );
+        MinMaxCalculator->ComputeMaximum();
+        maskValue = (MaskPixelType)MinMaxCalculator->GetMaximum();
+
+        mIt = MaskIteratorType( mask, mask->GetLargestPossibleRegion() ); //->GetBufferedRegion() );
+    }
+}
+
+
+template < class ImageType, class MaskImageType >
+void
+itkSTMS_ImageSequenceToTemporalSet< ImageType, MaskImageType >
+::GenerateDataSets()
+{
+    bool first = true;
+    std::string str;
+    IndexType idx;
+
+    // Preprocessing of the whole image sequence  // stmsParameters->startTimePoint 
+    for( unsigned int i=1 ; i<=stmsParameters->numTimePoints - stmsParameters->startTimePoint + 1 ; ++i )
+    {
+        idx = 0;
+
+        char buffer[6];
+        int n = 0;
+
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 6 ) n=sprintf (buffer, "%05d", i + stmsParameters->startTimePoint - 1);
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 5 ) n=sprintf (buffer, "%04d", i + stmsParameters->startTimePoint - 1);
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 4 ) n=sprintf (buffer, "%03d", i + stmsParameters->startTimePoint - 1);
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 3 ) n=sprintf (buffer, "%02d", i + stmsParameters->startTimePoint - 1);
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 2 ) n=sprintf (buffer, "%01d", i + stmsParameters->startTimePoint - 1);
+
+        std::string imagePath = expDescription->experimentPath+expDescription->inputFolder+expDescription->inputCommonRoot+buffer+expDescription->imageExtension;
+
+        ImagePointer image
+                = ImageType::New();
+        ReaderPointer reader
+                = itk::ImageFileReader< ImageType >::New();
+
+        reader->SetFileName( imagePath );
+        reader->Update();
+        image = reader->GetOutput();
+
+        IteratorType it( image, image->GetLargestPossibleRegion() );
+        SizeType Size = image->GetLargestPossibleRegion().GetSize();
+
+        // If there is no mask image specified, all the pixels are extracted
+        if( expDescription->maskImage == "null" )
+        {
+            // Only the range values have to be extracted at each time-point. The others need to be extracted just one time.
+            if( first )
+            {
+                // Containers initialisation
+                unsigned int numSamples = (unsigned int)Size[0];
+
+                for( unsigned int j=1 ; j<stmsParameters->dim ; ++j )
+                    numSamples *= (unsigned int)Size[j];
+
+                indexSet   = IndexSampleSetType( numSamples, 0 );
+                classSet   = IndexSampleSetType( numSamples, 0 );
+                mergingSet = IndexSampleSetType( numSamples, 0 );
+                weightsSet = IndexSampleSetType( numSamples, 1 );
+                spatialSet = SpatialSampleSetType( numSamples, SpatialVectorType(stmsParameters->dim, 0));
+                rangeSet   = RangeSampleSetType  ( numSamples, RangeVectorType(stmsParameters->numTimePoints - stmsParameters->startTimePoint + 1, 0) );
+            }
+
+            // Samples extraction
+            it.GoToBegin();
+            while( !it.IsAtEnd() ){
+                if( first ){
+                    indexSet[idx]    = idx;
+                    classSet[idx]    = idx+1;
+
+                    for( unsigned int j=0 ; j<stmsParameters->dim ; ++j )
+                        spatialSet[idx][j] = (SpatialType)( it.GetIndex()[j]/stmsParameters->spScales[j] );
+                }
+
+                rangeSet[idx++][i-1] = (PixelType)(it.Get()/stmsParameters->rScale);
+                ++it;
+            }
+
+            if( first )
+                first = false;
+        }
+        // If a mask is specified, just the characteristics of the pixels equal to maskValue in the mask image are extracted
+        else
+        {
+            // In this case the number of samples is not known in advance
+            if( first )
+            {
+                indexSet   = IndexSampleSetType();
+                classSet   = IndexSampleSetType();
+                mergingSet = IndexSampleSetType();
+                weightsSet = IndexSampleSetType();
+                spatialSet = SpatialSampleSetType();
+                rangeSet   = RangeSampleSetType();
+
+                indexSet.reserve  ( Size[0]*Size[1] );
+                classSet.reserve  ( Size[0]*Size[1] );
+                mergingSet.reserve( Size[0]*Size[1] );
+                weightsSet.reserve( Size[0]*Size[1] );
+                spatialSet.reserve( Size[0]*Size[1] );
+                rangeSet.reserve  ( Size[0]*Size[1] );
+            }
+
+            // Samples extraction
+            mIt.GoToBegin();
+            it.GoToBegin();
+            while( !mIt.IsAtEnd() )
+            {
+                if(mIt.Get() == maskValue)
+                {
+                    if( first )
+                    {
+                        SpatialVectorType spComp = SpatialVectorType(stmsParameters->dim, 0);
+                        for( unsigned int j=0 ; j<stmsParameters->dim ; ++j )
+                            spComp[j] = (SpatialType)( it.GetIndex()[j]/stmsParameters->spScales[j] );
+
+                        indexSet.push_back  ( idx    );
+                        classSet.push_back  ( ++idx  );
+                        mergingSet.push_back( 0      );
+                        weightsSet.push_back( 1      );
+                        spatialSet.push_back( spComp );
+                        rangeSet.push_back( RangeVectorType(stmsParameters->numTimePoints - stmsParameters->startTimePoint + 1, (PixelType)(it.Get()/stmsParameters->rScale)) );
+                    }
+                    else
+                        rangeSet[idx++][i-1] = (PixelType)(it.Get()/stmsParameters->rScale);
+                }
+
+                ++mIt;
+                ++it;
+            }
+
+            if( first )
+                first = false;
+        }
+    }
+}
+
+} // end of namespace itkSTMS
+
+#endif
diff --git a/Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet_Spine.h b/Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet_Spine.h
new file mode 100755 (executable)
index 0000000..7180ed3
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ #
+ #  File        : itkSTMS_ImageSequenceToTemporalSet_Spine.h
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_ImageSequenceToTemporalSetSpine_h
+#define itkSTMS_ImageSequenceToTemporalSetSpine_h
+
+#include <string>
+#include <vector>
+//#include <array>
+
+#include "itkImage.h"
+#include "itkSTMS_ArgumentsAnalysis_Spine.h"
+#include "itkImageFileReader.h"
+#include "itkImageRegionConstIteratorWithIndex.h"
+#include "itkMinimumMaximumImageCalculator.h"
+
+namespace itkSTMS_Spine
+{
+    template < class ImageType, class MaskImageType >
+    class itkSTMS_ImageSequenceToTemporalSet
+    {
+
+    public:
+        // Reader typedefs
+        typedef itk::ImageFileReader< ImageType >      ReaderType;
+        typedef typename ReaderType::Pointer           ReaderPointer;
+        typedef itk::ImageFileReader< MaskImageType >  MaskReaderType;
+        typedef typename MaskReaderType::Pointer       MaskReaderPointer;
+
+        // Mask processing typedefs
+        typedef itk::MinimumMaximumImageCalculator< MaskImageType >
+                MinMaxCalculatorType;
+        typedef typename MinMaxCalculatorType::Pointer MinMaxCalculatorPointer;
+
+        // Iterator typedefs
+        typedef itk::ImageRegionConstIteratorWithIndex< ImageType >     IteratorType;
+        typedef itk::ImageRegionConstIteratorWithIndex< MaskImageType > MaskIteratorType;
+
+        // Sample set typedefs
+        typedef unsigned int                            IndexType;
+        typedef float                                   SpatialType;
+        typedef typename ImageType::PixelType           PixelType;
+
+        typedef typename ImageType::Pointer             ImagePointer;
+        typedef typename ImageType::ConstPointer        ImageConstPointer;
+        typedef typename ImageType::SizeType            SizeType;
+
+        typedef std::vector< SpatialType >              SpatialVectorType;
+        typedef std::vector< PixelType >                RangeVectorType;
+
+        typedef std::vector< IndexType >                IndexSampleSetType;
+        typedef std::vector< SpatialVectorType >        SpatialSampleSetType;
+        typedef std::vector< RangeVectorType >          RangeSampleSetType;
+
+        // Mask image typedefs
+        typedef typename MaskImageType::PixelType       MaskPixelType;
+        typedef typename MaskImageType::Pointer         MaskImagePointer;
+        typedef typename MaskImageType::ConstPointer    MaskImageConstPointer;
+
+        // Methods
+        itkSTMS_ImageSequenceToTemporalSet( itkSTMS_Spine::ParamsAnalysisOutputType* stmsParameters );
+
+        void GenerateDataSets();
+
+        inline IndexSampleSetType*   GetIndexSet  (){ return &indexSet;   }
+        inline IndexSampleSetType*   GetClassSet  (){ return &classSet;   }
+        inline IndexSampleSetType*   GetMergingSet(){ return &mergingSet; }
+        inline IndexSampleSetType*   GetWeightsSet(){ return &weightsSet; }
+        inline SpatialSampleSetType* GetSpatialSet(){ return &spatialSet; }
+        inline RangeSampleSetType*   GetRangeSet  (){ return &rangeSet;   }
+
+    private:
+        // Attributes
+        itkSTMS_Spine::ParamsAnalysisOutputType* stmsParameters;
+
+        IndexSampleSetType      indexSet,
+                                classSet,
+                                mergingSet,
+                                weightsSet;
+        SpatialSampleSetType    spatialSet;
+        RangeSampleSetType      rangeSet;
+
+        MaskPixelType           maskValue;
+        MaskImagePointer        mask;
+        MaskReaderPointer       mReader;
+        MinMaxCalculatorPointer MinMaxCalculator;
+        MaskIteratorType        mIt;
+
+    };  // end of class itkSTMS_ImageSequenceToTemporalSet
+} // end of namespace itkstms
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSTMS_ImageSequenceToTemporalSet_Spine.txx"
+#endif
+
+#endif
diff --git a/Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet_Spine.txx b/Lib/PrePostProcessing/itkSTMS_ImageSequenceToTemporalSet_Spine.txx
new file mode 100755 (executable)
index 0000000..27436a5
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ #
+ #  File        : itkSTMS_ImageSequenceToTemporalSet_Spine.txx
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_ImageSequenceToTemporalSetSpine_txx
+#define itkSTMS_ImageSequenceToTemporalSetSpine_txx
+
+#include <string> 
+#include "itkSTMS_ImageSequenceToTemporalSet_Spine.h"
+#include "itkSTMS_ArgumentsAnalysis_Spine.h"
+
+
+namespace itkSTMS_Spine
+{
+
+template < class ImageType, class MaskImageType >
+itkSTMS_ImageSequenceToTemporalSet < ImageType, MaskImageType >
+::itkSTMS_ImageSequenceToTemporalSet( ParamsAnalysisOutputType* stmsParameters )
+{
+    // Get experiments parameters given by the user
+    this->stmsParameters = stmsParameters;
+
+    // If a mask image is specified ==> instanciation of a mask iterator (region with the highest value in the mask)
+    if( !this->stmsParameters->mask.empty() )
+    {
+        mask = MaskImageType::New();
+        mReader = MaskReaderType::New();
+        MinMaxCalculator = MinMaxCalculatorType::New();
+
+        mReader->SetFileName( this->stmsParameters->mask );
+        mReader->Update();
+        mask = mReader->GetOutput();
+
+        MinMaxCalculator->SetImage( mask );
+        MinMaxCalculator->ComputeMaximum();
+        maskValue = (MaskPixelType)MinMaxCalculator->GetMaximum();
+
+        mIt = MaskIteratorType( mask, mask->GetLargestPossibleRegion() ); //->GetBufferedRegion() );
+    }
+}
+
+
+template < class ImageType, class MaskImageType >
+void
+itkSTMS_ImageSequenceToTemporalSet< ImageType, MaskImageType >
+::GenerateDataSets()
+{
+    bool first = true;
+    std::string str;
+    IndexType idx, i;
+
+    // Preprocessing of the whole image sequence
+    i=1;
+    for (std::list<std::string>::iterator it_images = stmsParameters->images.begin(); it_images != stmsParameters->images.end(); ++it_images)
+    {
+        idx = 0;
+
+        ImagePointer image
+                = ImageType::New();
+        ReaderPointer reader
+                = itk::ImageFileReader< ImageType >::New();
+
+        reader->SetFileName( *it_images );
+        reader->Update();
+        image = reader->GetOutput();
+
+        IteratorType it( image, image->GetLargestPossibleRegion() );
+        SizeType Size = image->GetLargestPossibleRegion().GetSize();
+
+        // If there is no mask image specified, all the pixels are extracted
+        if( stmsParameters->mask.empty() )
+        {
+            // Only the range values have to be extracted at each time-point. The others need to be extracted just one time.
+            if( first )
+            {
+                // Containers initialisation
+                unsigned int numSamples = (unsigned int)Size[0];
+
+                for( unsigned int j=1 ; j<stmsParameters->dim ; ++j )
+                    numSamples *= (unsigned int)Size[j];
+
+                indexSet   = IndexSampleSetType( numSamples, 0 );
+                classSet   = IndexSampleSetType( numSamples, 0 );
+                mergingSet = IndexSampleSetType( numSamples, 0 );
+                weightsSet = IndexSampleSetType( numSamples, 1 );
+                spatialSet = SpatialSampleSetType( numSamples, SpatialVectorType(stmsParameters->dim, 0));
+                rangeSet   = RangeSampleSetType  ( numSamples, RangeVectorType(stmsParameters->numTimePoints, 0) );
+            }
+
+            // Samples extraction
+            it.GoToBegin();
+            while( !it.IsAtEnd() ){
+                if( first ){
+                    indexSet[idx]    = idx;
+                    classSet[idx]    = idx+1;
+
+                    for( unsigned int j=0 ; j<stmsParameters->dim ; ++j )
+                        spatialSet[idx][j] = (SpatialType)( it.GetIndex()[j]/stmsParameters->spScales[j] );
+                }
+
+                rangeSet[idx++][i-1] = (PixelType)(it.Get()/stmsParameters->rScale);
+                ++it;
+            }
+
+            if( first )
+                first = false;
+        }
+        // If a mask is specified, just the characteristics of the pixels equal to maskValue in the mask image are extracted
+        else
+        {
+            // In this case the number of samples is not known in advance
+            if( first )
+            {
+                indexSet   = IndexSampleSetType();
+                classSet   = IndexSampleSetType();
+                mergingSet = IndexSampleSetType();
+                weightsSet = IndexSampleSetType();
+                spatialSet = SpatialSampleSetType();
+                rangeSet   = RangeSampleSetType();
+
+                indexSet.reserve  ( Size[0]*Size[1] );
+                classSet.reserve  ( Size[0]*Size[1] );
+                mergingSet.reserve( Size[0]*Size[1] );
+                weightsSet.reserve( Size[0]*Size[1] );
+                spatialSet.reserve( Size[0]*Size[1] );
+                rangeSet.reserve  ( Size[0]*Size[1] );
+            }
+
+            // Samples extraction
+            mIt.GoToBegin();
+            it.GoToBegin();
+            while( !mIt.IsAtEnd() )
+            {
+                if(mIt.Get() == maskValue)
+                {
+                    if( first )
+                    {
+                        SpatialVectorType spComp = SpatialVectorType(stmsParameters->dim, 0);
+                        for( unsigned int j=0 ; j<stmsParameters->dim ; ++j )
+                            spComp[j] = (SpatialType)( it.GetIndex()[j]/stmsParameters->spScales[j] );
+
+                        indexSet.push_back  ( idx    );
+                        classSet.push_back  ( ++idx  );
+                        mergingSet.push_back( 0      );
+                        weightsSet.push_back( 1      );
+                        spatialSet.push_back( spComp );
+                        rangeSet.push_back( RangeVectorType(stmsParameters->numTimePoints, (PixelType)(it.Get()/stmsParameters->rScale)) );
+                    }
+                    else
+                        rangeSet[idx++][i-1] = (PixelType)(it.Get()/stmsParameters->rScale);
+                }
+
+                ++mIt;
+                ++it;
+            }
+
+            if( first )
+                first = false;
+        }
+
+        ++i;
+    }
+}
+
+} // end of namespace itkSTMS
+
+#endif
diff --git a/Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence.h b/Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence.h
new file mode 100755 (executable)
index 0000000..dd93ea4
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ #
+ #  File        : itkSTMS_TemporalSetToImageSequence.h
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_TemporalSetToImageSequence_h
+#define itkSTMS_TemporalSetToImageSequence_h
+
+#include <string>
+#include <vector>
+#include <math.h>
+
+#include "itkImage.h"
+#include "itkImageFileReader.h"
+#include "itkImageFileWriter.h"
+#include "itkImageRegionIteratorWithIndex.h"
+
+
+#ifndef STMS_NUMBERING_FORM_ONE
+#define STMS_NUMBERING_FORM_ONE "1"
+#endif
+
+namespace itkSTMS
+{
+    template < class ImageType, class ClassImageType >
+    class itkSTMS_TemporalSetToImageSequence
+    {
+    public:
+        // Reader and writer typedefs
+        typedef itk::ImageFileReader< ImageType >       ReaderType;
+        typedef typename ReaderType::Pointer            ReaderPointer;
+        typedef itk::ImageFileWriter< ImageType >       WriterType;
+        typedef typename WriterType::Pointer            WriterPointer;
+        typedef itk::ImageFileWriter< ClassImageType >  ClassWriterType;
+        typedef typename ClassWriterType::Pointer       ClassWriterPointer;
+
+        // Sample set typedefs
+        typedef unsigned int                        IndexType;
+        typedef float                               SpatialType;
+        typedef typename ImageType::PixelType       PixelType;
+
+        typedef std::vector< SpatialType >          SpatialVectorType;
+        typedef std::vector< PixelType >            RangeVectorType;
+
+        typedef std::vector< IndexType >            IndexSampleSetType;
+        typedef std::vector< SpatialVectorType >    SpatialSampleSetType;
+        typedef std::vector< RangeVectorType >      RangeSampleSetType;
+
+        // Image typedefs
+        typedef typename ImageType::IndexType       SpatialIndexType;
+        typedef typename ImageType::RegionType      RegionType;
+
+        typedef typename ImageType::Pointer         ImagePointer;
+        typedef typename ImageType::ConstPointer    ImageConstPointer;
+        typedef typename ImageType::SizeType        SizeType;
+
+        typedef typename ClassImageType::Pointer    ClassImagePointer;
+        typedef typename ClassImageType::RegionType ClassRegionType;
+
+
+        // Methods
+        itkSTMS_TemporalSetToImageSequence( IndexSampleSetType*   cl,
+                                            SpatialSampleSetType* sp,
+                                            RangeSampleSetType*   ra,
+                                            itkSTMS::ParamsAnalysisOutputType* params,
+                                            itkSTMS::ParserOutputType*         desc   );
+
+        void GenerateImageSequence();
+
+    private:
+        // Attributes
+        itkSTMS::ParserOutputType*         expDescription;
+        itkSTMS::ParamsAnalysisOutputType* stmsParameters;
+
+        IndexSampleSetType*      classSet;
+        SpatialSampleSetType*    spatialSet;
+        RangeSampleSetType*      rangeSet;
+
+    };  // end of class itkSTMS_TemporalSetToImageSequence
+} // end of namespace itkstms
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSTMS_TemporalSetToImageSequence.txx"
+#endif
+
+#endif
diff --git a/Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence.txx b/Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence.txx
new file mode 100755 (executable)
index 0000000..698e3ae
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ #
+ #  File        : itkSTMS_TemporalSetToImageSequence.txx
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_TemporalSetToImageSequence_txx
+#define itkSTMS_TemporalSetToImageSequence_txx
+
+#include "itkSTMS_TemporalSetToImageSequence.h"
+#include "itkSTMS_XMLFileParser.h"
+#include "itkSTMS_ArgumentsAnalysis.h"
+
+namespace itkSTMS
+{
+
+template < class ImageType, class ClassImageType >
+itkSTMS_TemporalSetToImageSequence < ImageType, ClassImageType >
+::itkSTMS_TemporalSetToImageSequence( IndexSampleSetType* cl, SpatialSampleSetType* sp, RangeSampleSetType* ra,
+                                      itkSTMS::ParamsAnalysisOutputType* params, itkSTMS::ParserOutputType* desc )
+{
+    this->stmsParameters = params;
+    this->expDescription = desc;
+
+    this->classSet   = cl;
+    this->spatialSet = sp;
+    this->rangeSet   = ra;
+}
+
+
+template < class ImageType, class ClassImageType >
+void
+itkSTMS_TemporalSetToImageSequence< ImageType, ClassImageType >
+::GenerateImageSequence()
+{
+    bool first = true;
+
+    // Output images allocation
+    ImagePointer image
+            = ImageType::New();
+    ReaderPointer reader
+            = ReaderType::New();
+
+    std::string imagePath = expDescription->experimentPath+expDescription->inputFolder+expDescription->inputCommonRoot+STMS_NUMBERING_FORM_ONE+expDescription->imageExtension;
+
+    reader->SetFileName( imagePath );
+    reader->Update();
+    image = reader->GetOutput();
+
+    SpatialIndexType start, outIndex, classIndex;
+    start.Fill(0);
+
+    RegionType region;
+    region.SetSize( image->GetBufferedRegion().GetSize());
+    region.SetIndex(start);
+
+    ClassRegionType classRegion;
+    classRegion.SetSize( image->GetBufferedRegion().GetSize());
+    classRegion.SetIndex( start );
+
+
+    std::string outputPath, classPath;
+
+    ClassImagePointer classImage
+            = ClassImageType::New();
+
+    classImage->SetRegions( classRegion );
+    classImage->Allocate();
+    classImage->FillBuffer( 15.0 );
+
+
+    classPath = expDescription->experimentPath+expDescription->outputFolder+
+            expDescription->outputCommonRoot+
+            "_Class_X-"+std::to_string((unsigned int)stmsParameters->spScales[0])+
+            "_Y-"+std::to_string((unsigned int)stmsParameters->spScales[1])+
+            "_Z-"+std::to_string((unsigned int)stmsParameters->spScales[2])+
+            "_R-"+std::to_string(stmsParameters->rScale)+"_"+
+            expDescription->outputImageExtension;
+
+    ClassWriterPointer classWriter
+            = ClassWriterType::New();
+    classWriter->SetFileName( classPath );
+
+    // Filetered image sequence and class image saving
+    for( unsigned int i=1 ; i<=stmsParameters->numTimePoints - stmsParameters->startTimePoint + 1; ++i ){
+
+        char buffer[6];
+        int n;
+
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 6 ) n=sprintf (buffer, "%05d", i + stmsParameters->startTimePoint - 1);
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 5 ) n=sprintf (buffer, "%04d", i + stmsParameters->startTimePoint - 1);
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 4 ) n=sprintf (buffer, "%03d", i + stmsParameters->startTimePoint - 1);
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 3 ) n=sprintf (buffer, "%02d", i + stmsParameters->startTimePoint - 1);
+        if( sizeof(STMS_NUMBERING_FORM_ONE) == 2 ) n=sprintf (buffer, "%01d", i + stmsParameters->startTimePoint - 1);
+
+        outputPath = expDescription->experimentPath+expDescription->outputFolder+
+                expDescription->outputCommonRoot+
+                "_X-"+std::to_string((unsigned int)stmsParameters->spScales[0])+
+                "_Y-"+std::to_string((unsigned int)stmsParameters->spScales[1])+
+                "_Z-"+std::to_string((unsigned int)stmsParameters->spScales[2])+
+                "_R-"+std::to_string(stmsParameters->rScale)+"_"+
+                buffer+expDescription->outputImageExtension;
+
+        ImagePointer outImage
+                = ImageType::New();
+
+        outImage->SetRegions( region );
+        outImage->Allocate();
+        outImage->FillBuffer( 15.0 );
+
+        WriterPointer writer
+                = WriterType::New();
+        writer->SetFileName( outputPath );
+
+        //#pragma omp parrallel for ...
+        for(unsigned int j=0 ; j<classSet->size() ; ++j)
+        {
+            for( unsigned int k=0 ; k<stmsParameters->dim ; ++k)
+            {
+                outIndex[k]   = (IndexType)( round(spatialSet->at(j)[k]*stmsParameters->spScales[k]) );
+
+                if( first )
+                    classIndex[k] = outIndex[k];
+            }
+
+            outImage->SetPixel( outIndex, rangeSet->at( classSet->at(j)-1 )[i-1]*stmsParameters->rScale );
+
+            if( first )
+                classImage->SetPixel(classIndex, classSet->at(j));
+        }
+
+        writer->SetInput( outImage );
+        writer->Update();
+
+        if( first )
+        {
+            classWriter->SetInput( classImage );
+            classWriter->Update();
+            first = false;
+        }
+    }
+}
+
+} // end of namespace itkSTMS
+
+#endif
diff --git a/Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence_Spine.h b/Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence_Spine.h
new file mode 100755 (executable)
index 0000000..3ff92d5
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ #
+ #  File        : itkSTMS_TemporalSetToImageSequence_Spine.h
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_TemporalSetToImageSequenceSpine_h
+#define itkSTMS_TemporalSetToImageSequenceSpine_h
+
+#include <string>
+#include <vector>
+#include <math.h>
+
+#include "itkImage.h"
+#include "itkImageFileReader.h"
+#include "itkImageFileWriter.h"
+#include "itkImageRegionIteratorWithIndex.h"
+
+namespace itkSTMS_Spine
+{
+    template < class ImageType, class ClassImageType >
+    class itkSTMS_TemporalSetToImageSequence
+    {
+    public:
+        // Reader and writer typedefs
+        typedef itk::ImageFileReader< ImageType >       ReaderType;
+        typedef typename ReaderType::Pointer            ReaderPointer;
+        typedef itk::ImageFileWriter< ImageType >       WriterType;
+        typedef typename WriterType::Pointer            WriterPointer;
+        typedef itk::ImageFileWriter< ClassImageType >  ClassWriterType;
+        typedef typename ClassWriterType::Pointer       ClassWriterPointer;
+
+        // Sample set typedefs
+        typedef unsigned int                        IndexType;
+        typedef float                               SpatialType;
+        typedef typename ImageType::PixelType       PixelType;
+
+        typedef std::vector< SpatialType >          SpatialVectorType;
+        typedef std::vector< PixelType >            RangeVectorType;
+
+        typedef std::vector< IndexType >            IndexSampleSetType;
+        typedef std::vector< SpatialVectorType >    SpatialSampleSetType;
+        typedef std::vector< RangeVectorType >      RangeSampleSetType;
+
+        // Image typedefs
+        typedef typename ImageType::IndexType       SpatialIndexType;
+        typedef typename ImageType::RegionType      RegionType;
+
+        typedef typename ImageType::Pointer         ImagePointer;
+        typedef typename ImageType::ConstPointer    ImageConstPointer;
+        typedef typename ImageType::SizeType        SizeType;
+
+        typedef typename ClassImageType::Pointer    ClassImagePointer;
+        typedef typename ClassImageType::RegionType ClassRegionType;
+
+
+        // Methods
+        itkSTMS_TemporalSetToImageSequence( IndexSampleSetType*   cl,
+                                            SpatialSampleSetType* sp,
+                                            RangeSampleSetType*   ra,
+                                            itkSTMS_Spine::ParamsAnalysisOutputType* params );
+
+        void GenerateImageSequence();
+
+    private:
+        // Attributes
+        itkSTMS_Spine::ParamsAnalysisOutputType* stmsParameters;
+
+        IndexSampleSetType*      classSet;
+        SpatialSampleSetType*    spatialSet;
+        RangeSampleSetType*      rangeSet;
+
+    };  // end of class itkSTMS_TemporalSetToImageSequence
+} // end of namespace itkstms
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSTMS_TemporalSetToImageSequence_Spine.txx"
+#endif
+
+#endif
diff --git a/Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence_Spine.txx b/Lib/PrePostProcessing/itkSTMS_TemporalSetToImageSequence_Spine.txx
new file mode 100755 (executable)
index 0000000..6b58cbf
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ #
+ #  File        : itkSTMS_TemporalSetToImageSequence_Spine.txx
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_TemporalSetToImageSequenceSpine_txx
+#define itkSTMS_TemporalSetToImageSequenceSpine_txx
+
+#include "itkSTMS_TemporalSetToImageSequence_Spine.h"
+#include "itkSTMS_ArgumentsAnalysis_Spine.h"
+
+namespace itkSTMS_Spine
+{
+
+template < class ImageType, class ClassImageType >
+itkSTMS_TemporalSetToImageSequence < ImageType, ClassImageType >
+::itkSTMS_TemporalSetToImageSequence( IndexSampleSetType* cl, SpatialSampleSetType* sp, RangeSampleSetType* ra,
+                                      itkSTMS_Spine::ParamsAnalysisOutputType* params)
+{
+    this->stmsParameters = params;
+    this->classSet       = cl;
+    this->spatialSet     = sp;
+    this->rangeSet       = ra;
+}
+
+
+template < class ImageType, class ClassImageType >
+void
+itkSTMS_TemporalSetToImageSequence< ImageType, ClassImageType >
+::GenerateImageSequence()
+{
+    bool first = true;
+
+    // Output images allocation
+    ImagePointer image
+            = ImageType::New();
+    ReaderPointer reader
+            = ReaderType::New();
+
+    reader->SetFileName( *stmsParameters->images.begin() );
+    reader->Update();
+    image = reader->GetOutput();
+
+    SpatialIndexType start, outIndex, classIndex;
+    start.Fill(0);
+
+    RegionType region;
+    region.SetSize( image->GetBufferedRegion().GetSize());
+    region.SetIndex(start);
+
+    ClassRegionType classRegion;
+    classRegion.SetSize( image->GetBufferedRegion().GetSize());
+    classRegion.SetIndex( start );
+
+
+    std::string outputPath, classPath;
+
+    ClassImagePointer classImage
+            = ClassImageType::New();
+
+    classImage->SetRegions( classRegion );
+    classImage->Allocate();
+    classImage->FillBuffer( 15.0 );
+
+
+    // Filetered image sequence and class image saving
+    //    for( unsigned int i=1 ; i<=stmsParameters->numTimePoints ; ++i )
+    //    {
+    unsigned int i=1;
+    for (std::list<std::string>::iterator it_images = stmsParameters->images.begin(); it_images != stmsParameters->images.end(); ++it_images)
+    {
+        outputPath = stmsParameters->outFolder+ it_images->substr( it_images->find_last_of("/"), it_images->length()-stmsParameters->imageExtension.length()-it_images->find_last_of("/") ) +
+                "_X-"+std::to_string((unsigned int)stmsParameters->spScales[0])+
+                "_Y-"+std::to_string((unsigned int)stmsParameters->spScales[1])+
+                "_Z-"+std::to_string(stmsParameters->spScales[2])+
+                "_R-"+std::to_string(stmsParameters->rScale)+"_"+
+                std::to_string(i)+stmsParameters->imageExtension;
+
+        ImagePointer outImage
+                = ImageType::New();
+
+        outImage->SetRegions( region );
+        outImage->Allocate();
+        outImage->FillBuffer( 15.0 );
+
+        WriterPointer writer
+                = WriterType::New();
+        writer->SetFileName( outputPath );
+
+        //#pragma omp parrallel for ...
+        for(unsigned int j=0 ; j<classSet->size() ; ++j)
+        {
+            for( unsigned int k=0 ; k<stmsParameters->dim ; ++k)
+            {
+                outIndex[k]   = (IndexType)( round(spatialSet->at(j)[k]*stmsParameters->spScales[k]) );
+
+                if( first )
+                    classIndex[k] = outIndex[k];
+            }
+
+            outImage->SetPixel( outIndex, rangeSet->at( classSet->at(j)-1 )[i-1]*stmsParameters->rScale );
+
+            if( first )
+                classImage->SetPixel(classIndex, classSet->at(j));
+        }
+
+        writer->SetInput( outImage );
+        writer->Update();
+
+        if( first )
+        {
+            classPath = stmsParameters->outFolder +
+                    it_images->substr( it_images->find_last_of("/"), it_images->length()-stmsParameters->imageExtension.length()-it_images->find_last_of("/") ) +
+                    "_Class_X-"+std::to_string((unsigned int)stmsParameters->spScales[0])+
+                    "_Y-"+std::to_string((unsigned int)stmsParameters->spScales[1])+
+                    "_Z-"+std::to_string(stmsParameters->spScales[2])+
+                    "_R-"+std::to_string(stmsParameters->rScale)+"_"+
+                    stmsParameters->imageExtension;
+
+            ClassWriterPointer classWriter
+                    = ClassWriterType::New();
+            classWriter->SetFileName( classPath );
+
+            classWriter->SetInput( classImage );
+            classWriter->Update();
+            first = false;
+        }
+
+        ++i;
+    }
+}
+
+} // end of namespace itkSTMS
+
+#endif
diff --git a/Lib/PrePostProcessing/itkSTMS_XMLFileParser.h b/Lib/PrePostProcessing/itkSTMS_XMLFileParser.h
new file mode 100755 (executable)
index 0000000..0c3589e
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ #
+ #  File        : itkSTMS_XMLFileParser.h
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_XMLFileParser_H
+#define itkSTMS_XMLFileParser_H
+
+#include <string>
+#include "itkDOMNodeXMLReader.h"
+#include "itkFancyString.h"
+
+namespace itkSTMS
+{
+    struct ParserOutputType{
+        std::string  experimentPath;
+        std::string  imageExtension;
+        std::string  outputImageExtension;
+        std::string  inputCommonRoot;
+        std::string  inputFolder;
+        std::string  maskImage;
+        std::string  outputFolder;
+        std::string  outputCommonRoot;
+    };
+
+
+    class itkSTMS_XMLFileParser{
+    public:
+        typedef itk::DOMNodeXMLReader          InputType;
+        typedef typename InputType::Pointer    InputPointer;
+        typedef typename itk::DOMNode::Pointer NodePointer;
+
+        itkSTMS_XMLFileParser();
+        void Update();
+
+        inline void SetFileName(std::string fileName){ this->fileName = fileName; }
+        inline std::string GetFileName(){ return( this->fileName ); }
+        inline ParserOutputType* GetXMLParams(){ return( &xmlParams ); }
+
+    private:
+        ParserOutputType xmlParams;
+        InputPointer     parser;
+        std::string      fileName;
+        NodePointer      DomObject, listInput, listOutput;
+    };
+} // end of namespace itkSTMS
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSTMS_XMLFileParser.hxx"
+#endif
+
+#endif // itkSTMS_XMLFileParser_H
diff --git a/Lib/PrePostProcessing/itkSTMS_XMLFileParser.hxx b/Lib/PrePostProcessing/itkSTMS_XMLFileParser.hxx
new file mode 100755 (executable)
index 0000000..1bb4c27
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ #
+ #  File        : itkSTMS_XMLFileParser.hxx
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_XMLFileParser_HXX
+#define itkSTMS_XMLFileParser_HXX
+
+#include "itkSTMS_XMLFileParser.h"
+
+namespace itkSTMS
+{
+itkSTMS_XMLFileParser::itkSTMS_XMLFileParser()
+{
+    xmlParams.experimentPath     = "";
+    xmlParams.imageExtension     = "";
+    xmlParams.outputImageExtension = "";
+    xmlParams.inputCommonRoot    = "";
+    xmlParams.inputFolder        = "";
+    xmlParams.maskImage          = "";
+    xmlParams.outputFolder       = "";
+    xmlParams.outputCommonRoot   = "";
+}
+
+
+void itkSTMS_XMLFileParser::Update()
+{
+    parser = InputType::New();
+    parser->SetFileName( this->fileName );
+    parser->Update();
+
+    DomObject = parser->GetOutput();
+    if ( DomObject->GetName() != "STMS_ProcessInfo" )
+    {
+        std::cout << std::endl << std::endl <<  "Unrecognized input XML document! STMS_ProcessInfo expected" << std::endl << std::endl;
+        std::exit( EXIT_FAILURE );
+    }
+
+    // Read common parameters
+    xmlParams.experimentPath = DomObject->GetAttribute( "experimentPath" );
+    if ( xmlParams.experimentPath == "" )
+    {
+        std::cout << std::endl << std::endl <<  "experimentPath not found" << std::endl << std::endl;
+        std::exit( EXIT_FAILURE );
+    }
+
+    xmlParams.imageExtension = DomObject->GetAttribute( "imageExtension" );
+    if ( xmlParams.imageExtension == "" )
+    {
+        std::cout << std::endl << std::endl <<  "imageExtension not found" << std::endl << std::endl;
+        std::exit( EXIT_FAILURE );
+    }
+
+    xmlParams.outputImageExtension = DomObject->GetAttribute( "outputImageExtension" );
+    if ( xmlParams.outputImageExtension == "" )
+    {
+        std::cout << std::endl << std::endl <<  "outputImageExtension not found" << std::endl << std::endl;
+        std::exit( EXIT_FAILURE );
+    }
+
+    // Read input parameters
+    listInput = DomObject->GetChild( "listInput" );
+    xmlParams.inputFolder = listInput->GetAttribute( "inputFolder" );
+    if ( xmlParams.inputFolder == "" )
+    {
+        std::cout << std::endl << std::endl <<  "inputFolder not found" << std::endl << std::endl;
+        std::exit( EXIT_FAILURE );
+    }
+
+    xmlParams.inputCommonRoot = listInput->GetAttribute( "commonRoot" );
+    if ( xmlParams.inputCommonRoot == "" )
+    {
+        std::cout << std::endl << std::endl <<  "inputCommonRoot not found" << std::endl << std::endl;
+        std::exit( EXIT_FAILURE );
+    }
+
+    xmlParams.maskImage = listInput->GetAttribute( "maskImage" );
+    if ( xmlParams.maskImage == "" )
+    {
+        std::cout << std::endl << std::endl <<  "maskImage not found" << std::endl << std::endl;
+        std::exit( EXIT_FAILURE );
+    }
+
+    // Read output parameters
+    listOutput = DomObject->GetChild( "listOutput" );
+    xmlParams.outputFolder = listOutput->GetAttribute( "outputFolder" );
+    if ( xmlParams.outputFolder == "" )
+    {
+        std::cout << std::endl << std::endl <<  "outputFolder not found" << std::endl << std::endl;
+        std::exit( EXIT_FAILURE );
+    }
+
+    xmlParams.outputCommonRoot = listOutput->GetAttribute( "commonRoot" );
+    if ( xmlParams.outputCommonRoot == "" )
+    {
+        std::cout << std::endl << std::endl <<  "outputCommonRoot not found" << std::endl << std::endl;
+        std::exit( EXIT_FAILURE );
+    }
+}
+} // end of namespace itkSTMS
+#endif // itkSTMS_XMLFileParser_HXX
diff --git a/Lib/SpatioTemporalMeanShift/CMakeLists.txt b/Lib/SpatioTemporalMeanShift/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..c5ed43e
--- /dev/null
@@ -0,0 +1,87 @@
+#----------------------------------------------------------------------------
+# USER! : SET THE NAME OF YOUR LIBRARY
+# (Replace 'MyLib' by your own library name)
+
+#############################
+SET ( LIBRARY_NAME   SpatioTemporalMeanShift )
+#############################
+
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES A USER OPTION IN CMAKE
+OPTION ( BUILD_${LIBRARY_NAME}  "Build ${LIBRARY_NAME} library ?" ON)
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+IF ( BUILD_${LIBRARY_NAME} )
+#----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # BUILD LIBRARY
+  #----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # LIBRARY HEADERS (TO BE INSTALLED)
+  # EITHER LIST ALL .h, *.txx IN CURRENT DIR USING NEXT LINE:
+
+  FILE(GLOB ${LIBRARY_NAME}_HEADERS "*.h" "*.txx")
+  
+  # OR MANUALLY LIST YOUR HEADERS WITH NEXT COMMAND
+  #  SET ( ${LIBRARY_NAME}_HEADERS
+  #
+  #      )
+  #----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # LIBRARY SOURCES (TO BE COMPILED)
+  # EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+
+  FILE(GLOB ${LIBRARY_NAME}_SOURCES *.cxx *.cpp *.cc ${${LIBRARY_NAME}_HEADERS})
+
+  # OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+  #  SET ( ${LIBRARY_NAME}_SOURCES 
+  #   
+  #      )
+  #----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # LIBRARY DEPENDENCIES (LIBRARIES TO LINK WITH)
+  #
+  # USER! : Uncomment the Libraries you need
+  #
+  SET ( ${LIBRARY_NAME}_LINK_LIBRARIES
+  #    ${crea_LIBRARIES}
+  #    ${WXWIDGETS_LIBRARIES}
+  #    ${KWWidgets_LIBRARIES}
+  #    ${VTK_LIBRARIES}
+  #    ${ITK_LIBRARIES}
+  #    ${GDCM_LIBRARIES}
+  #    ${BOOST_LIBRARIES}
+
+  # If this library must link against other libraries 
+  # USER! : Add here any extra Library you need
+
+      )
+  #----------------------------------------------------------------------------
+
+  #----------------------------------------------------------------------------
+  # MACRO WHICH DOES ALL THE JOB : BUILD AND INSTALL
+
+  # USER! : The default is to create a Dynamic Library.
+  # if you need to create a static library
+  # comment out the following line :
+
+  #CREA_ADD_LIBRARY( ${LIBRARY_NAME} )
+
+  # and uncomment the 2 lines hereafter:
+
+   ADD_LIBRARY(${LIBRARY_NAME} STATIC  ${${LIBRARY_NAME}_SOURCES})
+   TARGET_LINK_LIBRARIES(${LIBRARY_NAME} ${${LIBRARY_NAME}_LINK_LIBRARIES} )
+   SET_TARGET_PROPERTIES(${LIBRARY_NAME} PROPERTIES LINKER_LANGUAGE C)
+
+  #
+  #----------------------------------------------------------------------------
+
+  #---------------------------------------------------------------------------
+ENDIF ( BUILD_${LIBRARY_NAME} )
diff --git a/Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS.h b/Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS.h
new file mode 100755 (executable)
index 0000000..6810349
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ #
+ #  File        : itkSTMS_BlurringSTMS.h
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_BlurringSTMS_H
+#define itkSTMS_BlurringSTMS_H
+
+#include "itkSTMS_ArgumentsAnalysis.h"
+#include "itkSTMS_ImageSequenceToTemporalSet.h"
+#include "itkImageFileReader.h"
+
+#ifndef STMS_NUMBERING_FORM_ONE
+#define STMS_NUMBERING_FORM_ONE "1"
+#endif
+
+namespace itkSTMS
+{
+    template < class IndexType, class SpatialType, class PixelType, class ImageType>
+    class itkSTMS_BlurringSTMS
+    {
+    public:
+
+        typedef itkSTMS::ParamsAnalysisOutputType ParametersType;
+
+        // Sample set typedefs
+        typedef std::vector< SpatialType >        SpatialVectorType;
+        typedef std::vector< PixelType >          RangeVectorType;
+
+        typedef std::vector< IndexType >          IndexSampleSetType;
+        typedef std::vector< SpatialVectorType >  SpatialSampleSetType;
+        typedef std::vector< RangeVectorType >    RangeSampleSetType;
+
+        typedef typename ImageType::Pointer       ImagePointer;
+        typedef itk::ImageFileReader<ImageType>   ReaderType;
+        typedef typename ReaderType::Pointer      ReaderPointer;
+
+        // Image typedefs
+        typedef typename ImageType::IndexType     ImageIndexType;
+        typedef std::vector<ImageIndexType>       ImageIndexSetType;
+
+        // Methods
+        itkSTMS_BlurringSTMS( IndexSampleSetType*   idx,
+                              IndexSampleSetType*   cla,
+                              IndexSampleSetType*   wei,
+                              SpatialSampleSetType* sp,
+                              RangeSampleSetType*   ra,
+                              ParametersType*       params,
+                              ParserOutputType*     desc   );
+
+        inline ~itkSTMS_BlurringSTMS(){ delete classSetMemory;
+                                        delete spatialSetMemory; }
+
+        inline IndexSampleSetType*   GetIndexSet       (){ return indexSet;         }
+        inline IndexSampleSetType*   GetClassSet       (){ return classSet;         }
+        inline IndexSampleSetType*   GetWeightsSet     (){ return weightsSet;       }
+        inline SpatialSampleSetType* GetSpatialSet     (){ return spatialSet;       }
+        inline RangeSampleSetType*   GetRangeSet       (){ return rangeSet;         }
+        inline IndexSampleSetType*   GetClassMemory    (){ return classSetMemory;   }
+        inline SpatialSampleSetType* GetSpatialMemory  (){ return spatialSetMemory; }
+
+        void GenerateData();
+        void NoMergeSTMSFiltering();
+        void ClassificationNoMergeSTMSFiltering();
+        void MergeSTMSFiltering();
+        void MergeSamples();
+        void FinalMerging();
+
+        template<class T> void VectorDistance(float &dist, std::vector< T > &a, std::vector< T > &b);
+        void InfiniteNorm  (bool  &dist, RangeVectorType &a, RangeVectorType &b);
+        void MergeInfiniteNorm(bool &dist, RangeVectorType &a, RangeVectorType &b);
+
+        template<class T> void VectorWeightedMean(std::vector<T> &a, unsigned int &a_w, std::vector<T> &b, unsigned int &b_w);
+        template<class T> void VectorWeightedAcc(std::vector<T> &a, std::vector<T> &b, unsigned int &b_w);
+        template<class T> void VectorWeightedAcc(std::vector<T> &a, unsigned int &a_w, std::vector<T> &b, unsigned int &b_w);
+        template<class T> void VectorMul(std::vector<T> &a, unsigned int &coeff);
+        template<class T> void VectorDiv(std::vector<T> &a, unsigned int &coeff);
+        template<class T> void VectorAcc(std::vector<T> &a, std::vector<T> &b);
+
+    private:
+        // Attributes
+        float mergeFactor;
+
+        ParametersType*        stmsParams;
+        ParserOutputType*      expDescription;
+
+        IndexSampleSetType*    classSetMemory;
+        SpatialSampleSetType*  spatialSetMemory;
+        IndexSampleSetType*    indexSet;
+        IndexSampleSetType*    classSet;
+        IndexSampleSetType*    weightsSet;
+        SpatialSampleSetType*  spatialSet;
+        RangeSampleSetType *   rangeSet;
+    };
+
+} // end of namespace itkSTMS
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSTMS_BlurringSTMS.txx"
+#endif
+
+#endif // itkSTMS_BlurringSTMS_H
diff --git a/Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS.txx b/Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS.txx
new file mode 100755 (executable)
index 0000000..8dda232
--- /dev/null
@@ -0,0 +1,936 @@
+/*
+ #
+ #  File        : itkSTMS_BlurringSTMS.txx
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_BlurringSTMS_TXX
+#define itkSTMS_BlurringSTMS_TXX
+
+#include <random>
+#include <algorithm>
+#include <iterator>
+#include "itkSTMS_BlurringSTMS.h"
+#include "itkSTMS_XMLFileParser.h"
+
+
+double gettime()
+{
+    struct timespec timestamp;
+
+    clock_gettime(CLOCK_REALTIME, &timestamp);
+    return timestamp.tv_sec * 1000.0 + timestamp.tv_nsec * 1.0e-6;
+}
+
+
+namespace itkSTMS
+{
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::itkSTMS_BlurringSTMS( IndexSampleSetType* idx, IndexSampleSetType* cla, IndexSampleSetType* wei,
+                        SpatialSampleSetType* sp, RangeSampleSetType* ra, ParametersType* params, ParserOutputType* desc)
+{
+    this->indexSet   = idx;
+    this->classSet   = cla;
+    this->weightsSet = wei;
+    this->spatialSet = sp;
+    this->rangeSet   = ra;
+
+    this->classSetMemory   = new IndexSampleSetType  (  *this->classSet  );
+    this->spatialSetMemory = new SpatialSampleSetType( *this->spatialSet );
+
+    this->stmsParams     = params;
+    this->expDescription = desc;
+
+    this->mergeFactor = 1000;
+}
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::GenerateData()
+{
+    double dtime;
+
+    if( !stmsParams->merge )
+    {
+        std::cout<< std::endl<<"No merge Filtering!"<<std::endl<<"numSamples: "<< indexSet->size() <<std::endl<< std::endl;
+        NoMergeSTMSFiltering();
+
+        dtime=gettime();
+        ClassificationNoMergeSTMSFiltering();
+        dtime = gettime()-dtime;
+        std::cout<< std::endl<<"Classif: " << dtime/1000 << " s" <<std::endl;
+        FinalMerging();
+    }
+    else
+    {
+        std::cout<<std::endl<<"Merge Filtering!"<<std::endl<<"numSamples: "<< indexSet->size() <<std::endl<< std::endl;
+        MergeSTMSFiltering();
+        FinalMerging();
+        //        ClassificationNoMergeSTMSFiltering();
+    }
+}
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::ClassificationNoMergeSTMSFiltering()
+{
+
+    IndexSampleSetType*   newClassSet
+            = new IndexSampleSetType();
+    newClassSet->reserve  ( indexSet->size() );
+
+    IndexSampleSetType*   newWeightsSet
+            = new IndexSampleSetType();
+    newWeightsSet->reserve( indexSet->size() );
+
+    IndexSampleSetType*   newIndexSet
+            = new IndexSampleSetType();
+    newIndexSet->reserve  ( indexSet->size() );
+
+    SpatialSampleSetType* newSpatialSet
+            = new SpatialSampleSetType();
+
+    newSpatialSet->reserve( indexSet->size() );
+
+    RangeSampleSetType*   newRangeSet
+            = new RangeSampleSetType();
+    newRangeSet->reserve  ( indexSet->size() );
+
+
+    newClassSet->push_back  ( 1 );
+    newWeightsSet->push_back( 1 );
+    newIndexSet->push_back  ( indexSet->at(0)   );
+    newSpatialSet->push_back( spatialSet->at(0) );
+    newRangeSet->push_back  ( rangeSet->at(0)   );
+    classSetMemory->at( indexSet->at(0) ) = newClassSet->at(0);
+
+
+    unsigned int k;
+    bool newC;
+    float spDist;
+    bool  raNorm;
+
+    for(unsigned int i=1 ; i<indexSet->size() ; ++i)
+    {
+        newC = true;
+        k=0;
+
+        while( (k<newClassSet->size()) && newC )
+        {
+            VectorDistance( spDist, newSpatialSet->at(k), spatialSet->at(i) );
+            if( spDist<=1 )
+            {
+                InfiniteNorm( raNorm, newRangeSet->at(k), rangeSet->at(i) );
+                if( raNorm )
+                {
+                    VectorWeightedMean( newSpatialSet->at(k), newWeightsSet->at(k), spatialSet->at(i), weightsSet->at(i) );
+                    VectorWeightedMean( newRangeSet->at(k)  , newWeightsSet->at(k), rangeSet->at(i)  , weightsSet->at(i) );
+
+                    classSetMemory->at( indexSet->at(i) ) = newClassSet->at(k);
+                    newC = false;
+                }
+                else
+                    ++k;
+            }
+            else
+                ++k;
+        }
+
+        if( newC )
+        {
+            newClassSet->push_back( (IndexType)newClassSet->back()+1 );
+            newWeightsSet->push_back( 1 );
+            newIndexSet->push_back  ( indexSet->at(i)   );
+            newSpatialSet->push_back( spatialSet->at(i) );
+            newRangeSet->push_back  ( rangeSet->at(i)   );
+            classSetMemory->at( indexSet->at(i) ) = newClassSet->back();
+        }
+    }
+
+    classSet->swap  ( *newClassSet   );
+    weightsSet->swap( *newWeightsSet );
+    indexSet->swap  ( *newIndexSet   );
+    spatialSet->swap( *newSpatialSet );
+    rangeSet->swap  ( *newRangeSet   );
+
+    delete newClassSet;
+    delete newWeightsSet;
+    delete newIndexSet;
+    delete newSpatialSet;
+    delete newRangeSet;
+}
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::NoMergeSTMSFiltering()
+{
+
+    SpatialSampleSetType* newSpatialSet
+            = new SpatialSampleSetType( indexSet->size(), SpatialVectorType(stmsParams->dim, 0) );
+    RangeSampleSetType*   newRangeSet
+            = new RangeSampleSetType( indexSet->size(), RangeVectorType(stmsParams->numTimePoints, 0) );
+
+    float globalEvolution = INFINITY;
+    float epsilon = (stmsParams->epsilon)*(stmsParams->epsilon);
+    float spDist, raDist;
+    bool  raNorm;
+    unsigned int iter = 0;
+
+    double dtime;
+    while( (globalEvolution>epsilon) & (iter<stmsParams->maxIt) )
+    {
+        dtime=gettime();
+        globalEvolution = 0.0;
+
+        #pragma omp parallel for reduction(+:globalEvolution) private(spDist, raDist, raNorm)
+        for(unsigned int i=0 ; i<indexSet->size() ; ++i)
+        {
+            unsigned int count = 0;
+            SpatialVectorType tmpSpatial( stmsParams->dim, 0 );
+            RangeVectorType   tmpRange  ( stmsParams->numTimePoints, 0 );
+
+            for(unsigned int j=0 ; j<indexSet->size() ; ++j)
+            {
+                VectorDistance( spDist, spatialSet->at(i), spatialSet->at(j));
+
+                if( spDist<=1 )
+                {
+                    InfiniteNorm(raNorm, rangeSet->at(i), rangeSet->at(j));
+
+                    if( raNorm )
+                    {
+                        VectorAcc( tmpSpatial, spatialSet->at(j) );
+                        VectorAcc( tmpRange  , rangeSet->at(j)   );
+
+                        ++count;
+                    }
+                }
+            }
+
+            if( count>1 )
+            {
+                VectorDiv( tmpSpatial, count );
+                VectorDiv( tmpRange  , count );
+            }
+
+            VectorDistance(spDist, spatialSet->at(i), tmpSpatial);
+            VectorDistance(raDist, rangeSet->at(i), tmpRange);
+
+            globalEvolution += (spDist+raDist);
+
+            #pragma omp critical
+            {
+                newSpatialSet->at(i) = tmpSpatial;
+                newRangeSet->at(i)   = tmpRange;
+            }
+        }
+
+        spatialSet->swap( *newSpatialSet );
+        rangeSet->swap  (  *newRangeSet  );
+
+        ++iter;
+        dtime = gettime()-dtime;
+        std::cout<< "Iter: " << iter <<"   "<< dtime/1000 << " s" <<"    GE: "<< globalEvolution <<std::endl;
+    }
+
+    delete newSpatialSet;
+    delete newRangeSet;
+}
+
+
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::MergeSTMSFiltering()
+{
+
+    float globalEvolution = INFINITY;
+    float epsilon = (stmsParams->epsilon)*(stmsParams->epsilon);
+    float spDist, raDist;
+    bool  raNorm, mergeNorm;
+    unsigned int iter = 0;
+    unsigned int merging;
+
+    double dtime;
+    while( (globalEvolution>epsilon) & (iter<stmsParams->maxIt) )
+    {
+        SpatialSampleSetType* newSpatialSet
+                = new SpatialSampleSetType( *spatialSet );
+        RangeSampleSetType*   newRangeSet
+                = new RangeSampleSetType  (  *rangeSet  );
+
+        dtime=gettime();
+        globalEvolution = 0.0;
+        merging = 0;
+
+        #pragma omp parallel for reduction(+:globalEvolution, merging) private(spDist, raDist, raNorm, mergeNorm)
+        for(unsigned int i=0 ; i<indexSet->size() ; ++i)
+        {
+            unsigned int weight = 0;
+            bool merge = false;
+            SpatialVectorType tmpSpatial( stmsParams->dim, 0 );
+            RangeVectorType   tmpRange  ( stmsParams->numTimePoints, 0 );
+
+            for(unsigned int j=0 ; j<indexSet->size() ; ++j)
+            {
+                VectorDistance( spDist, spatialSet->at(i), spatialSet->at(j));
+
+                if( spDist<=1 )
+                {
+                    InfiniteNorm(raNorm, rangeSet->at(i), rangeSet->at(j));
+
+                    if( raNorm )
+                    {
+                        VectorWeightedAcc(tmpSpatial, spatialSet->at(j), weightsSet->at(j));
+                        VectorWeightedAcc(tmpRange  , rangeSet->at(j)  , weightsSet->at(j));
+
+                        weight += weightsSet->at(j);
+
+                        MergeInfiniteNorm(mergeNorm, rangeSet->at(i), rangeSet->at(j));
+                        if( (spDist <= (1/mergeFactor)) && mergeNorm )
+                            merge = true;
+                    }
+                }
+            }
+
+            if(weight > weightsSet->at(i))
+            {
+                if( merge )
+                    merging += 1;
+                else
+                    merge = 0;
+            }
+            else
+                merge = 0;
+
+
+            VectorDiv( tmpSpatial, weight );
+            VectorDiv( tmpRange  , weight );
+
+            #pragma omp critical
+            {
+                newSpatialSet->at(i) = tmpSpatial;
+                newRangeSet->at(i)   = tmpRange;
+            }
+
+            VectorDistance(spDist, spatialSet->at(i), tmpSpatial);
+            VectorDistance(raDist, rangeSet->at(i), tmpRange);
+
+            globalEvolution += (spDist+raDist);
+        }
+
+        spatialSet->swap( *newSpatialSet );
+        rangeSet->swap  (  *newRangeSet  );
+
+        delete newSpatialSet;
+        delete newRangeSet;
+
+        if(merging > 0)
+            MergeSamples();
+
+        ++iter;
+        dtime = gettime()-dtime;
+        std::cout<< "Iter: " << iter <<"   "<< dtime/1000 << " s" <<"    GE: "<< globalEvolution << "      numSamples: "<< classSet->size() <<std::endl;
+    }
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::MergeSamples()
+{
+
+    IndexSampleSetType*   newClassSet
+            = new IndexSampleSetType();
+    newClassSet->reserve  ( indexSet->size() );
+
+    IndexSampleSetType*   newWeightsSet
+            = new IndexSampleSetType();
+    newWeightsSet->reserve( indexSet->size() );
+
+    IndexSampleSetType*   newIndexSet
+            = new IndexSampleSetType();
+    newIndexSet->reserve  ( indexSet->size() );
+
+    SpatialSampleSetType* newSpatialSet
+            = new SpatialSampleSetType();
+
+    newSpatialSet->reserve( indexSet->size() );
+
+    RangeSampleSetType*   newRangeSet
+            = new RangeSampleSetType();
+    newRangeSet->reserve  ( indexSet->size() );
+
+    IndexSampleSetType* newClassSetMemory
+            = new IndexSampleSetType( *classSetMemory );
+
+    IndexSampleSetType*   indexes
+            = new IndexSampleSetType( *classSet );
+
+    std::random_device rd;
+    std::mt19937 g(rd());
+
+    std::shuffle(indexes->begin(), indexes->end(), g);
+
+
+    newClassSet->push_back  ( 1 );
+    newWeightsSet->push_back( weightsSet->at( indexes->at(0)-1 ) );
+    newIndexSet->push_back  ( indexSet->at  ( indexes->at(0)-1 ) );
+    newSpatialSet->push_back( spatialSet->at( indexes->at(0)-1 ) );
+    newRangeSet->push_back  ( rangeSet->at  ( indexes->at(0)-1 ) );
+
+    for(unsigned int l=0 ; l< classSetMemory->size() ; ++l)
+    {
+        if(classSetMemory->at(l) == classSet->at(indexes->at(0)-1))
+            newClassSetMemory->at(l) = 1;
+    }
+
+    unsigned int k;
+    bool newC;
+    float spDist;
+    bool  raNorm;
+    unsigned int i;
+
+    for(unsigned int m=1 ; m<indexes->size() ; ++m)
+    {
+        i = indexes->at(m)-1;
+
+        newC = true;
+        k=0;
+
+        while( (k<newClassSet->size()) && newC )
+        {
+            VectorDistance( spDist, newSpatialSet->at(k), spatialSet->at(i) );
+            MergeInfiniteNorm( raNorm, newRangeSet->at(k), rangeSet->at(i) );
+            if( (spDist<=1/mergeFactor)&&raNorm )
+            {
+                VectorWeightedAcc( newSpatialSet->at(k), newWeightsSet->at(k), spatialSet->at(i), weightsSet->at(i) );
+                VectorWeightedAcc( newRangeSet->at(k)  , newWeightsSet->at(k), rangeSet->at(i)  , weightsSet->at(i) );
+
+                newWeightsSet->at(k) += weightsSet->at(i);
+
+                VectorDiv(newSpatialSet->at(k), newWeightsSet->at(k));
+                VectorDiv(newRangeSet->at(k), newWeightsSet->at(k));
+
+                for(unsigned int l=0 ; l<classSetMemory->size() ; ++l)
+                {
+                    if(classSetMemory->at(l) == classSet->at(i))
+                        newClassSetMemory->at(l) = newClassSet->at(k);
+                }
+
+                newC = false;
+            }
+            else
+                ++k;
+        }
+
+        if( newC )
+        {
+            newClassSet->push_back( newClassSet->back()+1 );
+            newWeightsSet->push_back( weightsSet->at(i) );
+            newIndexSet->push_back  ( indexSet->at(i)   );
+            newSpatialSet->push_back( spatialSet->at(i) );
+            newRangeSet->push_back  ( rangeSet->at(i)   );
+
+            for(unsigned int l=0 ; l< classSetMemory->size() ; ++l)
+            {
+                if(classSetMemory->at(l) == classSet->at(i))
+                    newClassSetMemory->at(l) = newClassSet->back();
+            }
+        }
+    }
+
+    classSet->swap  ( *newClassSet   );
+    weightsSet->swap( *newWeightsSet );
+    indexSet->swap  ( *newIndexSet   );
+    spatialSet->swap( *newSpatialSet );
+    rangeSet->swap  ( *newRangeSet   );
+    classSetMemory->swap  ( *newClassSetMemory );
+
+    delete newClassSet;
+    delete newWeightsSet;
+    delete newIndexSet;
+    delete newSpatialSet;
+    delete newRangeSet;
+    delete newClassSetMemory;
+    delete indexes;
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::FinalMerging()
+{
+    unsigned int size = INFINITY;
+    std::string imagePath = expDescription->experimentPath+expDescription->inputFolder+expDescription->inputCommonRoot+STMS_NUMBERING_FORM_ONE+expDescription->imageExtension;
+
+    while(size > classSet->size()){
+        IndexSampleSetType*   newClassSet
+                = new IndexSampleSetType();
+        newClassSet->reserve  ( indexSet->size() );
+
+        IndexSampleSetType*   newWeightsSet
+                = new IndexSampleSetType();
+        newWeightsSet->reserve( indexSet->size() );
+
+        IndexSampleSetType*   newIndexSet
+                = new IndexSampleSetType();
+        newIndexSet->reserve  ( indexSet->size() );
+
+        SpatialSampleSetType* newSpatialSet
+                = new SpatialSampleSetType();
+
+        newSpatialSet->reserve( indexSet->size() );
+
+        RangeSampleSetType*   newRangeSet
+                = new RangeSampleSetType();
+        newRangeSet->reserve  ( indexSet->size() );
+
+        IndexSampleSetType* newClassSetMemory
+                = new IndexSampleSetType( *classSetMemory );
+
+        newClassSet->push_back  ( 1 );
+        newWeightsSet->push_back( 1 );
+        newIndexSet->push_back  ( indexSet->at(0)   );
+        newSpatialSet->push_back( spatialSet->at(0) );
+        newRangeSet->push_back  ( rangeSet->at(0)   );
+
+        unsigned int k;
+        bool newC;
+        bool  raNorm;
+
+        for(unsigned int i=1 ; i<classSet->size() ; ++i)
+        {
+            newC = true;
+            k=0;
+
+            while( (k<newClassSet->size()) && newC )
+            {
+                InfiniteNorm( raNorm, newRangeSet->at(k), rangeSet->at(i) );
+                if( raNorm ){
+
+                    ReaderPointer reader = ReaderType::New();
+                    ImagePointer image = ImageType::New();
+
+                    reader->SetFileName( imagePath );
+                    reader->Update();
+                    image = reader->GetOutput();
+                    image->FillBuffer( 0 );
+
+                    ImageIndexSetType* refClass  = new ImageIndexSetType();
+                    ImageIndexSetType* candClass = new ImageIndexSetType();
+                    refClass->reserve( classSet->size()/2 );
+                    candClass->reserve( classSet->size()/2 );
+
+
+                    for(unsigned int m=0 ; m<newClassSetMemory->size() ; ++m)
+                    {
+                        ImageIndexType idx;
+                        if(newClassSetMemory->at(m) == classSet->at(i)){
+
+                            #pragma omp simd
+                            for(unsigned int n=0 ; n<stmsParams->dim ; ++n)
+                                idx[n] = spatialSetMemory->at(m)[n]*stmsParams->spScales[n];
+
+                            candClass->push_back( idx );
+                            image->SetPixel(candClass->back(), 1);
+                        }
+                        else
+                        {
+                            if(newClassSetMemory->at(m) == newClassSet->at(k)){
+
+                                #pragma omp simd
+                                for(unsigned int n=0 ; n<stmsParams->dim ; ++n)
+                                    idx[n] = spatialSetMemory->at(m)[n]*stmsParams->spScales[n];
+
+                                refClass->push_back( idx );
+                                image->SetPixel(refClass->back(), 2);
+                            }
+                        }
+                    }
+
+                    bool connex = false;
+                    if(stmsParams->dim == 2)
+                    {
+                        if(refClass->size() < candClass->size())
+                        {
+                            unsigned int m=0;
+                            ImageIndexType idx;
+                            while((m<refClass->size()) && !connex)
+                            {
+                                for(int x=-1 ; x<=1 ; ++x)
+                                {
+                                    for(int y=-1 ; y<=1 ; ++y)
+                                    {
+                                        idx[0] = refClass->at(m)[0]+x;
+                                        idx[1] = refClass->at(m)[1]+y;
+
+                                        if(idx[0]<image->GetBufferedRegion().GetSize()[0] && idx[0]>0 && idx[1]<image->GetBufferedRegion().GetSize()[1] && idx[1]>0)
+                                        {
+                                            if(image->GetPixel(idx) == 2)
+                                            {
+                                                connex = true;
+                                                x = 2;
+                                                y = 2;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                ++m;
+                            }
+                        }
+                        else
+                        {
+                            unsigned int m=0;
+                            ImageIndexType idx;
+                            while((m<candClass->size()) && !connex)
+                            {
+                                for(int x=-1 ; x<=1 ; ++x)
+                                {
+                                    for(int y=-1 ; y<=1 ; ++y)
+                                    {
+                                        idx[0] = candClass->at(m)[0]+x;
+                                        idx[1] = candClass->at(m)[1]+y;
+
+                                        if(idx[0]<image->GetBufferedRegion().GetSize()[0] && idx[0]>0 && idx[1]<image->GetBufferedRegion().GetSize()[1] && idx[1]>0)
+                                        {
+                                            if(image->GetPixel(idx) == 1)
+                                            {
+                                                connex = true;
+                                                x = 2;
+                                                y = 2;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                ++m;
+                            }
+                        }
+
+                    }
+                    else
+                    {
+                        if(refClass->size() < candClass->size())
+                        {
+                            unsigned int m=0;
+                            ImageIndexType idx;
+                            while((m<refClass->size()) && !connex)
+                            {
+                                for(int x=-1 ; x<=1 ; ++x)
+                                {
+                                    for(int y=-1 ; y<=1 ; ++y)
+                                    {
+                                        for(int z=-1 ; z<=1 ; ++z)
+                                        {
+                                            idx[0] = refClass->at(m)[0]+x;
+                                            idx[1] = refClass->at(m)[1]+y;
+                                            idx[2] = refClass->at(m)[2]+z;
+
+                                            if(idx[0]<image->GetBufferedRegion().GetSize()[0] && idx[0]>0 && idx[1]<image->GetBufferedRegion().GetSize()[1] && idx[1]>0 && idx[2]<image->GetBufferedRegion().GetSize()[2] && idx[2]>0)
+                                            {
+                                                if(image->GetPixel(idx) == 2)
+                                                {
+                                                    connex = true;
+                                                    x = 2;
+                                                    y = 2;
+                                                    z = 2;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+
+                                ++m;
+                            }
+                        }
+                        else
+                        {
+                            unsigned int m=0;
+                            ImageIndexType idx;
+                            while((m<candClass->size()) && !connex)
+                            {
+                                for(int x=-1 ; x<=1 ; ++x)
+                                {
+                                    for(int y=-1 ; y<=1 ; ++y)
+                                    {
+                                        for(int z=-1 ; z<=1 ; ++z)
+                                        {
+                                            idx[0] = candClass->at(m)[0]+x;
+                                            idx[1] = candClass->at(m)[1]+y;
+                                            idx[2] = candClass->at(m)[2]+z;
+
+                                            if(idx[0]<image->GetBufferedRegion().GetSize()[0] && idx[0]>0 && idx[1]<image->GetBufferedRegion().GetSize()[1] && idx[1]>0 && idx[2]<image->GetBufferedRegion().GetSize()[2] && idx[2]>0)
+                                            {
+                                                if(image->GetPixel(idx) == 1)
+                                                {
+                                                    connex = true;
+                                                    x = 2;
+                                                    y = 2;
+                                                    z = 2;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+
+                                ++m;
+                            }
+                        }
+                    }
+
+                    if( connex )
+                    {
+
+                        VectorWeightedAcc( newSpatialSet->at(k), newWeightsSet->at(k), spatialSet->at(i), weightsSet->at(i) );
+                        VectorWeightedAcc( newRangeSet->at(k)  , newWeightsSet->at(k), rangeSet->at(i)  , weightsSet->at(i) );
+
+                        newWeightsSet->at(k) += weightsSet->at(i);
+
+                        VectorDiv(newSpatialSet->at(k), newWeightsSet->at(k));
+                        VectorDiv(newRangeSet->at(k), newWeightsSet->at(k));
+
+                        for(unsigned int l=0 ; l< classSetMemory->size() ; ++l)
+                        {
+
+                            if(classSetMemory->at(l) == classSet->at(i))
+                                newClassSetMemory->at(l) = newClassSet->at(k);
+                        }
+
+                        newC = false;
+                    }
+                    else
+                        ++k;
+
+                    delete refClass;
+                    delete candClass;
+                }
+                else
+                    ++k;
+            }
+
+            if( newC )
+            {
+                newClassSet->push_back( newClassSet->back()+1 );
+                newWeightsSet->push_back( weightsSet->at(i) );
+                newIndexSet->push_back  ( indexSet->at(i)   );
+                newSpatialSet->push_back( spatialSet->at(i) );
+                newRangeSet->push_back  ( rangeSet->at(i)   );
+
+                for(unsigned int l=0 ; l< classSetMemory->size() ; ++l)
+                {
+                    if(classSetMemory->at(l) == classSet->at(i))
+                        newClassSetMemory->at(l) = newClassSet->back();
+                }
+            }
+        }
+
+        size = classSet->size();
+
+        classSet->swap  ( *newClassSet   );
+        weightsSet->swap( *newWeightsSet );
+        indexSet->swap  ( *newIndexSet   );
+        spatialSet->swap( *newSpatialSet );
+        rangeSet->swap  ( *newRangeSet   );
+        classSetMemory->swap  ( *newClassSetMemory );
+
+        delete newClassSet;
+        delete newWeightsSet;
+        delete newIndexSet;
+        delete newSpatialSet;
+        delete newRangeSet;
+        delete newClassSetMemory;
+    }
+}
+
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorDistance(float &dist, std::vector<T> &a, std::vector<T> &b)
+{
+    dist = 0.0;
+
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        dist += ( a[i]-b[i] )*( a[i]-b[i] );
+}
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::InfiniteNorm(bool &dist, RangeVectorType &a, RangeVectorType &b)
+{
+    dist = true;
+
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+    {
+        if(((a[i]-b[i])*(a[i]-b[i])) > 1)
+        {
+            dist = false;
+            i = a.size();
+        }
+    }
+}
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::MergeInfiniteNorm(bool &dist, RangeVectorType &a, RangeVectorType &b)
+{
+    dist = true;
+
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+    {
+        if(((a[i]-b[i])*(a[i]-b[i])) > (1/mergeFactor))
+        {
+            dist = false;
+            i = a.size();
+        }
+    }
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorAcc(std::vector<T> &a, std::vector<T> &b)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] += b[i];
+}
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorWeightedAcc(std::vector<T> &a, std::vector<T> &b, unsigned int &b_w)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] += b_w*b[i];
+}
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorWeightedAcc(std::vector<T> &a, unsigned int &a_w, std::vector<T> &b, unsigned int &b_w)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i){
+        a[i] *= a_w;
+        a[i] += b_w*b[i];
+    }
+}
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorWeightedMean(std::vector<T> &a, unsigned int &a_w, std::vector<T> &b, unsigned int &b_w)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] = ( (a[i]*a_w )+(b[i]*b_w) )/( a_w+b_w );
+
+    a_w += b_w;
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorMul(std::vector<T> &a, unsigned int &coeff)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] *= coeff;
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorDiv(std::vector<T> &a, unsigned int &coeff)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] /= coeff;
+}
+
+} // end of namespace itkSTMS
+
+#endif  // itkmsSTMS_BlurringSTMS_TXX
diff --git a/Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS_Spine.h b/Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS_Spine.h
new file mode 100755 (executable)
index 0000000..31d0ebd
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ #
+ #  File        : itkSTMS_BlurringSTMS_Spine.h
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_BlurringSTMS_Spine_H
+#define itkSTMS_BlurringSTMS_Spine_H
+
+#include "itkSTMS_ArgumentsAnalysis_Spine.h"
+#include "itkSTMS_ImageSequenceToTemporalSet_Spine.h"
+#include "itkImageFileReader.h"
+
+namespace itkSTMS_Spine
+{
+    template < class IndexType, class SpatialType, class PixelType, class ImageType>
+    class itkSTMS_BlurringSTMS
+    {
+    public:
+
+        typedef itkSTMS_Spine::ParamsAnalysisOutputType ParametersType;
+
+        // Sample set typedefs
+        typedef std::vector< SpatialType >        SpatialVectorType;
+        typedef std::vector< PixelType >          RangeVectorType;
+
+        typedef std::vector< IndexType >          IndexSampleSetType;
+        typedef std::vector< SpatialVectorType >  SpatialSampleSetType;
+        typedef std::vector< RangeVectorType >    RangeSampleSetType;
+
+        typedef typename ImageType::Pointer       ImagePointer;
+        typedef itk::ImageFileReader<ImageType>   ReaderType;
+        typedef typename ReaderType::Pointer      ReaderPointer;
+
+        // Image typedefs
+        typedef typename ImageType::IndexType     ImageIndexType;
+        typedef std::vector<ImageIndexType>       ImageIndexSetType;
+
+        // Methods
+        itkSTMS_BlurringSTMS( IndexSampleSetType*   idx,
+                              IndexSampleSetType*   cla,
+                              IndexSampleSetType*   wei,
+                              SpatialSampleSetType* sp,
+                              RangeSampleSetType*   ra,
+                              ParametersType*       params );
+
+        inline ~itkSTMS_BlurringSTMS(){ delete classSetMemory;
+                                        delete spatialSetMemory; }
+
+        inline IndexSampleSetType*   GetIndexSet       (){ return indexSet;         }
+        inline IndexSampleSetType*   GetClassSet       (){ return classSet;         }
+        inline IndexSampleSetType*   GetWeightsSet     (){ return weightsSet;       }
+        inline SpatialSampleSetType* GetSpatialSet     (){ return spatialSet;       }
+        inline RangeSampleSetType*   GetRangeSet       (){ return rangeSet;         }
+        inline IndexSampleSetType*   GetClassMemory    (){ return classSetMemory;   }
+        inline SpatialSampleSetType* GetSpatialMemory  (){ return spatialSetMemory; }
+
+        void GenerateData();
+        void NoMergeSTMSFiltering();
+        void ClassificationNoMergeSTMSFiltering();
+        void MergeSTMSFiltering();
+        void MergeSamples();
+        void FinalMerging();
+
+        template<class T> void VectorDistance(float &dist, std::vector< T > &a, std::vector< T > &b);
+        void InfiniteNorm  (bool  &dist, RangeVectorType &a, RangeVectorType &b);
+        void MergeInfiniteNorm(bool &dist, RangeVectorType &a, RangeVectorType &b);
+
+        template<class T> void VectorWeightedMean(std::vector<T> &a, unsigned int &a_w, std::vector<T> &b, unsigned int &b_w);
+        template<class T> void VectorWeightedAcc(std::vector<T> &a, std::vector<T> &b, unsigned int &b_w);
+        template<class T> void VectorWeightedAcc(std::vector<T> &a, unsigned int &a_w, std::vector<T> &b, unsigned int &b_w);
+        template<class T> void VectorMul(std::vector<T> &a, unsigned int &coeff);
+        template<class T> void VectorDiv(std::vector<T> &a, unsigned int &coeff);
+        template<class T> void VectorAcc(std::vector<T> &a, std::vector<T> &b);
+
+    private:
+        // Attributes
+        float mergeFactor;
+
+        ParametersType*        stmsParams;
+        IndexSampleSetType*    classSetMemory;
+        SpatialSampleSetType*  spatialSetMemory;
+        IndexSampleSetType*    indexSet;
+        IndexSampleSetType*    classSet;
+        IndexSampleSetType*    weightsSet;
+        SpatialSampleSetType*  spatialSet;
+        RangeSampleSetType *   rangeSet;
+    };
+
+} // end of namespace itkSTMS
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkSTMS_BlurringSTMS_Spine.txx"
+#endif
+
+#endif // itkSTMS_BlurringSTMS_Spine_H
diff --git a/Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS_Spine.txx b/Lib/SpatioTemporalMeanShift/itkSTMS_BlurringSTMS_Spine.txx
new file mode 100755 (executable)
index 0000000..cc12a06
--- /dev/null
@@ -0,0 +1,932 @@
+/*
+ #
+ #  File        : itkSTMS_BlurringSTMS_Spine.txx
+ #                ( C++ header file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL C
+ #                ( http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt )
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#ifndef itkSTMS_BlurringSTMS_TXX
+#define itkSTMS_BlurringSTMS_TXX
+
+#include <random>
+#include <algorithm>
+#include <iterator>
+#include "itkSTMS_BlurringSTMS_Spine.h"
+
+
+double gettime()
+{
+    struct timespec timestamp;
+
+    clock_gettime(CLOCK_REALTIME, &timestamp);
+    return timestamp.tv_sec * 1000.0 + timestamp.tv_nsec * 1.0e-6;
+}
+
+
+namespace itkSTMS_Spine
+{
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::itkSTMS_BlurringSTMS( IndexSampleSetType* idx, IndexSampleSetType* cla, IndexSampleSetType* wei,
+                        SpatialSampleSetType* sp, RangeSampleSetType* ra, ParametersType* params )
+{
+    this->indexSet   = idx;
+    this->classSet   = cla;
+    this->weightsSet = wei;
+    this->spatialSet = sp;
+    this->rangeSet   = ra;
+
+    this->classSetMemory   = new IndexSampleSetType  (  *this->classSet  );
+    this->spatialSetMemory = new SpatialSampleSetType( *this->spatialSet );
+
+    this->stmsParams     = params;
+
+    this->mergeFactor = 1000;
+}
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::GenerateData()
+{
+    double dtime;
+
+    if( !stmsParams->merge )
+    {
+        std::cout<< std::endl<<"No merge Filtering!"<<std::endl<<"numSamples: "<< indexSet->size() <<std::endl<< std::endl;
+        NoMergeSTMSFiltering();
+
+        dtime=gettime();
+        ClassificationNoMergeSTMSFiltering();
+        dtime = gettime()-dtime;
+        std::cout<< std::endl<<"Classif: " << dtime/1000 << " s" <<std::endl;
+        FinalMerging();
+    }
+    else
+    {
+        std::cout<<std::endl<<"Merge Filtering!"<<std::endl<<"numSamples: "<< indexSet->size() <<std::endl<< std::endl;
+        MergeSTMSFiltering();
+        FinalMerging();
+        //        ClassificationNoMergeSTMSFiltering();
+    }
+}
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::ClassificationNoMergeSTMSFiltering()
+{
+
+    IndexSampleSetType*   newClassSet
+            = new IndexSampleSetType();
+    newClassSet->reserve  ( indexSet->size() );
+
+    IndexSampleSetType*   newWeightsSet
+            = new IndexSampleSetType();
+    newWeightsSet->reserve( indexSet->size() );
+
+    IndexSampleSetType*   newIndexSet
+            = new IndexSampleSetType();
+    newIndexSet->reserve  ( indexSet->size() );
+
+    SpatialSampleSetType* newSpatialSet
+            = new SpatialSampleSetType();
+
+    newSpatialSet->reserve( indexSet->size() );
+
+    RangeSampleSetType*   newRangeSet
+            = new RangeSampleSetType();
+    newRangeSet->reserve  ( indexSet->size() );
+
+
+    newClassSet->push_back  ( 1 );
+    newWeightsSet->push_back( 1 );
+    newIndexSet->push_back  ( indexSet->at(0)   );
+    newSpatialSet->push_back( spatialSet->at(0) );
+    newRangeSet->push_back  ( rangeSet->at(0)   );
+    classSetMemory->at( indexSet->at(0) ) = newClassSet->at(0);
+
+
+    unsigned int k;
+    bool newC;
+    float spDist;
+    bool  raNorm;
+
+    for(unsigned int i=1 ; i<indexSet->size() ; ++i)
+    {
+        newC = true;
+        k=0;
+
+        while( (k<newClassSet->size()) && newC )
+        {
+            VectorDistance( spDist, newSpatialSet->at(k), spatialSet->at(i) );
+            if( spDist<=1 )
+            {
+                InfiniteNorm( raNorm, newRangeSet->at(k), rangeSet->at(i) );
+                if( raNorm )
+                {
+                    VectorWeightedMean( newSpatialSet->at(k), newWeightsSet->at(k), spatialSet->at(i), weightsSet->at(i) );
+                    VectorWeightedMean( newRangeSet->at(k)  , newWeightsSet->at(k), rangeSet->at(i)  , weightsSet->at(i) );
+
+                    classSetMemory->at( indexSet->at(i) ) = newClassSet->at(k);
+                    newC = false;
+                }
+                else
+                    ++k;
+            }
+            else
+                ++k;
+        }
+
+        if( newC )
+        {
+            newClassSet->push_back( (IndexType)newClassSet->back()+1 );
+            newWeightsSet->push_back( 1 );
+            newIndexSet->push_back  ( indexSet->at(i)   );
+            newSpatialSet->push_back( spatialSet->at(i) );
+            newRangeSet->push_back  ( rangeSet->at(i)   );
+            classSetMemory->at( indexSet->at(i) ) = newClassSet->back();
+        }
+    }
+
+    classSet->swap  ( *newClassSet   );
+    weightsSet->swap( *newWeightsSet );
+    indexSet->swap  ( *newIndexSet   );
+    spatialSet->swap( *newSpatialSet );
+    rangeSet->swap  ( *newRangeSet   );
+
+    delete newClassSet;
+    delete newWeightsSet;
+    delete newIndexSet;
+    delete newSpatialSet;
+    delete newRangeSet;
+}
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::NoMergeSTMSFiltering()
+{
+
+    SpatialSampleSetType* newSpatialSet
+            = new SpatialSampleSetType( indexSet->size(), SpatialVectorType(stmsParams->dim, 0) );
+    RangeSampleSetType*   newRangeSet
+            = new RangeSampleSetType( indexSet->size(), RangeVectorType(stmsParams->numTimePoints, 0) );
+
+    float globalEvolution = INFINITY;
+    float epsilon = (stmsParams->epsilon)*(stmsParams->epsilon);
+    float spDist, raDist;
+    bool  raNorm;
+    unsigned int iter = 0;
+
+    double dtime;
+    while( (globalEvolution>epsilon) & (iter<stmsParams->maxIt) )
+    {
+        dtime=gettime();
+        globalEvolution = 0.0;
+
+        #pragma omp parallel for reduction(+:globalEvolution) private(spDist, raDist, raNorm)
+        for(unsigned int i=0 ; i<indexSet->size() ; ++i)
+        {
+            unsigned int count = 0;
+            SpatialVectorType tmpSpatial( stmsParams->dim, 0 );
+            RangeVectorType   tmpRange  ( stmsParams->numTimePoints, 0 );
+
+            for(unsigned int j=0 ; j<indexSet->size() ; ++j)
+            {
+                VectorDistance( spDist, spatialSet->at(i), spatialSet->at(j));
+
+                if( spDist<=1 )
+                {
+                    InfiniteNorm(raNorm, rangeSet->at(i), rangeSet->at(j));
+
+                    if( raNorm )
+                    {
+                        VectorAcc( tmpSpatial, spatialSet->at(j) );
+                        VectorAcc( tmpRange  , rangeSet->at(j)   );
+
+                        ++count;
+                    }
+                }
+            }
+
+            if( count>1 )
+            {
+                VectorDiv( tmpSpatial, count );
+                VectorDiv( tmpRange  , count );
+            }
+
+            VectorDistance(spDist, spatialSet->at(i), tmpSpatial);
+            VectorDistance(raDist, rangeSet->at(i), tmpRange);
+
+            globalEvolution += (spDist+raDist);
+
+            #pragma omp critical
+            {
+                newSpatialSet->at(i) = tmpSpatial;
+                newRangeSet->at(i)   = tmpRange;
+            }
+        }
+
+        spatialSet->swap( *newSpatialSet );
+        rangeSet->swap  (  *newRangeSet  );
+
+        ++iter;
+        dtime = gettime()-dtime;
+        std::cout<< "Iter: " << iter <<"   "<< dtime/1000 << " s" <<"    GE: "<< globalEvolution <<std::endl;
+    }
+
+    delete newSpatialSet;
+    delete newRangeSet;
+}
+
+
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::MergeSTMSFiltering()
+{
+
+    float globalEvolution = INFINITY;
+    float epsilon = (stmsParams->epsilon)*(stmsParams->epsilon);
+    float spDist, raDist;
+    bool  raNorm, mergeNorm;
+    unsigned int iter = 0;
+    unsigned int merging;
+
+    double dtime;
+    while( (globalEvolution>epsilon) & (iter<stmsParams->maxIt) )
+    {
+        SpatialSampleSetType* newSpatialSet
+                = new SpatialSampleSetType( *spatialSet );
+        RangeSampleSetType*   newRangeSet
+                = new RangeSampleSetType  (  *rangeSet  );
+
+        dtime=gettime();
+        globalEvolution = 0.0;
+        merging = 0;
+
+        #pragma omp parallel for reduction(+:globalEvolution, merging) private(spDist, raDist, raNorm, mergeNorm)
+        for(unsigned int i=0 ; i<indexSet->size() ; ++i)
+        {
+            unsigned int weight = 0;
+            bool merge = false;
+            SpatialVectorType tmpSpatial( stmsParams->dim, 0 );
+            RangeVectorType   tmpRange  ( stmsParams->numTimePoints, 0 );
+
+            for(unsigned int j=0 ; j<indexSet->size() ; ++j)
+            {
+                VectorDistance( spDist, spatialSet->at(i), spatialSet->at(j));
+
+                if( spDist<=1 )
+                {
+                    InfiniteNorm(raNorm, rangeSet->at(i), rangeSet->at(j));
+
+                    if( raNorm )
+                    {
+                        VectorWeightedAcc(tmpSpatial, spatialSet->at(j), weightsSet->at(j));
+                        VectorWeightedAcc(tmpRange  , rangeSet->at(j)  , weightsSet->at(j));
+
+                        weight += weightsSet->at(j);
+
+                        MergeInfiniteNorm(mergeNorm, rangeSet->at(i), rangeSet->at(j));
+                        if( (spDist <= (1/mergeFactor)) && mergeNorm )
+                            merge = true;
+                    }
+                }
+            }
+
+            if(weight > weightsSet->at(i))
+            {
+                if( merge )
+                    merging += 1;
+                else
+                    merge = 0;
+            }
+            else
+                merge = 0;
+
+
+            VectorDiv( tmpSpatial, weight );
+            VectorDiv( tmpRange  , weight );
+
+            #pragma omp critical
+            {
+                newSpatialSet->at(i) = tmpSpatial;
+                newRangeSet->at(i)   = tmpRange;
+            }
+
+            VectorDistance(spDist, spatialSet->at(i), tmpSpatial);
+            VectorDistance(raDist, rangeSet->at(i), tmpRange);
+
+            globalEvolution += (spDist+raDist);
+        }
+
+        spatialSet->swap( *newSpatialSet );
+        rangeSet->swap  (  *newRangeSet  );
+
+        delete newSpatialSet;
+        delete newRangeSet;
+
+        if(merging > 0)
+            MergeSamples();
+
+        ++iter;
+        dtime = gettime()-dtime;
+        std::cout<< "Iter: " << iter <<"   "<< dtime/1000 << " s" <<"    GE: "<< globalEvolution << "      numSamples: "<< classSet->size() <<std::endl;
+    }
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::MergeSamples()
+{
+
+    IndexSampleSetType*   newClassSet
+            = new IndexSampleSetType();
+    newClassSet->reserve  ( indexSet->size() );
+
+    IndexSampleSetType*   newWeightsSet
+            = new IndexSampleSetType();
+    newWeightsSet->reserve( indexSet->size() );
+
+    IndexSampleSetType*   newIndexSet
+            = new IndexSampleSetType();
+    newIndexSet->reserve  ( indexSet->size() );
+
+    SpatialSampleSetType* newSpatialSet
+            = new SpatialSampleSetType();
+
+    newSpatialSet->reserve( indexSet->size() );
+
+    RangeSampleSetType*   newRangeSet
+            = new RangeSampleSetType();
+    newRangeSet->reserve  ( indexSet->size() );
+
+    IndexSampleSetType* newClassSetMemory
+            = new IndexSampleSetType( *classSetMemory );
+
+    IndexSampleSetType*   indexes
+            = new IndexSampleSetType( *classSet );
+
+    std::random_device rd;
+    std::mt19937 g(rd());
+
+    std::shuffle(indexes->begin(), indexes->end(), g);
+
+
+    newClassSet->push_back  ( 1 );
+    newWeightsSet->push_back( weightsSet->at( indexes->at(0)-1 ) );
+    newIndexSet->push_back  ( indexSet->at  ( indexes->at(0)-1 ) );
+    newSpatialSet->push_back( spatialSet->at( indexes->at(0)-1 ) );
+    newRangeSet->push_back  ( rangeSet->at  ( indexes->at(0)-1 ) );
+
+    for(unsigned int l=0 ; l< classSetMemory->size() ; ++l)
+    {
+        if(classSetMemory->at(l) == classSet->at(indexes->at(0)-1))
+            newClassSetMemory->at(l) = 1;
+    }
+
+    unsigned int k;
+    bool newC;
+    float spDist;
+    bool  raNorm;
+    unsigned int i;
+
+    for(unsigned int m=1 ; m<indexes->size() ; ++m)
+    {
+        i = indexes->at(m)-1;
+
+        newC = true;
+        k=0;
+
+        while( (k<newClassSet->size()) && newC )
+        {
+            VectorDistance( spDist, newSpatialSet->at(k), spatialSet->at(i) );
+            MergeInfiniteNorm( raNorm, newRangeSet->at(k), rangeSet->at(i) );
+            if( (spDist<=1/mergeFactor)&&raNorm )
+            {
+                VectorWeightedAcc( newSpatialSet->at(k), newWeightsSet->at(k), spatialSet->at(i), weightsSet->at(i) );
+                VectorWeightedAcc( newRangeSet->at(k)  , newWeightsSet->at(k), rangeSet->at(i)  , weightsSet->at(i) );
+
+                newWeightsSet->at(k) += weightsSet->at(i);
+
+                VectorDiv(newSpatialSet->at(k), newWeightsSet->at(k));
+                VectorDiv(newRangeSet->at(k), newWeightsSet->at(k));
+
+                for(unsigned int l=0 ; l<classSetMemory->size() ; ++l)
+                {
+                    if(classSetMemory->at(l) == classSet->at(i))
+                        newClassSetMemory->at(l) = newClassSet->at(k);
+                }
+
+                newC = false;
+            }
+            else
+                ++k;
+        }
+
+        if( newC )
+        {
+            newClassSet->push_back( newClassSet->back()+1 );
+            newWeightsSet->push_back( weightsSet->at(i) );
+            newIndexSet->push_back  ( indexSet->at(i)   );
+            newSpatialSet->push_back( spatialSet->at(i) );
+            newRangeSet->push_back  ( rangeSet->at(i)   );
+
+            for(unsigned int l=0 ; l< classSetMemory->size() ; ++l)
+            {
+                if(classSetMemory->at(l) == classSet->at(i))
+                    newClassSetMemory->at(l) = newClassSet->back();
+            }
+        }
+    }
+
+    classSet->swap  ( *newClassSet   );
+    weightsSet->swap( *newWeightsSet );
+    indexSet->swap  ( *newIndexSet   );
+    spatialSet->swap( *newSpatialSet );
+    rangeSet->swap  ( *newRangeSet   );
+    classSetMemory->swap  ( *newClassSetMemory );
+
+    delete newClassSet;
+    delete newWeightsSet;
+    delete newIndexSet;
+    delete newSpatialSet;
+    delete newRangeSet;
+    delete newClassSetMemory;
+    delete indexes;
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::FinalMerging()
+{
+    unsigned int size = INFINITY;
+    while(size > classSet->size()){
+        IndexSampleSetType*   newClassSet
+                = new IndexSampleSetType();
+        newClassSet->reserve  ( indexSet->size() );
+
+        IndexSampleSetType*   newWeightsSet
+                = new IndexSampleSetType();
+        newWeightsSet->reserve( indexSet->size() );
+
+        IndexSampleSetType*   newIndexSet
+                = new IndexSampleSetType();
+        newIndexSet->reserve  ( indexSet->size() );
+
+        SpatialSampleSetType* newSpatialSet
+                = new SpatialSampleSetType();
+
+        newSpatialSet->reserve( indexSet->size() );
+
+        RangeSampleSetType*   newRangeSet
+                = new RangeSampleSetType();
+        newRangeSet->reserve  ( indexSet->size() );
+
+        IndexSampleSetType* newClassSetMemory
+                = new IndexSampleSetType( *classSetMemory );
+
+        newClassSet->push_back  ( 1 );
+        newWeightsSet->push_back( 1 );
+        newIndexSet->push_back  ( indexSet->at(0)   );
+        newSpatialSet->push_back( spatialSet->at(0) );
+        newRangeSet->push_back  ( rangeSet->at(0)   );
+
+        unsigned int k;
+        bool newC;
+        bool  raNorm;
+
+        for(unsigned int i=1 ; i<classSet->size() ; ++i)
+        {
+            newC = true;
+            k=0;
+
+            while( (k<newClassSet->size()) && newC )
+            {
+                InfiniteNorm( raNorm, newRangeSet->at(k), rangeSet->at(i) );
+                if( raNorm ){
+
+                    ReaderPointer reader = ReaderType::New();
+                    ImagePointer image = ImageType::New();
+
+                    reader->SetFileName( *stmsParams->images.begin() );
+                    reader->Update();
+                    image = reader->GetOutput();
+                    image->FillBuffer( 0 );
+
+                    ImageIndexSetType* refClass  = new ImageIndexSetType();
+                    ImageIndexSetType* candClass = new ImageIndexSetType();
+                    refClass->reserve( classSet->size()/2 );
+                    candClass->reserve( classSet->size()/2 );
+
+
+                    for(unsigned int m=0 ; m<newClassSetMemory->size() ; ++m)
+                    {
+                        ImageIndexType idx;
+                        if(newClassSetMemory->at(m) == classSet->at(i)){
+
+                            #pragma omp simd
+                            for(unsigned int n=0 ; n<stmsParams->dim ; ++n)
+                                idx[n] = spatialSetMemory->at(m)[n]*stmsParams->spScales[n];
+
+                            candClass->push_back( idx );
+                            image->SetPixel(candClass->back(), 1);
+                        }
+                        else
+                        {
+                            if(newClassSetMemory->at(m) == newClassSet->at(k)){
+
+                                #pragma omp simd
+                                for(unsigned int n=0 ; n<stmsParams->dim ; ++n)
+                                    idx[n] = spatialSetMemory->at(m)[n]*stmsParams->spScales[n];
+
+                                refClass->push_back( idx );
+                                image->SetPixel(refClass->back(), 2);
+                            }
+                        }
+                    }
+
+                    bool connex = false;
+                    if(stmsParams->dim == 2)
+                    {
+                        if(refClass->size() < candClass->size())
+                        {
+                            unsigned int m=0;
+                            ImageIndexType idx;
+                            while((m<refClass->size()) && !connex)
+                            {
+                                for(int x=-1 ; x<=1 ; ++x)
+                                {
+                                    for(int y=-1 ; y<=1 ; ++y)
+                                    {
+                                        idx[0] = refClass->at(m)[0]+x;
+                                        idx[1] = refClass->at(m)[1]+y;
+
+                                        if(idx[0]<image->GetBufferedRegion().GetSize()[0] && idx[0]>0 && idx[1]<image->GetBufferedRegion().GetSize()[1] && idx[1]>0)
+                                        {
+                                            if(image->GetPixel(idx) == 2)
+                                            {
+                                                connex = true;
+                                                x = 2;
+                                                y = 2;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                ++m;
+                            }
+                        }
+                        else
+                        {
+                            unsigned int m=0;
+                            ImageIndexType idx;
+                            while((m<candClass->size()) && !connex)
+                            {
+                                for(int x=-1 ; x<=1 ; ++x)
+                                {
+                                    for(int y=-1 ; y<=1 ; ++y)
+                                    {
+                                        idx[0] = candClass->at(m)[0]+x;
+                                        idx[1] = candClass->at(m)[1]+y;
+
+                                        if(idx[0]<image->GetBufferedRegion().GetSize()[0] && idx[0]>0 && idx[1]<image->GetBufferedRegion().GetSize()[1] && idx[1]>0)
+                                        {
+                                            if(image->GetPixel(idx) == 1)
+                                            {
+                                                connex = true;
+                                                x = 2;
+                                                y = 2;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                ++m;
+                            }
+                        }
+
+                    }
+                    else
+                    {
+                        if(refClass->size() < candClass->size())
+                        {
+                            unsigned int m=0;
+                            ImageIndexType idx;
+                            while((m<refClass->size()) && !connex)
+                            {
+                                for(int x=-1 ; x<=1 ; ++x)
+                                {
+                                    for(int y=-1 ; y<=1 ; ++y)
+                                    {
+                                        for(int z=-1 ; z<=1 ; ++z)
+                                        {
+                                            idx[0] = refClass->at(m)[0]+x;
+                                            idx[1] = refClass->at(m)[1]+y;
+                                            idx[2] = refClass->at(m)[2]+z;
+
+                                            if(idx[0]<image->GetBufferedRegion().GetSize()[0] && idx[0]>0 && idx[1]<image->GetBufferedRegion().GetSize()[1] && idx[1]>0 && idx[2]<image->GetBufferedRegion().GetSize()[2] && idx[2]>0)
+                                            {
+                                                if(image->GetPixel(idx) == 2)
+                                                {
+                                                    connex = true;
+                                                    x = 2;
+                                                    y = 2;
+                                                    z = 2;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+
+                                ++m;
+                            }
+                        }
+                        else
+                        {
+                            unsigned int m=0;
+                            ImageIndexType idx;
+                            while((m<candClass->size()) && !connex)
+                            {
+                                for(int x=-1 ; x<=1 ; ++x)
+                                {
+                                    for(int y=-1 ; y<=1 ; ++y)
+                                    {
+                                        for(int z=-1 ; z<=1 ; ++z)
+                                        {
+                                            idx[0] = candClass->at(m)[0]+x;
+                                            idx[1] = candClass->at(m)[1]+y;
+                                            idx[2] = candClass->at(m)[2]+z;
+
+                                            if(idx[0]<image->GetBufferedRegion().GetSize()[0] && idx[0]>0 && idx[1]<image->GetBufferedRegion().GetSize()[1] && idx[1]>0 && idx[2]<image->GetBufferedRegion().GetSize()[2] && idx[2]>0)
+                                            {
+                                                if(image->GetPixel(idx) == 1)
+                                                {
+                                                    connex = true;
+                                                    x = 2;
+                                                    y = 2;
+                                                    z = 2;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+
+                                ++m;
+                            }
+                        }
+                    }
+
+                    if( connex )
+                    {
+
+                        VectorWeightedAcc( newSpatialSet->at(k), newWeightsSet->at(k), spatialSet->at(i), weightsSet->at(i) );
+                        VectorWeightedAcc( newRangeSet->at(k)  , newWeightsSet->at(k), rangeSet->at(i)  , weightsSet->at(i) );
+
+                        newWeightsSet->at(k) += weightsSet->at(i);
+
+                        VectorDiv(newSpatialSet->at(k), newWeightsSet->at(k));
+                        VectorDiv(newRangeSet->at(k), newWeightsSet->at(k));
+
+                        for(unsigned int l=0 ; l< classSetMemory->size() ; ++l)
+                        {
+
+                            if(classSetMemory->at(l) == classSet->at(i))
+                                newClassSetMemory->at(l) = newClassSet->at(k);
+                        }
+
+                        newC = false;
+                    }
+                    else
+                        ++k;
+
+                    delete refClass;
+                    delete candClass;
+                }
+                else
+                    ++k;
+            }
+
+            if( newC )
+            {
+                newClassSet->push_back( newClassSet->back()+1 );
+                newWeightsSet->push_back( weightsSet->at(i) );
+                newIndexSet->push_back  ( indexSet->at(i)   );
+                newSpatialSet->push_back( spatialSet->at(i) );
+                newRangeSet->push_back  ( rangeSet->at(i)   );
+
+                for(unsigned int l=0 ; l< classSetMemory->size() ; ++l)
+                {
+                    if(classSetMemory->at(l) == classSet->at(i))
+                        newClassSetMemory->at(l) = newClassSet->back();
+                }
+            }
+        }
+
+        size = classSet->size();
+
+        classSet->swap  ( *newClassSet   );
+        weightsSet->swap( *newWeightsSet );
+        indexSet->swap  ( *newIndexSet   );
+        spatialSet->swap( *newSpatialSet );
+        rangeSet->swap  ( *newRangeSet   );
+        classSetMemory->swap  ( *newClassSetMemory );
+
+        delete newClassSet;
+        delete newWeightsSet;
+        delete newIndexSet;
+        delete newSpatialSet;
+        delete newRangeSet;
+        delete newClassSetMemory;
+    }
+}
+
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorDistance(float &dist, std::vector<T> &a, std::vector<T> &b)
+{
+    dist = 0.0;
+
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        dist += ( a[i]-b[i] )*( a[i]-b[i] );
+}
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::InfiniteNorm(bool &dist, RangeVectorType &a, RangeVectorType &b)
+{
+    dist = true;
+
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+    {
+        if(((a[i]-b[i])*(a[i]-b[i])) > 1)
+        {
+            dist = false;
+            i = a.size();
+        }
+    }
+}
+
+
+template < class IndexType, class SpatialType, class PixelType, class ImageType >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::MergeInfiniteNorm(bool &dist, RangeVectorType &a, RangeVectorType &b)
+{
+    dist = true;
+
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+    {
+        if(((a[i]-b[i])*(a[i]-b[i])) > (1/mergeFactor))
+        {
+            dist = false;
+            i = a.size();
+        }
+    }
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorAcc(std::vector<T> &a, std::vector<T> &b)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] += b[i];
+}
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorWeightedAcc(std::vector<T> &a, std::vector<T> &b, unsigned int &b_w)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] += b_w*b[i];
+}
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorWeightedAcc(std::vector<T> &a, unsigned int &a_w, std::vector<T> &b, unsigned int &b_w)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i){
+        a[i] *= a_w;
+        a[i] += b_w*b[i];
+    }
+}
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorWeightedMean(std::vector<T> &a, unsigned int &a_w, std::vector<T> &b, unsigned int &b_w)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] = ( (a[i]*a_w )+(b[i]*b_w) )/( a_w+b_w );
+
+    a_w += b_w;
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorMul(std::vector<T> &a, unsigned int &coeff)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] *= coeff;
+}
+
+
+template< class IndexType, class SpatialType, class PixelType, class ImageType >
+template< class T >
+void
+itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType >
+::VectorDiv(std::vector<T> &a, unsigned int &coeff)
+{
+    #pragma omp simd
+    for(unsigned int i=0 ; i<a.size() ; ++i)
+        a[i] /= coeff;
+}
+
+} // end of namespace itkSTMS
+
+#endif  // itkmsSTMS_BlurringSTMS_Spine_TXX
diff --git a/Licence_CeCILL-C_V1-en.txt b/Licence_CeCILL-C_V1-en.txt
new file mode 100644 (file)
index 0000000..3d2a819
--- /dev/null
@@ -0,0 +1,517 @@
+
+CeCILL-C FREE SOFTWARE LICENSE AGREEMENT
+
+
+    Notice
+
+This Agreement is a Free Software license agreement that is the result
+of discussions between its authors in order to ensure compliance with
+the two main principles guiding its drafting:
+
+    * firstly, compliance with the principles governing the distribution
+      of Free Software: access to source code, broad rights granted to
+      users,
+    * secondly, the election of a governing law, French law, with which
+      it is conformant, both as regards the law of torts and
+      intellectual property law, and the protection that it offers to
+      both authors and holders of the economic rights over software.
+
+The authors of the CeCILL-C (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre])
+license are:
+
+Commissariat Ã  l'Energie Atomique - CEA, a public scientific, technical
+and industrial research establishment, having its principal place of
+business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France.
+
+Centre National de la Recherche Scientifique - CNRS, a public scientific
+and technological establishment, having its principal place of business
+at 3 rue Michel-Ange, 75794 Paris cedex 16, France.
+
+Institut National de Recherche en Informatique et en Automatique -
+INRIA, a public scientific and technological establishment, having its
+principal place of business at Domaine de Voluceau, Rocquencourt, BP
+105, 78153 Le Chesnay cedex, France.
+
+
+    Preamble
+
+The purpose of this Free Software license agreement is to grant users
+the right to modify and re-use the software governed by this license.
+
+The exercising of this right is conditional upon the obligation to make
+available to the community the modifications made to the source code of
+the software so as to contribute to its evolution.
+
+In consideration of access to the source code and the rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty and the software's author, the holder of the
+economic rights, and the successive licensors only have limited liability.
+
+In this respect, the risks associated with loading, using, modifying
+and/or developing or reproducing the software by the user are brought to
+the user's attention, given its Free Software status, which may make it
+complicated to use, with the result that its use is reserved for
+developers and experienced professionals having in-depth computer
+knowledge. Users are therefore encouraged to load and test the
+suitability of the software as regards their requirements in conditions
+enabling the security of their systems and/or data to be ensured and,
+more generally, to use and operate it in the same conditions of
+security. This Agreement may be freely reproduced and published,
+provided it is not altered, and that no provisions are either added or
+removed herefrom.
+
+This Agreement may apply to any or all software for which the holder of
+the economic rights decides to submit the use thereof to its provisions.
+
+
+    Article 1 - DEFINITIONS
+
+For the purpose of this Agreement, when the following expressions
+commence with a capital letter, they shall have the following meaning:
+
+Agreement: means this license agreement, and its possible subsequent
+versions and annexes.
+
+Software: means the software in its Object Code and/or Source Code form
+and, where applicable, its documentation, "as is" when the Licensee
+accepts the Agreement.
+
+Initial Software: means the Software in its Source Code and possibly its
+Object Code form and, where applicable, its documentation, "as is" when
+it is first distributed under the terms and conditions of the Agreement.
+
+Modified Software: means the Software modified by at least one
+Integrated Contribution.
+
+Source Code: means all the Software's instructions and program lines to
+which access is required so as to modify the Software.
+
+Object Code: means the binary files originating from the compilation of
+the Source Code.
+
+Holder: means the holder(s) of the economic rights over the Initial
+Software.
+
+Licensee: means the Software user(s) having accepted the Agreement.
+
+Contributor: means a Licensee having made at least one Integrated
+Contribution.
+
+Licensor: means the Holder, or any other individual or legal entity, who
+distributes the Software under the Agreement.
+
+Integrated Contribution: means any or all modifications, corrections,
+translations, adaptations and/or new functions integrated into the
+Source Code by any or all Contributors.
+
+Related Module: means a set of sources files including their
+documentation that, without modification to the Source Code, enables
+supplementary functions or services in addition to those offered by the
+Software.
+
+Derivative Software: means any combination of the Software, modified or
+not, and of a Related Module.
+
+Parties: mean both the Licensee and the Licensor.
+
+These expressions may be used both in singular and plural form.
+
+
+    Article 2 - PURPOSE
+
+The purpose of the Agreement is the grant by the Licensor to the
+Licensee of a non-exclusive, transferable and worldwide license for the
+Software as set forth in Article 5 hereinafter for the whole term of the
+protection granted by the rights over said Software. 
+
+
+    Article 3 - ACCEPTANCE
+
+3.1 The Licensee shall be deemed as having accepted the terms and
+conditions of this Agreement upon the occurrence of the first of the
+following events:
+
+    * (i) loading the Software by any or all means, notably, by
+      downloading from a remote server, or by loading from a physical
+      medium;
+    * (ii) the first time the Licensee exercises any of the rights
+      granted hereunder.
+
+3.2 One copy of the Agreement, containing a notice relating to the
+characteristics of the Software, to the limited warranty, and to the
+fact that its use is restricted to experienced users has been provided
+to the Licensee prior to its acceptance as set forth in Article 3.1
+hereinabove, and the Licensee hereby acknowledges that it has read and
+understood it.
+
+
+    Article 4 - EFFECTIVE DATE AND TERM
+
+
+      4.1 EFFECTIVE DATE
+
+The Agreement shall become effective on the date when it is accepted by
+the Licensee as set forth in Article 3.1.
+
+
+      4.2 TERM
+
+The Agreement shall remain in force for the entire legal term of
+protection of the economic rights over the Software.
+
+
+    Article 5 - SCOPE OF RIGHTS GRANTED
+
+The Licensor hereby grants to the Licensee, who accepts, the following
+rights over the Software for any or all use, and for the term of the
+Agreement, on the basis of the terms and conditions set forth hereinafter.
+
+Besides, if the Licensor owns or comes to own one or more patents
+protecting all or part of the functions of the Software or of its
+components, the Licensor undertakes not to enforce the rights granted by
+these patents against successive Licensees using, exploiting or
+modifying the Software. If these patents are transferred, the Licensor
+undertakes to have the transferees subscribe to the obligations set
+forth in this paragraph.
+
+
+      5.1 RIGHT OF USE
+
+The Licensee is authorized to use the Software, without any limitation
+as to its fields of application, with it being hereinafter specified
+that this comprises:
+
+   1. permanent or temporary reproduction of all or part of the Software
+      by any or all means and in any or all form.
+
+   2. loading, displaying, running, or storing the Software on any or
+      all medium.
+
+   3. entitlement to observe, study or test its operation so as to
+      determine the ideas and principles behind any or all constituent
+      elements of said Software. This shall apply when the Licensee
+      carries out any or all loading, displaying, running, transmission
+      or storage operation as regards the Software, that it is entitled
+      to carry out hereunder.
+
+
+      5.2 RIGHT OF MODIFICATION
+
+The right of modification includes the right to translate, adapt,
+arrange, or make any or all modifications to the Software, and the right
+to reproduce the resulting software. It includes, in particular, the
+right to create a Derivative Software.
+
+The Licensee is authorized to make any or all modification to the
+Software provided that it includes an explicit notice that it is the
+author of said modification and indicates the date of the creation thereof.
+
+
+      5.3 RIGHT OF DISTRIBUTION
+
+In particular, the right of distribution includes the right to publish,
+transmit and communicate the Software to the general public on any or
+all medium, and by any or all means, and the right to market, either in
+consideration of a fee, or free of charge, one or more copies of the
+Software by any means.
+
+The Licensee is further authorized to distribute copies of the modified
+or unmodified Software to third parties according to the terms and
+conditions set forth hereinafter.
+
+
+        5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION
+
+The Licensee is authorized to distribute true copies of the Software in
+Source Code or Object Code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+   1. a copy of the Agreement,
+
+   2. a notice relating to the limitation of both the Licensor's
+      warranty and liability as set forth in Articles 8 and 9,
+
+and that, in the event that only the Object Code of the Software is
+redistributed, the Licensee allows effective access to the full Source
+Code of the Software at a minimum during the entire period of its
+distribution of the Software, it being understood that the additional
+cost of acquiring the Source Code shall not exceed the cost of
+transferring the data.
+
+
+        5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE
+
+When the Licensee makes an Integrated Contribution to the Software, the
+terms and conditions for the distribution of the resulting Modified
+Software become subject to all the provisions of this Agreement.
+
+The Licensee is authorized to distribute the Modified Software, in
+source code or object code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+   1. a copy of the Agreement,
+
+   2. a notice relating to the limitation of both the Licensor's
+      warranty and liability as set forth in Articles 8 and 9,
+
+and that, in the event that only the object code of the Modified
+Software is redistributed, the Licensee allows effective access to the
+full source code of the Modified Software at a minimum during the entire
+period of its distribution of the Modified Software, it being understood
+that the additional cost of acquiring the source code shall not exceed
+the cost of transferring the data.
+
+
+        5.3.3 DISTRIBUTION OF DERIVATIVE SOFTWARE
+
+When the Licensee creates Derivative Software, this Derivative Software
+may be distributed under a license agreement other than this Agreement,
+subject to compliance with the requirement to include a notice
+concerning the rights over the Software as defined in Article 6.4.
+In the event the creation of the Derivative Software required modification 
+of the Source Code, the Licensee undertakes that:
+
+   1. the resulting Modified Software will be governed by this Agreement,
+   2. the Integrated Contributions in the resulting Modified Software
+      will be clearly identified and documented,
+   3. the Licensee will allow effective access to the source code of the
+      Modified Software, at a minimum during the entire period of
+      distribution of the Derivative Software, such that such
+      modifications may be carried over in a subsequent version of the
+      Software; it being understood that the additional cost of
+      purchasing the source code of the Modified Software shall not
+      exceed the cost of transferring the data.
+
+
+        5.3.4 COMPATIBILITY WITH THE CeCILL LICENSE
+
+When a Modified Software contains an Integrated Contribution subject to
+the CeCILL license agreement, or when a Derivative Software contains a
+Related Module subject to the CeCILL license agreement, the provisions
+set forth in the third item of Article 6.4 are optional.
+
+
+    Article 6 - INTELLECTUAL PROPERTY
+
+
+      6.1 OVER THE INITIAL SOFTWARE
+
+The Holder owns the economic rights over the Initial Software. Any or
+all use of the Initial Software is subject to compliance with the terms
+and conditions under which the Holder has elected to distribute its work
+and no one shall be entitled to modify the terms and conditions for the
+distribution of said Initial Software.
+
+The Holder undertakes that the Initial Software will remain ruled at
+least by this Agreement, for the duration set forth in Article 4.2.
+
+
+      6.2 OVER THE INTEGRATED CONTRIBUTIONS
+
+The Licensee who develops an Integrated Contribution is the owner of the
+intellectual property rights over this Contribution as defined by
+applicable law.
+
+
+      6.3 OVER THE RELATED MODULES
+
+The Licensee who develops a Related Module is the owner of the
+intellectual property rights over this Related Module as defined by
+applicable law and is free to choose the type of agreement that shall
+govern its distribution under the conditions defined in Article 5.3.3.
+
+
+      6.4 NOTICE OF RIGHTS
+
+The Licensee expressly undertakes:
+
+   1. not to remove, or modify, in any manner, the intellectual property
+      notices attached to the Software;
+
+   2. to reproduce said notices, in an identical manner, in the copies
+      of the Software modified or not;
+
+   3. to ensure that use of the Software, its intellectual property
+      notices and the fact that it is governed by the Agreement is
+      indicated in a text that is easily accessible, specifically from
+      the interface of any Derivative Software.
+
+The Licensee undertakes not to directly or indirectly infringe the
+intellectual property rights of the Holder and/or Contributors on the
+Software and to take, where applicable, vis-à-vis its staff, any and all
+measures required to ensure respect of said intellectual property rights
+of the Holder and/or Contributors.
+
+
+    Article 7 - RELATED SERVICES
+
+7.1 Under no circumstances shall the Agreement oblige the Licensor to
+provide technical assistance or maintenance services for the Software.
+
+However, the Licensor is entitled to offer this type of services. The
+terms and conditions of such technical assistance, and/or such
+maintenance, shall be set forth in a separate instrument. Only the
+Licensor offering said maintenance and/or technical assistance services
+shall incur liability therefor.
+
+7.2 Similarly, any Licensor is entitled to offer to its licensees, under
+its sole responsibility, a warranty, that shall only be binding upon
+itself, for the redistribution of the Software and/or the Modified
+Software, under terms and conditions that it is free to decide. Said
+warranty, and the financial terms and conditions of its application,
+shall be subject of a separate instrument executed between the Licensor
+and the Licensee.
+
+
+    Article 8 - LIABILITY
+
+8.1 Subject to the provisions of Article 8.2, the Licensee shall be
+entitled to claim compensation for any direct loss it may have suffered
+from the Software as a result of a fault on the part of the relevant
+Licensor, subject to providing evidence thereof.
+
+8.2 The Licensor's liability is limited to the commitments made under
+this Agreement and shall not be incurred as a result of in particular:
+(i) loss due the Licensee's total or partial failure to fulfill its
+obligations, (ii) direct or consequential loss that is suffered by the
+Licensee due to the use or performance of the Software, and (iii) more
+generally, any consequential loss. In particular the Parties expressly
+agree that any or all pecuniary or business loss (i.e. loss of data,
+loss of profits, operating loss, loss of customers or orders,
+opportunity cost, any disturbance to business activities) or any or all
+legal proceedings instituted against the Licensee by a third party,
+shall constitute consequential loss and shall not provide entitlement to
+any or all compensation from the Licensor.
+
+
+    Article 9 - WARRANTY
+
+9.1 The Licensee acknowledges that the scientific and technical
+state-of-the-art when the Software was distributed did not enable all
+possible uses to be tested and verified, nor for the presence of
+possible defects to be detected. In this respect, the Licensee's
+attention has been drawn to the risks associated with loading, using,
+modifying and/or developing and reproducing the Software which are
+reserved for experienced users.
+
+The Licensee shall be responsible for verifying, by any or all means,
+the suitability of the product for its requirements, its good working
+order, and for ensuring that it shall not cause damage to either persons
+or properties.
+
+9.2 The Licensor hereby represents, in good faith, that it is entitled
+to grant all the rights over the Software (including in particular the
+rights set forth in Article 5).
+
+9.3 The Licensee acknowledges that the Software is supplied "as is" by
+the Licensor without any other express or tacit warranty, other than
+that provided for in Article 9.2 and, in particular, without any warranty
+as to its commercial value, its secured, safe, innovative or relevant
+nature.
+
+Specifically, the Licensor does not warrant that the Software is free
+from any error, that it will operate without interruption, that it will
+be compatible with the Licensee's own equipment and software
+configuration, nor that it will meet the Licensee's requirements.
+
+9.4 The Licensor does not either expressly or tacitly warrant that the
+Software does not infringe any third party intellectual property right
+relating to a patent, software or any other property right. Therefore,
+the Licensor disclaims any and all liability towards the Licensee
+arising out of any or all proceedings for infringement that may be
+instituted in respect of the use, modification and redistribution of the
+Software. Nevertheless, should such proceedings be instituted against
+the Licensee, the Licensor shall provide it with technical and legal
+assistance for its defense. Such technical and legal assistance shall be
+decided on a case-by-case basis between the relevant Licensor and the
+Licensee pursuant to a memorandum of understanding. The Licensor
+disclaims any and all liability as regards the Licensee's use of the
+name of the Software. No warranty is given as regards the existence of
+prior rights over the name of the Software or as regards the existence
+of a trademark.
+
+
+    Article 10 - TERMINATION
+
+10.1 In the event of a breach by the Licensee of its obligations
+hereunder, the Licensor may automatically terminate this Agreement
+thirty (30) days after notice has been sent to the Licensee and has
+remained ineffective.
+
+10.2 A Licensee whose Agreement is terminated shall no longer be
+authorized to use, modify or distribute the Software. However, any
+licenses that it may have granted prior to termination of the Agreement
+shall remain valid subject to their having been granted in compliance
+with the terms and conditions hereof.
+
+
+    Article 11 - MISCELLANEOUS
+
+
+      11.1 EXCUSABLE EVENTS
+
+Neither Party shall be liable for any or all delay, or failure to
+perform the Agreement, that may be attributable to an event of force
+majeure, an act of God or an outside cause, such as defective
+functioning or interruptions of the electricity or telecommunications
+networks, network paralysis following a virus attack, intervention by
+government authorities, natural disasters, water damage, earthquakes,
+fire, explosions, strikes and labor unrest, war, etc.
+
+11.2 Any failure by either Party, on one or more occasions, to invoke
+one or more of the provisions hereof, shall under no circumstances be
+interpreted as being a waiver by the interested Party of its right to
+invoke said provision(s) subsequently.
+
+11.3 The Agreement cancels and replaces any or all previous agreements,
+whether written or oral, between the Parties and having the same
+purpose, and constitutes the entirety of the agreement between said
+Parties concerning said purpose. No supplement or modification to the
+terms and conditions hereof shall be effective as between the Parties
+unless it is made in writing and signed by their duly authorized
+representatives.
+
+11.4 In the event that one or more of the provisions hereof were to
+conflict with a current or future applicable act or legislative text,
+said act or legislative text shall prevail, and the Parties shall make
+the necessary amendments so as to comply with said act or legislative
+text. All other provisions shall remain effective. Similarly, invalidity
+of a provision of the Agreement, for any reason whatsoever, shall not
+cause the Agreement as a whole to be invalid.
+
+
+      11.5 LANGUAGE
+
+The Agreement is drafted in both French and English and both versions
+are deemed authentic.
+
+
+    Article 12 - NEW VERSIONS OF THE AGREEMENT
+
+12.1 Any person is authorized to duplicate and distribute copies of this
+Agreement.
+
+12.2 So as to ensure coherence, the wording of this Agreement is
+protected and may only be modified by the authors of the License, who
+reserve the right to periodically publish updates or new versions of the
+Agreement, each with a separate number. These subsequent versions may
+address new issues encountered by Free Software.
+
+12.3 Any Software distributed under a given version of the Agreement may
+only be subsequently distributed under the same version of the Agreement
+or a subsequent version.
+
+
+    Article 13 - GOVERNING LAW AND JURISDICTION
+
+13.1 The Agreement is governed by French law. The Parties agree to
+endeavor to seek an amicable solution to any disagreements or disputes
+that may arise during the performance of the Agreement.
+
+13.2 Failing an amicable solution within two (2) months as from their
+occurrence, and unless emergency proceedings are necessary, the
+disagreements or disputes shall be referred to the Paris Courts having
+jurisdiction, by the more diligent Party.
+
+
+Version 1.0 dated 2006-09-05.
diff --git a/Licence_CeCILL_V2.1-en.txt b/Licence_CeCILL_V2.1-en.txt
new file mode 100644 (file)
index 0000000..b705f37
--- /dev/null
@@ -0,0 +1,519 @@
+
+  CeCILL FREE SOFTWARE LICENSE AGREEMENT
+
+Version 2.1 dated 2013-06-21
+
+
+    Notice
+
+This Agreement is a Free Software license agreement that is the result
+of discussions between its authors in order to ensure compliance with
+the two main principles guiding its drafting:
+
+  * firstly, compliance with the principles governing the distribution
+    of Free Software: access to source code, broad rights granted to users,
+  * secondly, the election of a governing law, French law, with which it
+    is conformant, both as regards the law of torts and intellectual
+    property law, and the protection that it offers to both authors and
+    holders of the economic rights over software.
+
+The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) 
+license are: 
+
+Commissariat Ã  l'énergie atomique et aux Ã©nergies alternatives - CEA, a
+public scientific, technical and industrial research establishment,
+having its principal place of business at 25 rue Leblanc, immeuble Le
+Ponant D, 75015 Paris, France.
+
+Centre National de la Recherche Scientifique - CNRS, a public scientific
+and technological establishment, having its principal place of business
+at 3 rue Michel-Ange, 75794 Paris cedex 16, France.
+
+Institut National de Recherche en Informatique et en Automatique -
+Inria, a public scientific and technological establishment, having its
+principal place of business at Domaine de Voluceau, Rocquencourt, BP
+105, 78153 Le Chesnay cedex, France.
+
+
+    Preamble
+
+The purpose of this Free Software license agreement is to grant users
+the right to modify and redistribute the software governed by this
+license within the framework of an open source distribution model.
+
+The exercising of this right is conditional upon certain obligations for
+users so as to preserve this status for all subsequent redistributions.
+
+In consideration of access to the source code and the rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty and the software's author, the holder of the
+economic rights, and the successive licensors only have limited liability.
+
+In this respect, the risks associated with loading, using, modifying
+and/or developing or reproducing the software by the user are brought to
+the user's attention, given its Free Software status, which may make it
+complicated to use, with the result that its use is reserved for
+developers and experienced professionals having in-depth computer
+knowledge. Users are therefore encouraged to load and test the
+suitability of the software as regards their requirements in conditions
+enabling the security of their systems and/or data to be ensured and,
+more generally, to use and operate it in the same conditions of
+security. This Agreement may be freely reproduced and published,
+provided it is not altered, and that no provisions are either added or
+removed herefrom.
+
+This Agreement may apply to any or all software for which the holder of
+the economic rights decides to submit the use thereof to its provisions.
+
+Frequently asked questions can be found on the official website of the
+CeCILL licenses family (http://www.cecill.info/index.en.html) for any 
+necessary clarification.
+
+
+    Article 1 - DEFINITIONS
+
+For the purpose of this Agreement, when the following expressions
+commence with a capital letter, they shall have the following meaning:
+
+Agreement: means this license agreement, and its possible subsequent
+versions and annexes.
+
+Software: means the software in its Object Code and/or Source Code form
+and, where applicable, its documentation, "as is" when the Licensee
+accepts the Agreement.
+
+Initial Software: means the Software in its Source Code and possibly its
+Object Code form and, where applicable, its documentation, "as is" when
+it is first distributed under the terms and conditions of the Agreement.
+
+Modified Software: means the Software modified by at least one
+Contribution.
+
+Source Code: means all the Software's instructions and program lines to
+which access is required so as to modify the Software.
+
+Object Code: means the binary files originating from the compilation of
+the Source Code.
+
+Holder: means the holder(s) of the economic rights over the Initial
+Software.
+
+Licensee: means the Software user(s) having accepted the Agreement.
+
+Contributor: means a Licensee having made at least one Contribution.
+
+Licensor: means the Holder, or any other individual or legal entity, who
+distributes the Software under the Agreement.
+
+Contribution: means any or all modifications, corrections, translations,
+adaptations and/or new functions integrated into the Software by any or
+all Contributors, as well as any or all Internal Modules.
+
+Module: means a set of sources files including their documentation that
+enables supplementary functions or services in addition to those offered
+by the Software.
+
+External Module: means any or all Modules, not derived from the
+Software, so that this Module and the Software run in separate address
+spaces, with one calling the other when they are run.
+
+Internal Module: means any or all Module, connected to the Software so
+that they both execute in the same address space.
+
+GNU GPL: means the GNU General Public License version 2 or any
+subsequent version, as published by the Free Software Foundation Inc.
+
+GNU Affero GPL: means the GNU Affero General Public License version 3 or
+any subsequent version, as published by the Free Software Foundation Inc.
+
+EUPL: means the European Union Public License version 1.1 or any
+subsequent version, as published by the European Commission.
+
+Parties: mean both the Licensee and the Licensor.
+
+These expressions may be used both in singular and plural form.
+
+
+    Article 2 - PURPOSE
+
+The purpose of the Agreement is the grant by the Licensor to the
+Licensee of a non-exclusive, transferable and worldwide license for the
+Software as set forth in Article 5 <#scope> hereinafter for the whole
+term of the protection granted by the rights over said Software.
+
+
+    Article 3 - ACCEPTANCE
+
+3.1 The Licensee shall be deemed as having accepted the terms and
+conditions of this Agreement upon the occurrence of the first of the
+following events:
+
+  * (i) loading the Software by any or all means, notably, by
+    downloading from a remote server, or by loading from a physical medium;
+  * (ii) the first time the Licensee exercises any of the rights granted
+    hereunder.
+
+3.2 One copy of the Agreement, containing a notice relating to the
+characteristics of the Software, to the limited warranty, and to the
+fact that its use is restricted to experienced users has been provided
+to the Licensee prior to its acceptance as set forth in Article 3.1
+<#accepting> hereinabove, and the Licensee hereby acknowledges that it
+has read and understood it.
+
+
+    Article 4 - EFFECTIVE DATE AND TERM
+
+
+      4.1 EFFECTIVE DATE
+
+The Agreement shall become effective on the date when it is accepted by
+the Licensee as set forth in Article 3.1 <#accepting>.
+
+
+      4.2 TERM
+
+The Agreement shall remain in force for the entire legal term of
+protection of the economic rights over the Software.
+
+
+    Article 5 - SCOPE OF RIGHTS GRANTED
+
+The Licensor hereby grants to the Licensee, who accepts, the following
+rights over the Software for any or all use, and for the term of the
+Agreement, on the basis of the terms and conditions set forth hereinafter.
+
+Besides, if the Licensor owns or comes to own one or more patents
+protecting all or part of the functions of the Software or of its
+components, the Licensor undertakes not to enforce the rights granted by
+these patents against successive Licensees using, exploiting or
+modifying the Software. If these patents are transferred, the Licensor
+undertakes to have the transferees subscribe to the obligations set
+forth in this paragraph.
+
+
+      5.1 RIGHT OF USE
+
+The Licensee is authorized to use the Software, without any limitation
+as to its fields of application, with it being hereinafter specified
+that this comprises:
+
+ 1. permanent or temporary reproduction of all or part of the Software
+    by any or all means and in any or all form.
+
+ 2. loading, displaying, running, or storing the Software on any or all
+    medium.
+
+ 3. entitlement to observe, study or test its operation so as to
+    determine the ideas and principles behind any or all constituent
+    elements of said Software. This shall apply when the Licensee
+    carries out any or all loading, displaying, running, transmission or
+    storage operation as regards the Software, that it is entitled to
+    carry out hereunder.
+
+
+      5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS
+
+The right to make Contributions includes the right to translate, adapt,
+arrange, or make any or all modifications to the Software, and the right
+to reproduce the resulting software.
+
+The Licensee is authorized to make any or all Contributions to the
+Software provided that it includes an explicit notice that it is the
+author of said Contribution and indicates the date of the creation thereof.
+
+
+      5.3 RIGHT OF DISTRIBUTION
+
+In particular, the right of distribution includes the right to publish,
+transmit and communicate the Software to the general public on any or
+all medium, and by any or all means, and the right to market, either in
+consideration of a fee, or free of charge, one or more copies of the
+Software by any means.
+
+The Licensee is further authorized to distribute copies of the modified
+or unmodified Software to third parties according to the terms and
+conditions set forth hereinafter.
+
+
+        5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION
+
+The Licensee is authorized to distribute true copies of the Software in
+Source Code or Object Code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+ 1. a copy of the Agreement,
+
+ 2. a notice relating to the limitation of both the Licensor's warranty
+    and liability as set forth in Articles 8 and 9,
+
+and that, in the event that only the Object Code of the Software is
+redistributed, the Licensee allows effective access to the full Source
+Code of the Software for a period of at least three years from the
+distribution of the Software, it being understood that the additional
+acquisition cost of the Source Code shall not exceed the cost of the
+data transfer.
+
+
+        5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE
+
+When the Licensee makes a Contribution to the Software, the terms and
+conditions for the distribution of the resulting Modified Software
+become subject to all the provisions of this Agreement.
+
+The Licensee is authorized to distribute the Modified Software, in
+source code or object code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+ 1. a copy of the Agreement,
+
+ 2. a notice relating to the limitation of both the Licensor's warranty
+    and liability as set forth in Articles 8 and 9,
+
+and, in the event that only the object code of the Modified Software is
+redistributed,
+
+ 3. a note stating the conditions of effective access to the full source
+    code of the Modified Software for a period of at least three years
+    from the distribution of the Modified Software, it being understood
+    that the additional acquisition cost of the source code shall not
+    exceed the cost of the data transfer.
+
+
+        5.3.3 DISTRIBUTION OF EXTERNAL MODULES
+
+When the Licensee has developed an External Module, the terms and
+conditions of this Agreement do not apply to said External Module, that
+may be distributed under a separate license agreement.
+
+
+        5.3.4 COMPATIBILITY WITH OTHER LICENSES
+
+The Licensee can include a code that is subject to the provisions of one
+of the versions of the GNU GPL, GNU Affero GPL and/or EUPL in the
+Modified or unmodified Software, and distribute that entire code under
+the terms of the same version of the GNU GPL, GNU Affero GPL and/or EUPL.
+
+The Licensee can include the Modified or unmodified Software in a code
+that is subject to the provisions of one of the versions of the GNU GPL,
+GNU Affero GPL and/or EUPL and distribute that entire code under the
+terms of the same version of the GNU GPL, GNU Affero GPL and/or EUPL.
+
+
+    Article 6 - INTELLECTUAL PROPERTY
+
+
+      6.1 OVER THE INITIAL SOFTWARE
+
+The Holder owns the economic rights over the Initial Software. Any or
+all use of the Initial Software is subject to compliance with the terms
+and conditions under which the Holder has elected to distribute its work
+and no one shall be entitled to modify the terms and conditions for the
+distribution of said Initial Software.
+
+The Holder undertakes that the Initial Software will remain ruled at
+least by this Agreement, for the duration set forth in Article 4.2 <#term>.
+
+
+      6.2 OVER THE CONTRIBUTIONS
+
+The Licensee who develops a Contribution is the owner of the
+intellectual property rights over this Contribution as defined by
+applicable law.
+
+
+      6.3 OVER THE EXTERNAL MODULES
+
+The Licensee who develops an External Module is the owner of the
+intellectual property rights over this External Module as defined by
+applicable law and is free to choose the type of agreement that shall
+govern its distribution.
+
+
+      6.4 JOINT PROVISIONS
+
+The Licensee expressly undertakes:
+
+ 1. not to remove, or modify, in any manner, the intellectual property
+    notices attached to the Software;
+
+ 2. to reproduce said notices, in an identical manner, in the copies of
+    the Software modified or not.
+
+The Licensee undertakes not to directly or indirectly infringe the
+intellectual property rights on the Software of the Holder and/or
+Contributors, and to take, where applicable, vis-à-vis its staff, any
+and all measures required to ensure respect of said intellectual
+property rights of the Holder and/or Contributors.
+
+
+    Article 7 - RELATED SERVICES
+
+7.1 Under no circumstances shall the Agreement oblige the Licensor to
+provide technical assistance or maintenance services for the Software.
+
+However, the Licensor is entitled to offer this type of services. The
+terms and conditions of such technical assistance, and/or such
+maintenance, shall be set forth in a separate instrument. Only the
+Licensor offering said maintenance and/or technical assistance services
+shall incur liability therefor.
+
+7.2 Similarly, any Licensor is entitled to offer to its licensees, under
+its sole responsibility, a warranty, that shall only be binding upon
+itself, for the redistribution of the Software and/or the Modified
+Software, under terms and conditions that it is free to decide. Said
+warranty, and the financial terms and conditions of its application,
+shall be subject of a separate instrument executed between the Licensor
+and the Licensee.
+
+
+    Article 8 - LIABILITY
+
+8.1 Subject to the provisions of Article 8.2, the Licensee shall be
+entitled to claim compensation for any direct loss it may have suffered
+from the Software as a result of a fault on the part of the relevant
+Licensor, subject to providing evidence thereof.
+
+8.2 The Licensor's liability is limited to the commitments made under
+this Agreement and shall not be incurred as a result of in particular:
+(i) loss due the Licensee's total or partial failure to fulfill its
+obligations, (ii) direct or consequential loss that is suffered by the
+Licensee due to the use or performance of the Software, and (iii) more
+generally, any consequential loss. In particular the Parties expressly
+agree that any or all pecuniary or business loss (i.e. loss of data,
+loss of profits, operating loss, loss of customers or orders,
+opportunity cost, any disturbance to business activities) or any or all
+legal proceedings instituted against the Licensee by a third party,
+shall constitute consequential loss and shall not provide entitlement to
+any or all compensation from the Licensor.
+
+
+    Article 9 - WARRANTY
+
+9.1 The Licensee acknowledges that the scientific and technical
+state-of-the-art when the Software was distributed did not enable all
+possible uses to be tested and verified, nor for the presence of
+possible defects to be detected. In this respect, the Licensee's
+attention has been drawn to the risks associated with loading, using,
+modifying and/or developing and reproducing the Software which are
+reserved for experienced users.
+
+The Licensee shall be responsible for verifying, by any or all means,
+the suitability of the product for its requirements, its good working
+order, and for ensuring that it shall not cause damage to either persons
+or properties.
+
+9.2 The Licensor hereby represents, in good faith, that it is entitled
+to grant all the rights over the Software (including in particular the
+rights set forth in Article 5 <#scope>).
+
+9.3 The Licensee acknowledges that the Software is supplied "as is" by
+the Licensor without any other express or tacit warranty, other than
+that provided for in Article 9.2 <#good-faith> and, in particular,
+without any warranty as to its commercial value, its secured, safe,
+innovative or relevant nature.
+
+Specifically, the Licensor does not warrant that the Software is free
+from any error, that it will operate without interruption, that it will
+be compatible with the Licensee's own equipment and software
+configuration, nor that it will meet the Licensee's requirements.
+
+9.4 The Licensor does not either expressly or tacitly warrant that the
+Software does not infringe any third party intellectual property right
+relating to a patent, software or any other property right. Therefore,
+the Licensor disclaims any and all liability towards the Licensee
+arising out of any or all proceedings for infringement that may be
+instituted in respect of the use, modification and redistribution of the
+Software. Nevertheless, should such proceedings be instituted against
+the Licensee, the Licensor shall provide it with technical and legal
+expertise for its defense. Such technical and legal expertise shall be
+decided on a case-by-case basis between the relevant Licensor and the
+Licensee pursuant to a memorandum of understanding. The Licensor
+disclaims any and all liability as regards the Licensee's use of the
+name of the Software. No warranty is given as regards the existence of
+prior rights over the name of the Software or as regards the existence
+of a trademark.
+
+
+    Article 10 - TERMINATION
+
+10.1 In the event of a breach by the Licensee of its obligations
+hereunder, the Licensor may automatically terminate this Agreement
+thirty (30) days after notice has been sent to the Licensee and has
+remained ineffective.
+
+10.2 A Licensee whose Agreement is terminated shall no longer be
+authorized to use, modify or distribute the Software. However, any
+licenses that it may have granted prior to termination of the Agreement
+shall remain valid subject to their having been granted in compliance
+with the terms and conditions hereof.
+
+
+    Article 11 - MISCELLANEOUS
+
+
+      11.1 EXCUSABLE EVENTS
+
+Neither Party shall be liable for any or all delay, or failure to
+perform the Agreement, that may be attributable to an event of force
+majeure, an act of God or an outside cause, such as defective
+functioning or interruptions of the electricity or telecommunications
+networks, network paralysis following a virus attack, intervention by
+government authorities, natural disasters, water damage, earthquakes,
+fire, explosions, strikes and labor unrest, war, etc.
+
+11.2 Any failure by either Party, on one or more occasions, to invoke
+one or more of the provisions hereof, shall under no circumstances be
+interpreted as being a waiver by the interested Party of its right to
+invoke said provision(s) subsequently.
+
+11.3 The Agreement cancels and replaces any or all previous agreements,
+whether written or oral, between the Parties and having the same
+purpose, and constitutes the entirety of the agreement between said
+Parties concerning said purpose. No supplement or modification to the
+terms and conditions hereof shall be effective as between the Parties
+unless it is made in writing and signed by their duly authorized
+representatives.
+
+11.4 In the event that one or more of the provisions hereof were to
+conflict with a current or future applicable act or legislative text,
+said act or legislative text shall prevail, and the Parties shall make
+the necessary amendments so as to comply with said act or legislative
+text. All other provisions shall remain effective. Similarly, invalidity
+of a provision of the Agreement, for any reason whatsoever, shall not
+cause the Agreement as a whole to be invalid.
+
+
+      11.5 LANGUAGE
+
+The Agreement is drafted in both French and English and both versions
+are deemed authentic.
+
+
+    Article 12 - NEW VERSIONS OF THE AGREEMENT
+
+12.1 Any person is authorized to duplicate and distribute copies of this
+Agreement.
+
+12.2 So as to ensure coherence, the wording of this Agreement is
+protected and may only be modified by the authors of the License, who
+reserve the right to periodically publish updates or new versions of the
+Agreement, each with a separate number. These subsequent versions may
+address new issues encountered by Free Software.
+
+12.3 Any Software distributed under a given version of the Agreement may
+only be subsequently distributed under the same version of the Agreement
+or a subsequent version, subject to the provisions of Article 5.3.4
+<#compatibility>.
+
+
+    Article 13 - GOVERNING LAW AND JURISDICTION
+
+13.1 The Agreement is governed by French law. The Parties agree to
+endeavor to seek an amicable solution to any disagreements or disputes
+that may arise during the performance of the Agreement.
+
+13.2 Failing an amicable solution within two (2) months as from their
+occurrence, and unless emergency proceedings are necessary, the
+disagreements or disputes shall be referred to the Paris Courts having
+jurisdiction, by the more diligent Party.
+
diff --git a/Src/CMakeLists.txt b/Src/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..e5679da
--- /dev/null
@@ -0,0 +1,29 @@
+# cmake_minimum_required(VERSION 2.4)
+# SET(CMAKE_BUILD_TYPE Debug)
+#SET(CMAKE_BUILD_TYPE Release)
+
+# if(COMMAND CMAKE_POLICY)
+  # cmake_policy(SET CMP0003 NEW)
+# endif()
+
+# project(STMS)
+# include_regular_expression("^.*$")
+
+# find_package(ITK REQUIRED)
+# include(${ITK_USE_FILE})
+
+#add_executable(test_parseXML test_parseXML.cxx )
+#target_link_libraries(test_parseXML ${ITK_LIBRARIES})
+
+#add_executable(test_ArgumentsAnalysis test_ArgumentsAnalysis.cxx )
+#target_link_libraries(test_ArgumentsAnalysis ${ITK_LIBRARIES})
+
+#add_executable(test_ArgumentsAnalysis_Spine test_ArgumentsAnalysis_Spine.cxx )
+#target_link_libraries(test_ArgumentsAnalysis_Spine ${ITK_LIBRARIES}) 
+
+add_executable(STMS_GrayLevelFiltering STMS_GrayLevelFiltering.cxx)
+target_link_libraries(STMS_GrayLevelFiltering ${ITK_LIBRARIES})
+
+#add_executable(STMS_GrayLevelFiltering_Spine STMS_GrayLevelFiltering_Spine.cxx )
+#target_link_libraries(STMS_GrayLevelFiltering_Spine ${ITK_LIBRARIES})
+
diff --git a/Src/STMS_GrayLevelFiltering.cxx b/Src/STMS_GrayLevelFiltering.cxx
new file mode 100755 (executable)
index 0000000..d2bcb3d
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ #
+ #  File        : STMS_GrayLevelFiltering.cxx
+ #                ( C++ example file - STMS )
+ #
+ #  Description : STMS lib that implements the STMS filter and clustering.
+ #                This file is a part of the STMS Library project.
+ #                ( https://www.creatis.insa-lyon.fr/site7/fr/realisations )
+ #
+ #  [1] S. Mure, Grenier, T., Meier, S., Guttmann, R. G., et Benoit-Cattin, H.,
+ #       Â« Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification Â»,
+ #       Pattern Recognition Letters, vol. 68, Part 1, p. 48 - 55, 2015.
+ #
+ #  Copyright   : Thomas GRENIER - Simon MURE
+ #                ( https://www.creatis.insa-lyon.fr/~grenier/ )
+ #
+ #  License     : CeCILL V2.1
+ #                ( http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt)
+ #
+ #  This software is governed by the CeCILL  license under French law and
+ #  abiding by the rules of distribution of free software.  You can  use,
+ #  modify and/ or redistribute the software under the terms of the CeCILL
+ #  license as circulated by CEA, CNRS and INRIA at the following URL
+ #  "http://www.cecill.info".
+ #
+ #  As a counterpart to the access to the source code and  rights to copy,
+ #  modify and redistribute granted by the license, users are provided only
+ #  with a limited warranty  and the software's author,  the holder of the
+ #  economic rights,  and the successive licensors  have only  limited
+ #  liability.
+ #
+ #  In this respect, the user's attention is drawn to the risks associated
+ #  with loading,  using,  modifying and/or developing or reproducing the
+ #  software by the user in light of its specific status of free software,
+ #  that may mean  that it is complicated to manipulate,  and  that  also
+ #  therefore means  that it is reserved for developers  and  experienced
+ #  professionals having in-depth computer knowledge. Users are therefore
+ #  encouraged to load and test the software's suitability as regards their
+ #  requirements in conditions enabling the security of their systems and/or
+ #  data to be ensured and,  more generally, to use and operate it in the
+ #  same conditions as regards security.
+ #
+ #  The fact that you are presently reading this means that you have had
+ #  knowledge of the CeCILL license and that you accept its terms.
+ #
+*/
+/* Please don't forget to cite our work :
+  @article {MURE-15a,
+    title = {Unsupervised spatio-temporal filtering of image sequences. A mean-shift specification},
+    journal = {Pattern Recognition Letters},
+    volume = {68, Part 1},
+    year = {2015},
+    pages = {48 - 55},
+    issn = {0167-8655},
+    doi = {http://dx.doi.org/10.1016/j.patrec.2015.07.021},
+    url = {http://www.sciencedirect.com/science/article/pii/S0167865515002305},
+    author = {S. Mure and T Grenier and Meier, S. and Guttmann, R.G. and H. Benoit-Cattin}
+}
+*/
+#include <iomanip>
+#include <ctime>
+
+#define STMS_NUMBERING_FORM_ONE "01"
+
+#include "itkImage.h"
+#include "itkSTMS_ArgumentsAnalysis.h"
+#include "itkSTMS_ImageSequenceToTemporalSet.h"
+#include "itkSTMS_TemporalSetToImageSequence.h"
+#include "itkSTMS_BlurringSTMS.h"
+
+#include <array>
+
+
+
+typedef float PixelType;
+
+double gettime_hp()
+{
+    struct timespec timestamp;
+
+    clock_gettime(CLOCK_REALTIME, &timestamp);
+    return timestamp.tv_sec * 1000.0 + timestamp.tv_nsec * 1.0e-6;
+}
+
+// Only --expDescription and numTimePoints parameter are compulsory.
+
+//--expDescription /run/media/mure/HDD/Recherche/These/CVS/Mure/Dev/Cpp/itkSTMS/Data/P43_Parser.xml --imageDimension 2 --xScale 20 --yScale 20 --rScale 1 --epsilon 0.1 --maxIt 20 --numTimePoints 25 --merge
+
+//--expDescription /run/media/mure/HDD/Recherche/These/CVS/Mure/Dev/Cpp/itkSTMS/Data/L43_3_Parser.xml --imageDimension 3 --xScale 1000 --yScale 1000 --zScale 1000 --rScale 0.75 --epsilon 0.1 --maxIt 50 --numTimePoints 25 --merge
+//--expDescription /run/media/mure/HDD/Recherche/These/CVS/Mure/Dev/Cpp/itkSTMS/Data/Simu_Parser.xml --imageDimension 2 --xScale 255 --yScale 255 --rScale 0.4 --epsilon 0.01 --maxIt 50 --numTimePoints 8
+//--expDescription /run/media/mure/HDD/Recherche/These/CVS/Mure/Dev/Cpp/itkSTMS/Data/G1_Parser.xml --imageDimension 3 --xScale 1000 --yScale 1000 --zScale 1000 --rScale 0.15 --epsilon 0.01 --maxIt 50 --numTimePoints 8
+
+// --expDescription E:/Documents/Creatis/Projets/15_MUST/Data_Cardiac/Parser_AIF_Cardiac.xml --imageDimension 2 --xScale 10 --yScale 10 --rScale 10 --numTimePoints 80
+
+int main(int argc, char **argv){
+    double dtime;
+
+    std::cout << "The Numbering form is set to numbers like = " << STMS_NUMBERING_FORM_ONE << std::endl;
+    std::cout << "size : " << sizeof(STMS_NUMBERING_FORM_ONE) << std::endl;
+
+
+    itkSTMS::itkSTMS_ArgumentsAnalysis* argsAnalysis
+            = new itkSTMS::itkSTMS_ArgumentsAnalysis(argc, argv);
+    argsAnalysis->Update();
+
+    itkSTMS::ParamsAnalysisOutputType* params
+            = argsAnalysis->GetSTMSParams();
+
+
+    switch(params->dim){
+        case 2:
+        {
+            typedef itk::Image< PixelType, 2 >     ImageType2D;
+            typedef itk::Image< unsigned char, 2 > MaskImageType2D;
+
+
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::IndexType            IndexType;
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::SpatialType          SpatialType;
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::IndexSampleSetType   IndexSampleSetType;
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::SpatialSampleSetType SpatialSampleSetType;
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::RangeSampleSetType   RangeSampleSetType;
+
+            typedef itk::Image< IndexType, 2 >  ClassImageType2D;
+
+
+            dtime=gettime_hp();
+
+            itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >* preProcess
+                    = new itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D > ( params );
+            preProcess->GenerateDataSets();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "Characteristics extraction: " << dtime/1000 << " s" <<std::endl;
+
+            IndexSampleSetType*   indexSet   = preProcess->GetIndexSet();
+            IndexSampleSetType*   classSet   = preProcess->GetClassSet();
+            IndexSampleSetType*   weightsSet = preProcess->GetWeightsSet();
+            SpatialSampleSetType* spatialSet = preProcess->GetSpatialSet();
+            RangeSampleSetType*   rangeSet   = preProcess->GetRangeSet();
+
+
+            dtime=gettime_hp();
+
+            itkSTMS::itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType2D >* stmsFilter
+                    = new itkSTMS::itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType2D >
+                    (indexSet, classSet, weightsSet, spatialSet, rangeSet,  params, preProcess->GetExperimentDescription());
+
+            stmsFilter->GenerateData();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "STMS filtering: " << dtime/1000 << " s" <<std::endl;
+
+
+            dtime=gettime_hp();
+
+            itkSTMS::itkSTMS_TemporalSetToImageSequence< ImageType2D, ClassImageType2D >* postProcess
+                    = new itkSTMS::itkSTMS_TemporalSetToImageSequence< ImageType2D, ClassImageType2D >(stmsFilter->GetClassMemory(),
+                                                                                                       stmsFilter->GetSpatialMemory(),
+                                                                                                       stmsFilter->GetRangeSet(),
+                                                                                                       params,
+                                                                                                       preProcess->GetExperimentDescription());
+
+            postProcess->GenerateImageSequence();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "Image sequence saving: " << dtime/1000 << " s" <<std::endl;
+
+            delete argsAnalysis;
+            delete preProcess;
+            delete stmsFilter;
+            delete postProcess;
+            break;
+        }
+
+        case 3:
+        {
+            typedef itk::Image< PixelType, 3 >     ImageType3D;
+            typedef itk::Image< unsigned char, 3 > MaskImageType3D;
+
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::IndexType            IndexType;
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::SpatialType          SpatialType;
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::IndexSampleSetType   IndexSampleSetType;
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::SpatialSampleSetType SpatialSampleSetType;
+            typedef itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::RangeSampleSetType   RangeSampleSetType;
+
+
+            dtime=gettime_hp();
+
+            itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >* preProcess
+                    = new itkSTMS::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D > ( params );
+            preProcess->GenerateDataSets();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "Characteristics extraction: " << dtime/1000 << " s" <<std::endl;
+
+            IndexSampleSetType*   indexSet   = preProcess->GetIndexSet();
+            IndexSampleSetType*   classSet   = preProcess->GetClassSet();
+            IndexSampleSetType*   weightsSet = preProcess->GetWeightsSet();
+            SpatialSampleSetType* spatialSet = preProcess->GetSpatialSet();
+            RangeSampleSetType*   rangeSet   = preProcess->GetRangeSet();
+
+
+
+
+            dtime=gettime_hp();
+
+            itkSTMS::itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType3D >* stmsFilter
+                    = new itkSTMS::itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType3D >
+                    (indexSet, classSet, weightsSet, spatialSet, rangeSet,  params, preProcess->GetExperimentDescription());
+
+            stmsFilter->GenerateData();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "STMS filtering: " << dtime/1000 << " s" <<std::endl;
+
+
+            dtime=gettime_hp();
+
+            itkSTMS::itkSTMS_TemporalSetToImageSequence< ImageType3D, MaskImageType3D >* postProcess
+                    = new itkSTMS::itkSTMS_TemporalSetToImageSequence< ImageType3D, MaskImageType3D >(stmsFilter->GetClassMemory(),
+                                                                                                      stmsFilter->GetSpatialMemory(),
+                                                                                                      stmsFilter->GetRangeSet(),
+                                                                                                      params,
+                                                                                                      preProcess->GetExperimentDescription());
+
+            postProcess->GenerateImageSequence();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "Image sequence saving: " << dtime/1000 << " s" <<std::endl;
+
+
+            delete argsAnalysis;
+            delete preProcess;
+            delete stmsFilter;
+            delete postProcess;
+            break;
+        }
+
+        default:
+        {
+            delete argsAnalysis;
+
+            std::cout << std::endl << "Image dimensionality should be equal to 2 or 3.";
+            std::exit( EXIT_FAILURE );
+            break;
+        }
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/Src/STMS_GrayLevelFiltering_Spine.cxx b/Src/STMS_GrayLevelFiltering_Spine.cxx
new file mode 100755 (executable)
index 0000000..464374a
--- /dev/null
@@ -0,0 +1,181 @@
+#include <iomanip>
+#include <ctime>
+#include "itkImage.h"
+#include "itkSTMS_ArgumentsAnalysis_Spine.h"
+#include "itkSTMS_ImageSequenceToTemporalSet_Spine.h"
+#include "itkSTMS_TemporalSetToImageSequence_Spine.h"
+#include "itkSTMS_BlurringSTMS_Spine.h"
+
+
+typedef float PixelType;
+
+double gettime_hp()
+{
+    struct timespec timestamp;
+
+    clock_gettime(CLOCK_REALTIME, &timestamp);
+    return timestamp.tv_sec * 1000.0 + timestamp.tv_nsec * 1.0e-6;
+}
+
+// Only --expDescription and --outFolder parameters are compulsory.
+/* --image ../../itkSTMS/Data/Images/Simu/Simu1.nii --image ../../itkSTMS/Data/Images/Simu/Simu2.nii --image ../../itkSTMS/Data/Images/Simu/Simu3.nii
+--image ../../itkSTMS/Data/Images/Simu/Simu4.nii --image ../../itkSTMS/Data/Images/Simu/Simu5.nii --image ../../itkSTMS/Data/Images/Simu/Simu6.nii
+--image ../../itkSTMS/Data/Images/Simu/Simu7.nii --image ../../itkSTMS/Data/Images/Simu/Simu8.nii --outFolder ../../itkSTMS/Data/Images/Simu_Outputs-Spine/
+--imageDimension 2 --xScale 1000 --yScale 1000 --rScale 0.5 --mask ../../itkSTMS/Data/Images/Simu/Mask.nii --imageExtension .nii
+
+--image ../../itkSTMS/Data/Images/Simu/Simu1.nii --image ../../itkSTMS/Data/Images/Simu/Simu2.nii --image ../../itkSTMS/Data/Images/Simu/Simu3.nii
+--image ../../itkSTMS/Data/Images/Simu/Simu4.nii --image ../../itkSTMS/Data/Images/Simu/Simu5.nii --image ../../itkSTMS/Data/Images/Simu/Simu6.nii
+--image ../../itkSTMS/Data/Images/Simu/Simu7.nii --image ../../itkSTMS/Data/Images/Simu/Simu8.nii --outFolder ../../itkSTMS/Data/Images/Simu_Outputs-Spine/
+--imageDimension 2 --xScale 1000 --yScale 1000 --rScale 0.5 --imageExtension .nii
+*/
+int main(int argc, char **argv){
+    double dtime;
+
+    itkSTMS_Spine::itkSTMS_ArgumentsAnalysis* argsAnalysis
+            = new itkSTMS_Spine::itkSTMS_ArgumentsAnalysis(argc, argv);
+    argsAnalysis->Update();
+
+    itkSTMS_Spine::ParamsAnalysisOutputType* params
+            = argsAnalysis->GetSTMSParams();
+
+
+    switch(params->dim){
+        case 2:
+        {
+            typedef itk::Image< PixelType, 2 >     ImageType2D;
+            typedef itk::Image< unsigned int, 2 > MaskImageType2D;
+
+
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::IndexType            IndexType;
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::SpatialType          SpatialType;
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::IndexSampleSetType   IndexSampleSetType;
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::SpatialSampleSetType SpatialSampleSetType;
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >::RangeSampleSetType   RangeSampleSetType;
+
+            typedef itk::Image< IndexType, 2 >  ClassImageType2D;
+
+
+            dtime=gettime_hp();
+
+            itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D >* preProcess
+                    = new itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType2D, MaskImageType2D > ( params );
+            preProcess->GenerateDataSets();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "Characteristics extraction: " << dtime/1000 << " s" <<std::endl;
+
+            IndexSampleSetType*   indexSet   = preProcess->GetIndexSet();
+            IndexSampleSetType*   classSet   = preProcess->GetClassSet();
+            IndexSampleSetType*   weightsSet = preProcess->GetWeightsSet();
+            SpatialSampleSetType* spatialSet = preProcess->GetSpatialSet();
+            RangeSampleSetType*   rangeSet   = preProcess->GetRangeSet();
+
+
+            dtime=gettime_hp();
+
+            itkSTMS_Spine::itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType2D >* stmsFilter
+                    = new itkSTMS_Spine::itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType2D >
+                    (indexSet, classSet, weightsSet, spatialSet, rangeSet,  params );
+
+            stmsFilter->GenerateData();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "STMS filtering: " << dtime/1000 << " s" <<std::endl;
+
+
+
+            dtime=gettime_hp();
+
+            itkSTMS_Spine::itkSTMS_TemporalSetToImageSequence< ImageType2D, ClassImageType2D >* postProcess
+                    = new itkSTMS_Spine::itkSTMS_TemporalSetToImageSequence< ImageType2D, ClassImageType2D >(stmsFilter->GetClassMemory(),
+                                                                                                       stmsFilter->GetSpatialMemory(),
+                                                                                                       stmsFilter->GetRangeSet(),
+                                                                                                       params );
+
+            postProcess->GenerateImageSequence();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "Image sequence saving: " << dtime/1000 << " s" <<std::endl;
+
+            delete argsAnalysis;
+            delete preProcess;
+            delete stmsFilter;
+            delete postProcess;
+            break;
+        }
+
+        case 3:
+        {
+            typedef itk::Image< PixelType, 3 >     ImageType3D;
+            typedef itk::Image< unsigned int, 3 > MaskImageType3D;
+
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::IndexType            IndexType;
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::SpatialType          SpatialType;
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::IndexSampleSetType   IndexSampleSetType;
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::SpatialSampleSetType SpatialSampleSetType;
+            typedef itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >::RangeSampleSetType   RangeSampleSetType;
+
+
+            dtime=gettime_hp();
+
+            itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D >* preProcess
+                    = new itkSTMS_Spine::itkSTMS_ImageSequenceToTemporalSet< ImageType3D, MaskImageType3D > ( params );
+            preProcess->GenerateDataSets();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "Characteristics extraction: " << dtime/1000 << " s" <<std::endl;
+
+            IndexSampleSetType*   indexSet   = preProcess->GetIndexSet();
+            IndexSampleSetType*   classSet   = preProcess->GetClassSet();
+            IndexSampleSetType*   weightsSet = preProcess->GetWeightsSet();
+            SpatialSampleSetType* spatialSet = preProcess->GetSpatialSet();
+            RangeSampleSetType*   rangeSet   = preProcess->GetRangeSet();
+
+
+
+
+            dtime=gettime_hp();
+
+            itkSTMS_Spine::itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType3D >* stmsFilter
+                    = new itkSTMS_Spine::itkSTMS_BlurringSTMS< IndexType, SpatialType, PixelType, ImageType3D >
+                    (indexSet, classSet, weightsSet, spatialSet, rangeSet,  params );
+
+            stmsFilter->GenerateData();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "STMS filtering: " << dtime/1000 << " s" <<std::endl;
+
+
+            dtime=gettime_hp();
+
+            itkSTMS_Spine::itkSTMS_TemporalSetToImageSequence< ImageType3D, MaskImageType3D >* postProcess
+                    = new itkSTMS_Spine::itkSTMS_TemporalSetToImageSequence< ImageType3D, MaskImageType3D >(stmsFilter->GetClassMemory(),
+                                                                                                      stmsFilter->GetSpatialMemory(),
+                                                                                                      stmsFilter->GetRangeSet(),
+                                                                                                      params );
+
+            postProcess->GenerateImageSequence();
+
+            dtime = gettime_hp()-dtime;
+            std::cout<<std::endl<< std::setw(30) << std::left << "Image sequence saving: " << dtime/1000 << " s" <<std::endl;
+
+
+            delete argsAnalysis;
+            delete preProcess;
+            delete stmsFilter;
+            delete postProcess;
+            break;
+        }
+
+        default:
+        {
+            delete argsAnalysis;
+
+            std::cout << std::endl << "Image dimensionality should be equal to 2 or 3.";
+            std::exit( EXIT_FAILURE );
+            break;
+        }
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/Src/test_ArgumentsAnalysis.cxx b/Src/test_ArgumentsAnalysis.cxx
new file mode 100755 (executable)
index 0000000..ccf6fcd
--- /dev/null
@@ -0,0 +1,26 @@
+#include <string>
+#include "itkSTMS_ArgumentsAnalysis.h"
+
+//--expDescription ../xmlFile.xml --xScale 10 --yScale 10 --zScale 10 --rScale 1.0 --epsilon 0.1 --maxIt 50
+// Only --expDescription parameter is compulsory.
+
+int main(int argc, char **argv)
+{
+    itkSTMS::itkSTMS_ArgumentsAnalysis* argsAnalysis = new itkSTMS::itkSTMS_ArgumentsAnalysis(argc, argv);
+    argsAnalysis->Update();
+
+    itkSTMS::ParamsAnalysisOutputType* params = argsAnalysis->GetSTMSParams();
+
+
+    std::cout << params->expDescription << std::endl;
+    std::cout << params->xScale << std::endl;
+    std::cout << params->yScale << std::endl;
+    std::cout << params->zScale << std::endl;
+    std::cout << params->rScale << std::endl;
+    std::cout << params->epsilon << std::endl;
+    std::cout << params->maxIt << std::endl;
+
+
+    delete argsAnalysis;
+    return EXIT_SUCCESS;
+}
diff --git a/Src/test_ArgumentsAnalysis_Spine.cxx b/Src/test_ArgumentsAnalysis_Spine.cxx
new file mode 100755 (executable)
index 0000000..f34dcdc
--- /dev/null
@@ -0,0 +1,37 @@
+#include <string>
+#include "itkSTMS_ArgumentsAnalysis_Spine.h"
+
+
+// --image image1.nii --xScale 15.2 --image image2.nii --yScale 16.3 --zScale 17.4 --rScale 10.6 --mask mask.nii --image image3.nii --outFolder outFolder/ --epsilon 0.1 --imageDimension 2 --maxIt 20
+int main(int argc, char **argv)
+{
+    itkSTMS::itkSTMS_ArgumentsAnalysis* argsAnalysis = new itkSTMS::itkSTMS_ArgumentsAnalysis(argc, argv);
+    argsAnalysis->Update();
+
+    itkSTMS::ParamsAnalysisOutputType* params = argsAnalysis->GetSTMSParams();
+
+
+    std::cout << "images:"<<std::endl;
+
+    for (std::list<std::string>::iterator it =  params->images.begin(); it !=  params->images.end(); ++it)
+    {
+        std::cout<< *it << std::endl;
+    }
+
+    std::cout << std::endl << "x          :"<< params->spScales[0]   << std::endl<< std::endl;
+    std::cout << std::endl << "y          :"<< params->spScales[1]   << std::endl<< std::endl;
+    std::cout << std::endl << "z          :"<< params->spScales[2]   << std::endl<< std::endl;
+    std::cout << std::endl << "r          :"<< params->rScale        << std::endl<< std::endl;
+    std::cout << std::endl << "mask       :"<< params->mask          << std::endl<< std::endl;
+    std::cout << std::endl << "outFolder  :"<< params->outFolder     << std::endl<< std::endl;
+    std::cout << std::endl << "ntp        :"<< params->numTimePoints << std::endl<< std::endl;
+    std::cout << std::endl << "eps        :"<< params->epsilon       << std::endl<< std::endl;
+    std::cout << std::endl << "imDim      :"<< params->dim           << std::endl<< std::endl;
+    std::cout << std::endl << "maxIt      :"<< params->maxIt         << std::endl<< std::endl;
+    std::cout << std::endl << "merge      :"<< params->merge         << std::endl<< std::endl;
+
+    std::cout << std::endl << "1st element:"<< *params->images.begin()<< std::endl<< std::endl;
+
+    delete argsAnalysis;
+    return EXIT_SUCCESS;
+}
diff --git a/Src/test_parseXML.cxx b/Src/test_parseXML.cxx
new file mode 100755 (executable)
index 0000000..a7b9a27
--- /dev/null
@@ -0,0 +1,24 @@
+//#include <string>
+//#include "itkDOMNodeXMLReader.h"
+//#include "itkFancyString.h"
+
+#include <string>
+#include "itkSTMS_XMLFileParser.h"
+
+int main(int argc, char **argv)
+{
+    std::string fileName = "/run/media/mure/HDD/Recherche/These/CVS/Mure/Dev/Cpp/STMS/Data/G1_Parser.xml";
+
+    itkSTMS::itkSTMS_XMLFileParser* parser = new itkSTMS::itkSTMS_XMLFileParser();
+    parser->SetFileName( fileName );
+    parser->Update();
+
+    itkSTMS::ParserOutputType* expDescritpion = parser->GetXMLParams();
+
+    std::cout << expDescritpion->experimentPath <<std::endl;
+
+
+
+    delete parser;
+    return EXIT_SUCCESS;
+}