From 2303cf8e29ab3d6f1ecc641af2350fa2cac7d073 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9line=20=20TREBEAU?= <celine.trebeau@pasteur.fr>
Date: Mon, 9 Nov 2020 10:58:48 +0100
Subject: [PATCH] Code simplification Creation of classes for user parameters
 (basic and advanced) Modification of existant classes (Local variables
 removed to refer to global variables) Regroupement of classes to avoid code
 repetition (LocalExtremaDetection) Removal of unnecessary classes (stored in
 snippets)

---
 .editorconfig                                 | 283 +++++++++++
 README.md                                     |  69 +++
 src/main/java/StartingOSStats.java            |  16 +-
 src/main/java/SurfacesExtractionAnalyse.java  |  27 --
 .../ida/zellige/command/ZelligeCommand.java   |  93 ----
 .../ida/zellige/command/ZelligeCommand2.java  |  18 -
 .../command/ZelligePluginTestDrive.java       |  34 --
 .../ida/zellige/gui/AdvancedSettings.form     | 203 --------
 .../ida/zellige/gui/AdvancedSettings.java     |  90 ----
 .../fr/pasteur/ida/zellige/gui/Settings.form  | 439 ------------------
 .../fr/pasteur/ida/zellige/gui/Settings.java  | 107 -----
 .../fr/pasteur/ida/zellige/gui/ZSpinner.java  |  62 ---
 .../ida/zellige/gui/ZelligeController.java    | 195 --------
 .../pasteur/ida/zellige/jzy3D/OSDisplay.java  |  18 +-
 .../ida/zellige/jzy3D/ScatterDemo.java        |  54 ---
 .../ida/zellige/jzy3D/ScatterDemo2.java       |  50 --
 .../ida/zellige/jzy3D/ScatterDemo6.java       |  65 ---
 .../ida/zellige/jzy3D/SurfaceDisplay.java     |   4 +-
 .../fr/pasteur/ida/zellige/main/Main.java     |  24 +-
 .../construction/OSConstruction.java          | 244 ----------
 .../construction/OSEListConstruction.java     | 272 +++++++++++
 .../ReferenceSurfaceExtraction.java           | 294 ++++++++++++
 .../construction}/SurfacePixelSelection.java  |  44 +-
 .../construction/SurfacesExtraction.java      | 338 --------------
 .../construction/SurfacesReconstruction.java  | 171 ++++---
 .../element/ReferenceSurface.java             |  88 ++++
 .../surfaceConstruction/element/Surface.java  |  40 +-
 .../element/{os => ose}/OSE.java              | 120 +----
 .../{os/OSList.java => ose/OSEList.java}      |   6 +-
 .../{os => ose}/OSEStartingStatus.java        |   2 +-
 .../element/surfaceLine/SurfaceLine.java      |   3 +-
 .../element/surfaceLine/SurfaceLineX.java     |   2 +-
 .../element/surfaceLine/SurfaceLineY.java     |   2 +-
 .../parameters/AdvancedUserParameters.java    |  57 +++
 .../parameters/DisplayParameter.java          |  40 ++
 .../parameters/UserParameters.java            |  72 +++
 .../ida/zellige/utils/BasePixFilter.java      | 126 -----
 .../pasteur/ida/zellige/utils/Filter2D.java   | 182 --------
 .../ida/zellige/utils/Histogram2D.java        |  81 ----
 .../ida/zellige/utils/Interpolation.java      | 318 +++++++------
 .../ida/zellige/utils/IsolatedPixFilter.java  | 118 -----
 .../zellige/utils/LocalExtremaDetection.java  | 154 ++++++
 .../zellige/utils/LocalMaximumDetection.java  | 174 -------
 .../zellige/utils/LocalMinimumDetection.java  | 173 -------
 .../ida/zellige/utils/LocalOtsuTest.java      |  26 --
 .../utils/MaximumAmplitudeClassification.java |   9 +-
 .../zellige/utils/MaximumVarianceFilter.java  |  52 ---
 .../ida/zellige/utils/MedianSkipZeros.java    | 197 --------
 .../fr/pasteur/ida/zellige/utils/Otsu.java    |  52 +--
 .../ida/zellige/utils/StackProjection.java    |   2 +-
 .../pasteur/ida/zellige/utils/Threshold.java  |   2 +-
 .../ida/zellige/utils/VarianceFilter2D.java   | 100 ----
 52 files changed, 1706 insertions(+), 3706 deletions(-)
 create mode 100644 .editorconfig
 create mode 100644 README.md
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/command/ZelligeCommand.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/command/ZelligeCommand2.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/command/ZelligePluginTestDrive.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/gui/AdvancedSettings.form
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/gui/AdvancedSettings.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/gui/Settings.form
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/gui/Settings.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/gui/ZSpinner.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/gui/ZelligeController.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo2.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo6.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/OSConstruction.java
 create mode 100644 src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/OSEListConstruction.java
 create mode 100644 src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/ReferenceSurfaceExtraction.java
 rename src/main/java/fr/pasteur/ida/zellige/{utils => surfaceConstruction/construction}/SurfacePixelSelection.java (77%)
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacesExtraction.java
 create mode 100644 src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ReferenceSurface.java
 rename src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/{os => ose}/OSE.java (67%)
 rename src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/{os/OSList.java => ose/OSEList.java} (91%)
 rename src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/{os => ose}/OSEStartingStatus.java (93%)
 create mode 100644 src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/AdvancedUserParameters.java
 create mode 100644 src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/DisplayParameter.java
 create mode 100644 src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/UserParameters.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/BasePixFilter.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/Filter2D.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/Histogram2D.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/IsolatedPixFilter.java
 create mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/LocalExtremaDetection.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/LocalMaximumDetection.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/LocalMinimumDetection.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/LocalOtsuTest.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/MaximumVarianceFilter.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/MedianSkipZeros.java
 delete mode 100644 src/main/java/fr/pasteur/ida/zellige/utils/VarianceFilter2D.java

diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..88e34589
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,283 @@
+[*]
+charset = utf-8
+end_of_line = crlf
+indent_size = 4
+indent_style = space
+insert_final_newline = false
+max_line_length = 120
+tab_width = 4
+ij_continuation_indent_size = 8
+ij_formatter_off_tag = @formatter:off
+ij_formatter_on_tag = @formatter:on
+ij_formatter_tags_enabled = false
+ij_smart_tabs = false
+ij_wrap_on_typing = false
+
+[*.java]
+ij_java_align_consecutive_assignments = false
+ij_java_align_consecutive_variable_declarations = false
+ij_java_align_group_field_declarations = false
+ij_java_align_multiline_annotation_parameters = false
+ij_java_align_multiline_array_initializer_expression = false
+ij_java_align_multiline_assignment = false
+ij_java_align_multiline_binary_operation = false
+ij_java_align_multiline_chained_methods = false
+ij_java_align_multiline_extends_list = false
+ij_java_align_multiline_for = true
+ij_java_align_multiline_method_parentheses = false
+ij_java_align_multiline_parameters = true
+ij_java_align_multiline_parameters_in_calls = false
+ij_java_align_multiline_parenthesized_expression = false
+ij_java_align_multiline_records = true
+ij_java_align_multiline_resources = true
+ij_java_align_multiline_ternary_operation = false
+ij_java_align_multiline_text_blocks = false
+ij_java_align_multiline_throws_list = false
+ij_java_align_subsequent_simple_methods = false
+ij_java_align_throws_keyword = false
+ij_java_annotation_parameter_wrap = off
+ij_java_array_initializer_new_line_after_left_brace = false
+ij_java_array_initializer_right_brace_on_new_line = false
+ij_java_array_initializer_wrap = off
+ij_java_assert_statement_colon_on_next_line = false
+ij_java_assert_statement_wrap = off
+ij_java_assignment_wrap = off
+ij_java_binary_operation_sign_on_next_line = false
+ij_java_binary_operation_wrap = off
+ij_java_blank_lines_after_anonymous_class_header = 0
+ij_java_blank_lines_after_class_header = 0
+ij_java_blank_lines_after_imports = 1
+ij_java_blank_lines_after_package = 1
+ij_java_blank_lines_around_class = 1
+ij_java_blank_lines_around_field = 0
+ij_java_blank_lines_around_field_in_interface = 0
+ij_java_blank_lines_around_initializer = 1
+ij_java_blank_lines_around_method = 1
+ij_java_blank_lines_around_method_in_interface = 1
+ij_java_blank_lines_before_class_end = 0
+ij_java_blank_lines_before_imports = 1
+ij_java_blank_lines_before_method_body = 0
+ij_java_blank_lines_before_package = 0
+ij_java_block_brace_style = next_line
+ij_java_block_comment_at_first_column = true
+ij_java_call_parameters_new_line_after_left_paren = false
+ij_java_call_parameters_right_paren_on_new_line = false
+ij_java_call_parameters_wrap = off
+ij_java_case_statement_on_separate_line = true
+ij_java_catch_on_new_line = true
+ij_java_class_annotation_wrap = split_into_lines
+ij_java_class_brace_style = next_line
+ij_java_class_count_to_use_import_on_demand = 5
+ij_java_class_names_in_javadoc = 1
+ij_java_do_not_indent_top_level_class_members = false
+ij_java_do_not_wrap_after_single_annotation = false
+ij_java_do_while_brace_force = always
+ij_java_doc_add_blank_line_after_description = true
+ij_java_doc_add_blank_line_after_param_comments = false
+ij_java_doc_add_blank_line_after_return = false
+ij_java_doc_add_p_tag_on_empty_lines = true
+ij_java_doc_align_exception_comments = true
+ij_java_doc_align_param_comments = true
+ij_java_doc_do_not_wrap_if_one_line = false
+ij_java_doc_enable_formatting = true
+ij_java_doc_enable_leading_asterisks = true
+ij_java_doc_indent_on_continuation = false
+ij_java_doc_keep_empty_lines = true
+ij_java_doc_keep_empty_parameter_tag = true
+ij_java_doc_keep_empty_return_tag = true
+ij_java_doc_keep_empty_throws_tag = true
+ij_java_doc_keep_invalid_tags = true
+ij_java_doc_param_description_on_new_line = false
+ij_java_doc_preserve_line_breaks = false
+ij_java_doc_use_throws_not_exception_tag = true
+ij_java_else_on_new_line = true
+ij_java_enum_constants_wrap = off
+ij_java_extends_keyword_wrap = off
+ij_java_extends_list_wrap = off
+ij_java_field_annotation_wrap = split_into_lines
+ij_java_finally_on_new_line = true
+ij_java_for_brace_force = always
+ij_java_for_statement_new_line_after_left_paren = false
+ij_java_for_statement_right_paren_on_new_line = false
+ij_java_for_statement_wrap = off
+ij_java_generate_final_locals = false
+ij_java_generate_final_parameters = false
+ij_java_if_brace_force = always
+ij_java_imports_layout = *,|,javax.**,java.**,|,$*
+ij_java_indent_case_from_switch = true
+ij_java_insert_inner_class_imports = false
+ij_java_insert_override_annotation = true
+ij_java_keep_blank_lines_before_right_brace = 2
+ij_java_keep_blank_lines_between_package_declaration_and_header = 2
+ij_java_keep_blank_lines_in_code = 2
+ij_java_keep_blank_lines_in_declarations = 2
+ij_java_keep_control_statement_in_one_line = true
+ij_java_keep_first_column_comment = true
+ij_java_keep_indents_on_empty_lines = false
+ij_java_keep_line_breaks = true
+ij_java_keep_multiple_expressions_in_one_line = false
+ij_java_keep_simple_blocks_in_one_line = false
+ij_java_keep_simple_classes_in_one_line = false
+ij_java_keep_simple_lambdas_in_one_line = false
+ij_java_keep_simple_methods_in_one_line = false
+ij_java_label_indent_absolute = false
+ij_java_label_indent_size = 0
+ij_java_lambda_brace_style = next_line
+ij_java_layout_static_imports_separately = true
+ij_java_line_comment_add_space = false
+ij_java_line_comment_at_first_column = true
+ij_java_method_annotation_wrap = split_into_lines
+ij_java_method_brace_style = next_line
+ij_java_method_call_chain_wrap = off
+ij_java_method_parameters_new_line_after_left_paren = false
+ij_java_method_parameters_right_paren_on_new_line = false
+ij_java_method_parameters_wrap = off
+ij_java_modifier_list_wrap = false
+ij_java_names_count_to_use_import_on_demand = 3
+ij_java_new_line_after_lparen_in_record_header = false
+ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
+ij_java_parameter_annotation_wrap = off
+ij_java_parentheses_expression_new_line_after_left_paren = false
+ij_java_parentheses_expression_right_paren_on_new_line = false
+ij_java_place_assignment_sign_on_next_line = false
+ij_java_prefer_longer_names = true
+ij_java_prefer_parameters_wrap = false
+ij_java_record_components_wrap = normal
+ij_java_repeat_synchronized = true
+ij_java_replace_instanceof_and_cast = false
+ij_java_replace_null_check = true
+ij_java_replace_sum_lambda_with_method_ref = true
+ij_java_resource_list_new_line_after_left_paren = false
+ij_java_resource_list_right_paren_on_new_line = false
+ij_java_resource_list_wrap = normal
+ij_java_rparen_on_new_line_in_record_header = false
+ij_java_space_after_closing_angle_bracket_in_type_argument = false
+ij_java_space_after_colon = true
+ij_java_space_after_comma = true
+ij_java_space_after_comma_in_type_arguments = true
+ij_java_space_after_for_semicolon = true
+ij_java_space_after_quest = true
+ij_java_space_after_type_cast = true
+ij_java_space_before_annotation_array_initializer_left_brace = false
+ij_java_space_before_annotation_parameter_list = false
+ij_java_space_before_array_initializer_left_brace = false
+ij_java_space_before_catch_keyword = true
+ij_java_space_before_catch_left_brace = true
+ij_java_space_before_catch_parentheses = true
+ij_java_space_before_class_left_brace = true
+ij_java_space_before_colon = true
+ij_java_space_before_colon_in_foreach = true
+ij_java_space_before_comma = false
+ij_java_space_before_do_left_brace = true
+ij_java_space_before_else_keyword = true
+ij_java_space_before_else_left_brace = true
+ij_java_space_before_finally_keyword = true
+ij_java_space_before_finally_left_brace = true
+ij_java_space_before_for_left_brace = true
+ij_java_space_before_for_parentheses = true
+ij_java_space_before_for_semicolon = false
+ij_java_space_before_if_left_brace = true
+ij_java_space_before_if_parentheses = true
+ij_java_space_before_method_call_parentheses = false
+ij_java_space_before_method_left_brace = true
+ij_java_space_before_method_parentheses = false
+ij_java_space_before_opening_angle_bracket_in_type_parameter = false
+ij_java_space_before_quest = true
+ij_java_space_before_switch_left_brace = true
+ij_java_space_before_switch_parentheses = true
+ij_java_space_before_synchronized_left_brace = true
+ij_java_space_before_synchronized_parentheses = true
+ij_java_space_before_try_left_brace = true
+ij_java_space_before_try_parentheses = true
+ij_java_space_before_type_parameter_list = false
+ij_java_space_before_while_keyword = true
+ij_java_space_before_while_left_brace = true
+ij_java_space_before_while_parentheses = true
+ij_java_space_inside_one_line_enum_braces = false
+ij_java_space_within_empty_array_initializer_braces = false
+ij_java_space_within_empty_method_call_parentheses = false
+ij_java_space_within_empty_method_parentheses = false
+ij_java_spaces_around_additive_operators = true
+ij_java_spaces_around_assignment_operators = true
+ij_java_spaces_around_bitwise_operators = true
+ij_java_spaces_around_equality_operators = true
+ij_java_spaces_around_lambda_arrow = true
+ij_java_spaces_around_logical_operators = true
+ij_java_spaces_around_method_ref_dbl_colon = false
+ij_java_spaces_around_multiplicative_operators = true
+ij_java_spaces_around_relational_operators = true
+ij_java_spaces_around_shift_operators = true
+ij_java_spaces_around_type_bounds_in_type_parameters = true
+ij_java_spaces_around_unary_operator = true
+ij_java_spaces_within_angle_brackets = true
+ij_java_spaces_within_annotation_parentheses = true
+ij_java_spaces_within_array_initializer_braces = true
+ij_java_spaces_within_braces = true
+ij_java_spaces_within_brackets = true
+ij_java_spaces_within_cast_parentheses = true
+ij_java_spaces_within_catch_parentheses = true
+ij_java_spaces_within_for_parentheses = true
+ij_java_spaces_within_if_parentheses = true
+ij_java_spaces_within_method_call_parentheses = true
+ij_java_spaces_within_method_parentheses = true
+ij_java_spaces_within_parentheses = true
+ij_java_spaces_within_switch_parentheses = true
+ij_java_spaces_within_synchronized_parentheses = true
+ij_java_spaces_within_try_parentheses = true
+ij_java_spaces_within_while_parentheses = true
+ij_java_special_else_if_treatment = true
+ij_java_subclass_name_suffix = Impl
+ij_java_ternary_operation_signs_on_next_line = false
+ij_java_ternary_operation_wrap = off
+ij_java_test_name_suffix = Test
+ij_java_throws_keyword_wrap = off
+ij_java_throws_list_wrap = off
+ij_java_use_external_annotations = false
+ij_java_use_fq_class_names = false
+ij_java_use_relative_indents = false
+ij_java_use_single_class_imports = true
+ij_java_variable_annotation_wrap = off
+ij_java_visibility = public
+ij_java_while_brace_force = always
+ij_java_while_on_new_line = false
+ij_java_wrap_comments = false
+ij_java_wrap_first_method_in_call_chain = false
+ij_java_wrap_long_lines = false
+
+[*.properties]
+ij_properties_align_group_field_declarations = false
+ij_properties_keep_blank_lines = false
+ij_properties_key_value_delimiter = equals
+ij_properties_spaces_around_key_value_delimiter = false
+
+[.editorconfig]
+ij_editorconfig_align_group_field_declarations = false
+ij_editorconfig_space_after_colon = false
+ij_editorconfig_space_after_comma = true
+ij_editorconfig_space_before_colon = false
+ij_editorconfig_space_before_comma = false
+ij_editorconfig_spaces_around_assignment_operators = true
+
+[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.jspx,*.pom,*.rng,*.tagx,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
+ij_xml_align_attributes = true
+ij_xml_align_text = false
+ij_xml_attribute_wrap = normal
+ij_xml_block_comment_at_first_column = true
+ij_xml_keep_blank_lines = 2
+ij_xml_keep_indents_on_empty_lines = false
+ij_xml_keep_line_breaks = true
+ij_xml_keep_line_breaks_in_text = true
+ij_xml_keep_whitespaces = false
+ij_xml_keep_whitespaces_around_cdata = preserve
+ij_xml_keep_whitespaces_inside_cdata = false
+ij_xml_line_comment_at_first_column = true
+ij_xml_space_after_tag_name = false
+ij_xml_space_around_equals_in_attribute = false
+ij_xml_space_inside_empty_tag = false
+ij_xml_text_wrap = normal
+ij_xml_use_custom_settings = false
+
+[{*.yaml,*.yml}]
+indent_size = 2
+ij_yaml_keep_indents_on_empty_lines = false
+ij_yaml_keep_line_breaks = true
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..ed1286ba
--- /dev/null
+++ b/README.md
@@ -0,0 +1,69 @@
+# zellige-core
+ 
+
+
+ ## Workflow
+ 
+- I. Input of the image.
+
+     - The image has to be a z-stack.
+
+
+ - II. Pretreatment of the image.
+
+     - Conversion of pixel values into FloatType
+
+     - Image denoising with an anisotropic gaussian convolution
+
+     - Normalization of the histogram (pixel value between 0 and 255).
+ 
+- III. Local maximum search and selection according to user specified minimum threshold parameter (percent) and dilation (sigma).
+
+     - Local maximum detection using partial derivative
+
+     - Grid of local thresholds using Otsu thresholding method.
+
+     - Maxima selection according to local thresholds
+
+     - Dilatation of the resulting image
+
+     - New local maximum detection due to previous smoothing
+
+     - Conversion of the coordinates found into a  2D Pixels array
+ 
+
+
+ - IV. Construction of the OS in dimension Y */
+
+     - Construction of OS .
+ 
+- V. Construction of the surfaces in dimension X.*/
+
+ Construction of Surface. Merging of those if necessary.
+ 
+- VI. Reconstruction of the tempSurface found in dimension 1.
+
+     - Construction of the previous Surface objects in the other dimension if they contain duplicates.  
+
+         Merging if necessary.
+
+
+ - VII. Production of the height map and referenceSurface according to the delta.
+ 
+## Build
+ 
+````
+
+ mvn clean install
+
+ ````
+ 
+## Usage 
+ 
+````
+ 
+````
+ 
+## Pipelines
+ 
+https://gitlab.pasteur.fr/ctrebeau/zellige-core/-/pipelines
\ No newline at end of file
diff --git a/src/main/java/StartingOSStats.java b/src/main/java/StartingOSStats.java
index 9c0c4c3f..1217020f 100644
--- a/src/main/java/StartingOSStats.java
+++ b/src/main/java/StartingOSStats.java
@@ -1,5 +1,7 @@
-import fr.pasteur.ida.zellige.surfaceConstruction.construction.SurfacesExtraction;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSE;
+import fr.pasteur.ida.zellige.surfaceConstruction.parameters.AdvancedUserParameters;
+import fr.pasteur.ida.zellige.surfaceConstruction.construction.ReferenceSurfaceExtraction;
+import fr.pasteur.ida.zellige.surfaceConstruction.parameters.UserParameters;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSE;
 import fr.pasteur.ida.zellige.utils.TestMIP;
 import ij.IJ;
 import ij.ImageJ;
@@ -88,9 +90,8 @@ public class StartingOSStats
         int delta = Integer.parseInt( args[ 7 ] );
         /* End of parameters. */
 
-
-
-        /* End of  Print parameters.*/
+        UserParameters userParameters = new UserParameters( amplitude, otsu, sigmas, delta, "MIP" );
+        AdvancedUserParameters advancedUserParameters = new AdvancedUserParameters( k1, percent1, k2, percent2 );
 
         IJ.log("Type: "+ imgPlus.firstElement().getClass().toGenericString());
 
@@ -98,10 +99,7 @@ public class StartingOSStats
         {
             ImageJFunctions.show( stackImage, "original" );
             ImageJFunctions.show( TestMIP.findMIP( stackImage, stackImage.factory() ), "MIP" );
-
-
-            SurfacesExtraction.extract(stackImage, stackImage.factory(),amplitude, otsu, sigmas, false, delta, false,
-                    false, true, "MIP", k1, percent1, k2, percent2);
+            new ReferenceSurfaceExtraction<>( stackImage, stackImage.factory(),userParameters, advancedUserParameters );
         }
         else
         {
diff --git a/src/main/java/SurfacesExtractionAnalyse.java b/src/main/java/SurfacesExtractionAnalyse.java
index ed2a32fd..e37a8e35 100644
--- a/src/main/java/SurfacesExtractionAnalyse.java
+++ b/src/main/java/SurfacesExtractionAnalyse.java
@@ -1,30 +1,3 @@
-import fr.pasteur.ida.zellige.exception.FirstRoundConstructionException;
-import fr.pasteur.ida.zellige.exception.NoSurfaceFoundException;
-import fr.pasteur.ida.zellige.jzy3D.LocalMaximumsDisplay;
-import fr.pasteur.ida.zellige.jzy3D.OSDisplay;
-import fr.pasteur.ida.zellige.jzy3D.SurfaceDisplay;
-import fr.pasteur.ida.zellige.surfaceConstruction.construction.OSConstruction;
-import fr.pasteur.ida.zellige.surfaceConstruction.construction.SurfacesReconstruction;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Surface;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSE;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSEStartingStatus;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSList;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine.SurfaceLine;
-import fr.pasteur.ida.zellige.utils.*;
-import io.scif.img.IO;
-import io.scif.img.SCIFIOImgPlus;
-import net.imglib2.img.Img;
-import net.imglib2.img.display.imagej.ImageJFunctions;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.logic.BitType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.type.numeric.integer.UnsignedShortType;
-import org.jzy3d.analysis.AnalysisLauncher;
-
-import java.util.ArrayList;
-
-
 public class SurfacesExtractionAnalyse
 {
 //    public static < T extends RealType < T > & NativeType < T > > void main( String[] args )
diff --git a/src/main/java/fr/pasteur/ida/zellige/command/ZelligeCommand.java b/src/main/java/fr/pasteur/ida/zellige/command/ZelligeCommand.java
deleted file mode 100644
index b4768efe..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/command/ZelligeCommand.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package fr.pasteur.ida.zellige.command;
-
-import ij.IJ;
-import net.imagej.Dataset;
-import net.imagej.ImgPlus;
-import net.imagej.display.ImageDisplayService;
-import net.imagej.ops.OpService;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.util.Util;
-import org.scijava.ItemIO;
-import org.scijava.command.ContextCommand;
-import org.scijava.log.LogService;
-import org.scijava.plugin.Parameter;
-import org.scijava.plugin.Plugin;
-
-import java.util.ArrayList;
-
-@Plugin ( type = ZelligeCommand.class, name = "Zellige", menuPath = "Plugins > Process > Zellige" )
-public class ZelligeCommand< T extends RealType < T > & NativeType < T > > extends ContextCommand
-{
-
-    @Parameter
-    private ImageDisplayService imageDisplayService;
-
-    @Parameter
-    private LogService logService;
-
-    @Parameter
-    protected OpService ops;
-
-    @Parameter
-    private int sigma;
-
-    @Parameter
-    private int localThreshold;
-
-    @Parameter
-    private int globalThreshold;
-
-    @Parameter
-    private int delta;
-
-    @Parameter(type = ItemIO.OUTPUT)
-    ArrayList < RandomAccessibleInterval < T > > surfaces;
-
-    @Override
-    public void run()
-    {
-        /*
-         * Get current dataset.
-         */
-
-        Dataset dataset = imageDisplayService.getActiveDataset();
-        if ( null == dataset )
-        {
-            logService.error( "Please open an image before running Zellige." );
-            return;
-        }
-        /*
-         * Wrap it into an ImgLib2 'Plus' image.
-         */
-        @SuppressWarnings( "unchecked" )
-        ImgPlus < T > img = ( ImgPlus< T > ) dataset.getImgPlus();
-
-        long[] dims = new long[dataset.numDimensions()];
-        dataset.dimensions(dims);
-
-        IJ.log( "Zellige received the image: " + img.getName() );
-        IJ.log( "Size: " + Util.printInterval( img ) );
-        IJ.log( "Type: " + img.firstElement().getClass().toGenericString() );
-        IJ.log( "Dimensionality: " + img.numDimensions() + "D" );
-        for ( int d = 0; d < img.numDimensions(); d++ )
-            IJ.log( " - dimension " + d + ": [" + img.axis( d ).type() + "], 1 unit = " + img.averageScale( d ) + " " + img.axis( d ).unit() );
-        if ( img.numDimensions() == 3 )// Is it a stack ?
-        {
-//            SurfacesExtraction <T > extraction =
-//                    new SurfacesExtraction <>( img, localThreshold, globalThreshold, sigma, delta );
-//            surfaces = extraction.extract();
-        }
-        else
-        {
-            IJ.log( " This image has to be a z-stack ! " );
-        }
-        IJ.log(" Number of surfaces found : " + surfaces.size());
-    }
-}
-
-
-
-
-
diff --git a/src/main/java/fr/pasteur/ida/zellige/command/ZelligeCommand2.java b/src/main/java/fr/pasteur/ida/zellige/command/ZelligeCommand2.java
deleted file mode 100644
index 30575cb2..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/command/ZelligeCommand2.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package fr.pasteur.ida.zellige.command;
-
-import fr.pasteur.ida.zellige.gui.ZelligeController;
-import org.scijava.command.ContextCommand;
-import org.scijava.plugin.Plugin;
-
-
-@Plugin( type = fr.pasteur.ida.zellige.command.ZelligeCommand.class, name = "Zellige", menuPath = "Plugins > Process > Zellige" )
-public class ZelligeCommand2 extends ContextCommand
-{
-
-
-    @Override
-    public void run()
-    {
-        new ZelligeController( context() );
-    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/command/ZelligePluginTestDrive.java b/src/main/java/fr/pasteur/ida/zellige/command/ZelligePluginTestDrive.java
deleted file mode 100644
index 32e3f46b..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/command/ZelligePluginTestDrive.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package fr.pasteur.ida.zellige.command;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.FileSystems;
-
-
-import net.imagej.ImageJ;
-
-public class ZelligePluginTestDrive
-{
-
-    public static void main( String[] args ) throws IOException
-    {
-        String currentFolder = FileSystems.getDefault()
-                .getPath( "" )
-                .toAbsolutePath()
-                .toString();
-        String imageFilePath = "doc/STK_crop.tif";
-
-        // Launch ImageJ.
-        ImageJ ij = new ImageJ();
-        ij.launch( args );
-
-        // Load the image.
-        Object obj = ij.io().open( new File( currentFolder, imageFilePath ).getAbsolutePath() );
-
-        // Display it.
-        ij.ui().show( obj );
-
-        ij.command().run( ZelligeCommand2.class, true );
-    }
-
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/AdvancedSettings.form b/src/main/java/fr/pasteur/ida/zellige/gui/AdvancedSettings.form
deleted file mode 100644
index ec7eb2db..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/gui/AdvancedSettings.form
+++ /dev/null
@@ -1,203 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="fr.pasteur.ida.zellige.gui.AdvancedSettings">
-  <grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-    <margin top="10" left="10" bottom="10" right="10"/>
-    <constraints>
-      <xy x="48" y="54" width="436" height="204"/>
-    </constraints>
-    <properties/>
-    <border type="none"/>
-    <children>
-      <grid id="94766" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-        <margin top="0" left="0" bottom="0" right="0"/>
-        <constraints>
-          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties/>
-        <border type="none"/>
-        <children>
-          <hspacer id="98af6">
-            <constraints>
-              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-            </constraints>
-          </hspacer>
-          <grid id="9538f" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="true" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="e7465" class="javax.swing.JButton" binding="buttonOK">
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <text value="OK"/>
-                </properties>
-              </component>
-              <component id="5723f" class="javax.swing.JButton" binding="buttonCancel">
-                <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <text value="Cancel"/>
-                </properties>
-              </component>
-            </children>
-          </grid>
-        </children>
-      </grid>
-      <grid id="e3588" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-        <margin top="0" left="0" bottom="0" right="0"/>
-        <constraints>
-          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties/>
-        <border type="none"/>
-        <children>
-          <grid id="6c1a9" binding="panel1" default-binding="true" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <grid id="827a0" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="79d5c" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="OS minimum size"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="81448" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <grid id="bcc3f" class="fr.pasteur.ida.zellige.gui.ZSpinner" binding="osMinimumSize" custom-create="true" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                    <margin top="0" left="0" bottom="0" right="0"/>
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties/>
-                    <border type="none"/>
-                    <children/>
-                  </grid>
-                </children>
-              </grid>
-              <grid id="1f74d" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="4f849" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="First round construction"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="7357a" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <grid id="c4271" class="fr.pasteur.ida.zellige.gui.ZSpinner" binding="firstRound" custom-create="true" default-binding="true" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                    <margin top="0" left="0" bottom="0" right="0"/>
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties/>
-                    <border type="none"/>
-                    <children/>
-                  </grid>
-                </children>
-              </grid>
-              <grid id="df249" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="5f03f" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="Second round construction"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="b507b" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <grid id="71495" class="fr.pasteur.ida.zellige.gui.ZSpinner" binding="secondRound" custom-create="true" default-binding="true" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                    <margin top="0" left="0" bottom="0" right="0"/>
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties/>
-                    <border type="none"/>
-                    <children/>
-                  </grid>
-                </children>
-              </grid>
-            </children>
-          </grid>
-          <grid id="9aaf0" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="cb7e3" class="javax.swing.JLabel">
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <text value="OS minimum size"/>
-                </properties>
-              </component>
-            </children>
-          </grid>
-        </children>
-      </grid>
-    </children>
-  </grid>
-</form>
diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/AdvancedSettings.java b/src/main/java/fr/pasteur/ida/zellige/gui/AdvancedSettings.java
deleted file mode 100644
index 34d2a93e..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/gui/AdvancedSettings.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package fr.pasteur.ida.zellige.gui;
-
-import javax.swing.*;
-import java.awt.event.*;
-
-public class AdvancedSettings extends JDialog
-{
-    private JPanel contentPane;
-    private JButton buttonOK;
-    private JButton buttonCancel;
-    private JPanel panel1;
-    private ZSpinner firstRound;
-    private ZSpinner secondRound;
-    private ZSpinner osMinimumSize;
-
-    public AdvancedSettings()
-    {
-        setContentPane( contentPane );
-        setModal( true );
-        getRootPane().setDefaultButton( buttonOK );
-
-        buttonOK.addActionListener( new ActionListener()
-        {
-            public void actionPerformed( ActionEvent e )
-            {
-                onOK();
-            }
-        } );
-
-        buttonCancel.addActionListener( new ActionListener()
-        {
-            public void actionPerformed( ActionEvent e )
-            {
-                onCancel();
-            }
-        } );
-
-        // call onCancel() when cross is clicked
-        setDefaultCloseOperation( DO_NOTHING_ON_CLOSE );
-        addWindowListener( new WindowAdapter()
-        {
-            public void windowClosing( WindowEvent e )
-            {
-                onCancel();
-            }
-        } );
-
-        // call onCancel() on ESCAPE
-        contentPane.registerKeyboardAction( new ActionListener()
-        {
-            public void actionPerformed( ActionEvent e )
-            {
-                onCancel();
-            }
-        }, KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0 ), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
-        this.pack();
-//        this.setVisible( false );
-    }
-
-    private void createUIComponents()
-    {
-        firstRound = new ZSpinner( "first round construction value", 0, 2000, 70, 10 );
-        firstRound.setDefaultRange( 20, 70 );
-        secondRound = new ZSpinner( "second round construction value", 0, 2000, 70, 10 );
-        secondRound.setDefaultRange( 20, 70 );
-        osMinimumSize = new ZSpinner( "OS Minimum size", 1, 1000, 3, 1 );
-        osMinimumSize.setDefaultRange( 2, 30 );
-
-    }
-
-    private void onOK()
-    {
-        // add your code here
-        dispose();
-    }
-
-    private void onCancel()
-    {
-        // add your code here if necessary
-        dispose();
-    }
-
-    public static void main( String[] args )
-    {
-        AdvancedSettings dialog = new AdvancedSettings();
-        dialog.pack();
-        dialog.setVisible( true );
-        System.exit( 0 );
-    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/Settings.form b/src/main/java/fr/pasteur/ida/zellige/gui/Settings.form
deleted file mode 100644
index a6a3eccb..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/gui/Settings.form
+++ /dev/null
@@ -1,439 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="fr.pasteur.ida.zellige.gui.Settings">
-  <grid id="27dc6" binding="panel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-    <margin top="20" left="20" bottom="20" right="20"/>
-    <constraints>
-      <xy x="20" y="20" width="362" height="535"/>
-    </constraints>
-    <properties/>
-    <border type="none"/>
-    <children>
-      <grid id="2525f" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-        <margin top="0" left="0" bottom="0" right="0"/>
-        <constraints>
-          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties/>
-        <border type="none"/>
-        <children>
-          <grid id="a5b1b" layout-manager="FlowLayout" hgap="5" vgap="5" flow-align="1">
-            <constraints>
-              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="78478" class="javax.swing.JLabel">
-                <constraints/>
-                <properties>
-                  <text value="Surface extraction settings"/>
-                </properties>
-              </component>
-            </children>
-          </grid>
-          <grid id="3c75" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <grid id="59c6e" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="f48c3" class="javax.swing.JButton" binding="advancedSettingsButton" default-binding="true">
-                    <constraints>
-                      <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="Advanced settings"/>
-                    </properties>
-                  </component>
-                  <hspacer id="60dae">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                  </hspacer>
-                </children>
-              </grid>
-              <grid id="fc361" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="4" fill="2" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="60740" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="Blur size"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="d6c7d" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="c45a6" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="Local threshold"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="936f6" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="391b8" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="Global threshold"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="c7b13" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <grid id="72ed3" class="fr.pasteur.ida.zellige.gui.ZSpinner" binding="blurSpinner" custom-create="true" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                    <margin top="0" left="0" bottom="0" right="0"/>
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties/>
-                    <border type="none"/>
-                    <children/>
-                  </grid>
-                </children>
-              </grid>
-              <grid id="798a9" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="c82b8" class="fr.pasteur.ida.zellige.gui.ZSpinner" binding="localThresholdSpinner" custom-create="true">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties/>
-                  </component>
-                </children>
-              </grid>
-              <grid id="b25ed" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="2b274" class="fr.pasteur.ida.zellige.gui.ZSpinner" binding="globalThresholdSpinner" custom-create="true">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties/>
-                  </component>
-                </children>
-              </grid>
-              <grid id="34c04" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="d065f" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="Delta"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="e787a" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="549c1" class="fr.pasteur.ida.zellige.gui.ZSpinner" binding="deltaSpinner" custom-create="true">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties/>
-                  </component>
-                </children>
-              </grid>
-            </children>
-          </grid>
-        </children>
-      </grid>
-      <grid id="6ecf0" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-        <margin top="0" left="0" bottom="0" right="0"/>
-        <constraints>
-          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-        </constraints>
-        <properties/>
-        <border type="none"/>
-        <children>
-          <grid id="d6313" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="7c19b" class="javax.swing.JButton" binding="runZelligeButton" default-binding="true">
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties>
-                  <text value="Run Zellige"/>
-                </properties>
-              </component>
-            </children>
-          </grid>
-          <grid id="fbf72" layout-manager="FlowLayout" hgap="5" vgap="5" flow-align="1">
-            <constraints>
-              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <component id="b6c35" class="javax.swing.JLabel">
-                <constraints/>
-                <properties>
-                  <text value="Output Settings"/>
-                </properties>
-              </component>
-            </children>
-          </grid>
-          <grid id="beadd" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <grid id="e3a82" layout-manager="FlowLayout" hgap="5" vgap="5" flow-align="1">
-                <constraints>
-                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="4" fill="2" indent="0" use-parent-layout="false">
-                    <preferred-size width="50" height="20"/>
-                  </grid>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="ca880" class="javax.swing.JLabel">
-                    <constraints/>
-                    <properties>
-                      <text value="Extracted stack"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="a6c85" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
-                    <preferred-size width="50" height="24"/>
-                  </grid>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="2b021" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="Projection"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="6ea90" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
-                    <preferred-size width="50" height="24"/>
-                  </grid>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="efaed" class="javax.swing.JCheckBox" binding="extractedStack">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value=""/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="d89e9" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
-                    <preferred-size width="145" height="24"/>
-                  </grid>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="f900f" class="javax.swing.JCheckBox" binding="projection">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value=""/>
-                    </properties>
-                  </component>
-                  <component id="ec4fb" class="javax.swing.JComboBox" binding="projectionType" custom-create="true">
-                    <constraints>
-                      <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
-                        <preferred-size width="146" height="30"/>
-                      </grid>
-                    </constraints>
-                    <properties>
-                      <enabled value="false"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="44706" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="b2ef" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="Zmap"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="d8eaf" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
-                    <preferred-size width="50" height="-1"/>
-                  </grid>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="32059" class="javax.swing.JCheckBox" binding="zMap" default-binding="true">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value=""/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-            </children>
-          </grid>
-          <grid id="60958" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-            <margin top="0" left="0" bottom="0" right="0"/>
-            <constraints>
-              <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
-            </constraints>
-            <properties/>
-            <border type="none"/>
-            <children>
-              <grid id="1defa" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
-                    <preferred-size width="50" height="24"/>
-                  </grid>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="df956" class="javax.swing.JLabel">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <text value="Height map"/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-              <grid id="4c1e1" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-                <margin top="0" left="0" bottom="0" right="0"/>
-                <constraints>
-                  <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
-                    <preferred-size width="145" height="24"/>
-                  </grid>
-                </constraints>
-                <properties/>
-                <border type="none"/>
-                <children>
-                  <component id="f540f" class="javax.swing.JCheckBox" binding="HeightMap">
-                    <constraints>
-                      <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
-                    </constraints>
-                    <properties>
-                      <enabled value="false"/>
-                      <text value=""/>
-                    </properties>
-                  </component>
-                </children>
-              </grid>
-            </children>
-          </grid>
-        </children>
-      </grid>
-    </children>
-  </grid>
-</form>
diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/Settings.java b/src/main/java/fr/pasteur/ida/zellige/gui/Settings.java
deleted file mode 100644
index 642d8714..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/gui/Settings.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package fr.pasteur.ida.zellige.gui;
-
-import javax.swing.*;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-public class Settings
-{
-    private JButton advancedSettingsButton;
-    private JButton runZelligeButton;
-    private JComboBox <String> projectionType;
-    private JCheckBox extractedStack;
-    private JCheckBox HeightMap;
-    private JCheckBox projection;
-    private ZSpinner blurSpinner;
-    private ZSpinner localThresholdSpinner;
-    private ZSpinner globalThresholdSpinner;
-    private ZSpinner deltaSpinner;
-    private JCheckBox zMap;
-    private JPanel panel;
-
-
-    public Settings(  )
-    {
-
-    }
-
-
-
-
-    private void createUIComponents()
-    {
-        this.blurSpinner = new ZSpinner("blur value", 0, 50, 15, 1 );
-        this.blurSpinner.setDefaultRange( 5, 20 );
-        this.localThresholdSpinner = new ZSpinner( "local threshold value",0, 100, 70, 5 );
-        this.localThresholdSpinner.setDefaultRange( 0 , 90);
-        this.globalThresholdSpinner = new ZSpinner("global threshold value", 0, 100, 30, 5 );
-        this.globalThresholdSpinner.setDefaultRange( 0, 50 );
-        this.deltaSpinner = new ZSpinner("delta value", 0, 50, 1, 1  );
-        this.deltaSpinner.setDefaultRange( 0, 3 );
-        String[] strings = new String[]{"MIP", "Minimum Intensity", "Median", "FastSME", "Element 4", "Element 5"};
-        this.projectionType = new JComboBox<>(strings);
-    }
-
-
-    public JButton getRunZelligeButton()
-    {
-        return runZelligeButton;
-    }
-
-    public JComboBox <String> getProjectionType()
-    {
-        return projectionType;
-    }
-
-    public JCheckBox getZMap()
-    {
-        return zMap;
-    }
-
-    public JCheckBox getExtractedStack()
-    {
-        return extractedStack;
-    }
-
-    public JCheckBox getHeightMap()
-    {
-        return HeightMap;
-    }
-
-    public JCheckBox getProjection()
-    {
-        return projection;
-    }
-
-    public ZSpinner getBlurSpinner()
-    {
-        return blurSpinner;
-    }
-
-    public ZSpinner getLocalThresholdSpinner()
-    {
-        return localThresholdSpinner;
-    }
-
-    public ZSpinner getGlobalThresholdSpinner()
-    {
-        return globalThresholdSpinner;
-    }
-
-    public ZSpinner getDeltaSpinner()
-    {
-        return deltaSpinner;
-    }
-
-    public JButton getAdvancedSettingsButton()
-    {
-        return advancedSettingsButton;
-    }
-
-    public JPanel getPanel()
-    {
-        return panel;
-    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/ZSpinner.java b/src/main/java/fr/pasteur/ida/zellige/gui/ZSpinner.java
deleted file mode 100644
index acf9a3c1..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/gui/ZSpinner.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package fr.pasteur.ida.zellige.gui;
-
-
-
-import javax.swing.*;
-import java.awt.*;
-
-public class ZSpinner extends JSpinner
-{
-    private int minDefaultValue = -1;
-    private int maxDefaultValue = -1;
-    private final String name;
-
-    public ZSpinner(String name, int min, int max, int value, int step)
-    {
-        super(new SpinnerNumberModel(value, min, max, step));
-        this.name = name;
-        this.setPreferredSize( new Dimension(100, 20) );
-
-    }
-
-//TODO color range not working
-    public void setRangeColor()
-    {
-        if (getTextValue() < minDefaultValue || getTextValue()> maxDefaultValue)
-        {
-            this.getEditor().setBackground( Color.RED );
-        }
-        else
-        {
-            this.getEditor().setForeground( Color.BLACK );
-        }
-    }
-
-    public int  getTextValue() {
-        JComponent editor = this.getEditor();
-        if (editor instanceof JSpinner.DefaultEditor) {
-            JFormattedTextField formattedTextField = ((JSpinner.DefaultEditor)  editor ).getTextField();
-            try
-            {
-                int value = Integer.parseInt(  formattedTextField.getText().trim());
-                System.out.println(value);
-                return value;
-            }
-            catch ( NumberFormatException nfe )
-            {
-                JOptionPane.showMessageDialog(null, "The "+ name + " is not an integer.",
-                        "Error Message", JOptionPane.ERROR_MESSAGE);
-
-            }
-        }
-        return -1;
-    }
-
-
-
-    public void setDefaultRange(int min, int max)
-    {
-        this.minDefaultValue = min;
-        this.maxDefaultValue = max;
-    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/ZelligeController.java b/src/main/java/fr/pasteur/ida/zellige/gui/ZelligeController.java
deleted file mode 100644
index fbcb55ca..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/gui/ZelligeController.java
+++ /dev/null
@@ -1,195 +0,0 @@
-package fr.pasteur.ida.zellige.gui;
-import fr.pasteur.ida.zellige.surfaceConstruction.construction.SurfacesExtraction;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
-import ij.IJ;
-import net.imagej.ImgPlus;
-import net.imagej.display.ImageDisplayService;
-import net.imagej.ops.OpService;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.util.Util;
-import org.scijava.Context;
-import org.scijava.log.LogService;
-
-import net.imagej.Dataset;
-
-import javax.swing.*;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.function.Supplier;
-
-
-
-public class ZelligeController implements ChangeListener, ActionListener
-{
-    private final Context context;
-    private ImageDisplayService imageDisplayService;
-
-    private final Settings settings;
-    private final AdvancedSettings advancedSettings;
-
-    private JButton advancedSettingsButton;
-    private JButton runZelligeButton;
-    private JCheckBox zMap;
-    private JComboBox<String> projectionType;
-    private JCheckBox extractedStack;
-    private JCheckBox HeightMap;
-    private JCheckBox projection;
-    private ZSpinner blurSpinner;
-    private ZSpinner localThresholdSpinner;
-    private ZSpinner globalThresholdSpinner;
-    private ZSpinner deltaSpinner;
-
-//    private Cancelable cancelable;
-
-    private final OpService ops;
-
-    private final LogService logService;
-
-    public ZelligeController( Context context )
-    {
-        this.context = context;
-        this.ops = context.getService( OpService.class );
-        this.logService = context.getService( LogService.class );
-
-        final ImageDisplayService imageDisplayService = context.getService( ImageDisplayService.class );
-        final Supplier< Dataset > datasetSupplier = () -> imageDisplayService.getActiveDataset();
-
-        this.advancedSettings = new AdvancedSettings();
-        this.settings = new Settings();
-
-        this.set();
-
-
-        final JFrame frame = new JFrame("Zellige");
-        frame.setLocationByPlatform( true );
-        frame.setLocationRelativeTo( null );
-        frame.getContentPane().add( settings.getPanel() );
-        frame.pack();
-        frame.setVisible( true );
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
-
-    }
-
-    @Override
-    public void stateChanged( ChangeEvent e )
-    {
-        if (e.getSource() instanceof ZSpinner )
-        {
-            ZSpinner zSpinner = ( ZSpinner ) e.getSource();
-            zSpinner.setRangeColor();
-        }
-    }
-
-    @Override
-    public void actionPerformed( ActionEvent e )
-    {
-        if (e.getSource() instanceof JButton )
-        {
-            if (e.getSource().equals( this.advancedSettingsButton ))
-            {
-                this.advancedSettings.setVisible( true );
-            }
-            else if (e.getSource().equals( this.runZelligeButton ))
-            {
-                runZellige();
-            }
-        }
-        else if (e.getSource().equals( this.projection ))// Projection type display only if the projection checkBox is selected
-        {
-            this.projectionType.setEnabled( this.projection.isSelected() );
-            this.HeightMap.setEnabled( this.projection.isSelected() );
-        }
-
-        else if ( e.getSource().equals( this.projectionType ))
-        {
-            if ( this.projectionType.getSelectedItem().toString().trim().equals(  "MIP")
-            ||this.projectionType.getSelectedItem() == "Minimum Intensity" )
-            {
-                this.HeightMap.setEnabled( true );
-            }
-            else{
-                this.HeightMap.setEnabled( false );
-            }
-        }
-    }
-
-
-    public void set()
-    {
-
-        this.blurSpinner = this.settings.getBlurSpinner();
-        this.blurSpinner.addChangeListener( this );
-        this.localThresholdSpinner = this.settings.getLocalThresholdSpinner();
-        this.localThresholdSpinner.addChangeListener( this );
-        this.globalThresholdSpinner = this.settings.getGlobalThresholdSpinner();
-        this.globalThresholdSpinner.addChangeListener( this );
-        this.deltaSpinner = this.settings.getDeltaSpinner();
-        this.deltaSpinner.addChangeListener( this );
-        this.extractedStack = this.settings.getExtractedStack();
-        this.HeightMap = this.settings.getHeightMap();
-        this.projection = this.settings.getProjection();
-        this.projection.addActionListener( this );
-        this.projectionType = this.settings.getProjectionType();
-        this.projectionType.addActionListener( this );
-        this.zMap = this.settings.getZMap();
-        this.advancedSettingsButton = this.settings.getAdvancedSettingsButton();
-        this.advancedSettingsButton.addActionListener( this );
-                this.runZelligeButton = this.settings.getRunZelligeButton();
-                this.runZelligeButton.addActionListener( this );
-    }
-
-    public< T extends RealType< T > & NativeType< T > > void runZellige()
-    {
-
-        final ImageDisplayService imageDisplayService = context.getService( ImageDisplayService.class );
-        final Supplier< Dataset > datasetSupplier = () -> imageDisplayService.getActiveDataset();
-        Dataset dataset = imageDisplayService.getActiveDataset();
-        if ( null == dataset )
-        {
-            logService.error( "Please open an image before running Zellige." );
-            return;
-        }
-        /*
-         * Wrap it into an ImgLib2 'Plus' image.
-         */
-        @SuppressWarnings( "unchecked" )
-        ImgPlus< T > stackImage = ( ImgPlus< T > ) datasetSupplier.get().getImgPlus();
-
-        long[] dims = new long[dataset.numDimensions()];
-        dataset.dimensions(dims);
-
-        IJ.log( "Zellige received the image: " + stackImage.getName() );
-        IJ.log( "Size: " + Util.printInterval( stackImage ) );
-        IJ.log( "Type: " + stackImage.firstElement().getClass().toGenericString() );
-        IJ.log( "Dimensionality: " + stackImage.numDimensions() + "D" );
-        for ( int d = 0; d < stackImage.numDimensions(); d++ )
-            IJ.log( " - dimension " + d + ": [" + stackImage.axis( d ).type() + "], 1 unit = " + stackImage.averageScale( d ) + " " + stackImage.axis( d ).unit() );
-        if ( stackImage.numDimensions() == 3 )// Is it a stack ?
-        {
-
-
-            int localThreshold = localThresholdSpinner.getTextValue();
-            int globalThreshold = globalThresholdSpinner.getTextValue();
-            int sigma = blurSpinner.getTextValue();
-            int delta = deltaSpinner.getTextValue();
-            boolean zMapDisplay = this.zMap.isSelected();
-            boolean extractedStackDisplay = this.extractedStack.isSelected();
-            boolean heightMapDisplay = this.HeightMap.isSelected();
-            boolean projectionDisplay = this.projection.isSelected();
-            String projectionSelection = ( String ) this.projectionType.getEditor().getItem();
-//            SurfacesExtraction.extract(stackImage, globalThreshold,  sigma, maximums,
-//                    zMapDisplay, delta, extractedStackDisplay,
-//                    heightMapDisplay, projectionDisplay, projectionSelection);
-        }
-        else
-        {
-            IJ.log( " This image has to be a z-stack ! " );
-        }
-
-    }
-
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/jzy3D/OSDisplay.java b/src/main/java/fr/pasteur/ida/zellige/jzy3D/OSDisplay.java
index 0c2152b7..b1d8a7ba 100644
--- a/src/main/java/fr/pasteur/ida/zellige/jzy3D/OSDisplay.java
+++ b/src/main/java/fr/pasteur/ida/zellige/jzy3D/OSDisplay.java
@@ -1,8 +1,8 @@
 package fr.pasteur.ida.zellige.jzy3D;
 
 import fr.pasteur.ida.zellige.surfaceConstruction.element.Coordinate;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSE;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSList;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSE;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSEList;
 import org.jzy3d.analysis.AbstractAnalysis;
 import org.jzy3d.chart.factories.AWTChartComponentFactory;
 import org.jzy3d.colors.Color;
@@ -15,18 +15,18 @@ import java.util.Random;
 public class OSDisplay extends AbstractAnalysis {
 
 
-    private final OSList[] osLists;
+    private final OSEList[] oseLists;
 
-    public OSDisplay(OSList[] osLists) {
-        this.osLists = osLists;
+    public OSDisplay( OSEList[] oseLists ) {
+        this.oseLists = oseLists;
         init();
     }
 
 
     public void init() {
         int count = 0;
-        for (OSList osList : osLists) {
-            for ( OSE os : osList) {
+        for ( OSEList oseList : oseLists ) {
+            for ( OSE os : oseList ) {
                 count = count+os.size();
             }
         }
@@ -40,9 +40,9 @@ public class OSDisplay extends AbstractAnalysis {
         float z;
 
         int index = 0;
-        for (OSList osList : osLists) {
+        for ( OSEList oseList : oseLists ) {
 
-            for ( OSE os : osList) {
+            for ( OSE os : oseList ) {
                 // one color per OS
                 float G = r.nextFloat() ;
                 float R = r.nextFloat()  ;
diff --git a/src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo.java b/src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo.java
deleted file mode 100644
index 7ef37fdf..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package fr.pasteur.ida.zellige.jzy3D;
-
-
-public class ScatterDemo
-{//extends AbstractAnalysis{
-//    public static void main(String[] args) throws Exception {
-//        AnalysisLauncher.open(new ScatterDemo());
-//    }
-
-//    private ArrayList< Coordinate > maximumCoordinates;
-//
-//    public ScatterDemo( ArrayList< Coordinate >  coordinates )
-//    {
-//        this.maximumCoordinates = coordinates;
-//        init();
-//    }
-//
-//    @Override
-//    public void init()
-//    {
-//        if ( maximumCoordinates != null )
-//        {
-//            int size = 500000;
-//            float a;
-//
-//            Coord3d[] points = new Coord3d[maximumCoordinates.size()];
-//            Color[] colors = new Color[maximumCoordinates.size()];
-//            Coordinate c = null;
-//
-////        Random r = new Random();
-////        r.setSeed(0);
-//
-//            int x;
-//            int y;
-//            int z;
-//
-//            for ( int i = 0; i <= this.maximumCoordinates.size() - 1; i++ )
-//            {
-//                c = maximumCoordinates.get( i );
-//                x = c.getX();
-//                y = c.getY();
-//                z = c.getZ();
-//                points[i] = new Coord3d( x, y, z );
-//                a = 2f;
-//                colors[i] = new Color( 0, 0, 0, a );
-//                System.out.println( points[i] );
-//            }
-//
-//            Scatter scatter = new Scatter( points, colors );
-//            chart = AWTChartComponentFactory.chart( Quality.Advanced, "newt" );
-//            chart.getScene().add( scatter );
-//        }
-//    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo2.java b/src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo2.java
deleted file mode 100644
index f909aaa4..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo2.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package fr.pasteur.ida.zellige.jzy3D;
-
-import org.jzy3d.analysis.AbstractAnalysis;
-import org.jzy3d.analysis.AnalysisLauncher;
-import org.jzy3d.chart.factories.AWTChartComponentFactory;
-import org.jzy3d.colors.Color;
-import org.jzy3d.maths.Coord3d;
-import org.jzy3d.plot3d.primitives.Scatter;
-import org.jzy3d.plot3d.rendering.canvas.Quality;
-
-import java.util.Random;
-// comment for nothing
-
-public class ScatterDemo2 extends AbstractAnalysis
-{
-    public static void main( String[] args ) throws Exception
-    {
-        AnalysisLauncher.open( new ScatterDemo2() );
-    }
-
-    @Override
-    public void init( )
-    {
-        int size = 500000;
-        float x;
-        float y;
-        float z;
-        float a;
-
-        Coord3d[] points = new Coord3d[ size ];
-        Color[] colors = new Color[ size ];
-
-        Random r = new Random();
-        r.setSeed( 0 );
-
-        for ( int i = 0; i < size; i++ )
-        {
-            x = r.nextFloat() - 0.5f;
-            y = r.nextFloat() - 0.5f;
-            z = r.nextFloat() - 0.5f;
-            points[ i ] = new Coord3d( x, y, z );
-            a = 0.25f;
-            colors[ i ] = new Color( x, y, z, a );
-        }
-
-        Scatter scatter = new Scatter( points, colors );
-        chart = AWTChartComponentFactory.chart( Quality.Advanced, "newt" );
-        chart.getScene().add( scatter );
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo6.java b/src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo6.java
deleted file mode 100644
index 58384f16..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/jzy3D/ScatterDemo6.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package fr.pasteur.ida.zellige.jzy3D;
-
-
-import org.jzy3d.analysis.AbstractAnalysis;
-
-
-public class ScatterDemo6 extends AbstractAnalysis
-{
-
-
-//    private AllSurface allSurface;
-//
-//    public ScatterDemo6( AllSurface allSurface )
-//    {
-//        this.allSurface = allSurface;
-//    }
-
-    @Override
-    public void init( )
-    {
-//        int size = allSurface.count();
-//        System.out.println("final fr.pasteur.ida.zellige.surface number " + allSurface.getSurfaces().size());
-//        System.out.println( Coordinate.number);
-//        System.out.println( Surface1D.SurfaceCoordinates.ovsCount);
-//        Coord3d[] points = new Coord3d[size];
-//        Color[] colors = new Color[size];
-//        int j = 0;
-//        for(int i = 0; i <= allSurface.getSurfaces().size()-1; i++)
-//
-//        {
-//            Surface1D.SurfaceCoordinates coordinates = allSurface.getSurfaces().get( i );
-//            Random r = new Random();
-//            r.setSeed( i+3 );
-//            float G = r.nextFloat();
-//            float R = r.nextFloat();
-//
-//            float B = r.nextFloat();
-//            for ( OVSCoordinates ovsCoordinates : coordinates.getOvsCoordinates() )
-//            {
-//                Coordinate c = ovsCoordinates.getFist();
-//                    int x;
-//                    int y;
-//                    int z;
-//
-//                    while ( c != null  )
-//                    {
-//                        x = c.getX();
-//                        y = c.getY();
-//                        z = c.getZ();
-//
-//                        points[j] = new Coord3d( x, y, z );
-//                        colors[j] = new Color( R, G, B, 5f );
-//                        c = c.getRight();
-//                        j++;
-//                    }
-//            }
-//        }
-//        Scatter scatter = new Scatter( points, colors );
-//        scatter.setWidth( 5 );
-//        chart = AWTChartComponentFactory.chart( Quality.Advanced, "newt" );
-//        chart.getScene().add( scatter );
-
-    }
-}
-
diff --git a/src/main/java/fr/pasteur/ida/zellige/jzy3D/SurfaceDisplay.java b/src/main/java/fr/pasteur/ida/zellige/jzy3D/SurfaceDisplay.java
index c26cdcd0..641b78de 100644
--- a/src/main/java/fr/pasteur/ida/zellige/jzy3D/SurfaceDisplay.java
+++ b/src/main/java/fr/pasteur/ida/zellige/jzy3D/SurfaceDisplay.java
@@ -14,7 +14,7 @@ import org.jzy3d.plot3d.rendering.canvas.Quality;
 public class SurfaceDisplay extends AbstractAnalysis
 {
 
-    private Surface surface;
+    private final Surface surface;
 
     public SurfaceDisplay( Surface surface )
     {
@@ -36,7 +36,7 @@ public class SurfaceDisplay extends AbstractAnalysis
             int z;
             int index = 0;
             int size = 0;
-            for ( int i = 0; i <= surface.getLength() - 1; i++ )
+            for ( int i = 0; i <= surface.getHeight() - 1; i++ )
             {
                 SurfaceLine surfaceLine = this.surface.get( i );
                 if ( surfaceLine != null )
diff --git a/src/main/java/fr/pasteur/ida/zellige/main/Main.java b/src/main/java/fr/pasteur/ida/zellige/main/Main.java
index f014ae61..0be1b5d2 100644
--- a/src/main/java/fr/pasteur/ida/zellige/main/Main.java
+++ b/src/main/java/fr/pasteur/ida/zellige/main/Main.java
@@ -1,23 +1,17 @@
 package fr.pasteur.ida.zellige.main;
 
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
+import fr.pasteur.ida.zellige.surfaceConstruction.parameters.AdvancedUserParameters;
+import fr.pasteur.ida.zellige.surfaceConstruction.construction.ReferenceSurfaceExtraction;
+import fr.pasteur.ida.zellige.surfaceConstruction.parameters.UserParameters;
 import fr.pasteur.ida.zellige.utils.TestMIP;
 import ij.IJ;
 import ij.ImageJ;
-import io.scif.config.SCIFIOConfig;
 import io.scif.img.IO;
 import io.scif.img.SCIFIOImgPlus;
-import net.imagej.ImgPlus;
-import net.imglib2.RandomAccessibleInterval;
 import net.imglib2.img.Img;
-import net.imglib2.img.ImgFactory;
-import net.imglib2.img.array.ArrayImgFactory;
 import net.imglib2.img.display.imagej.ImageJFunctions;
-import net.imglib2.script.slice.SliceYZ;
 import net.imglib2.type.NativeType;
 import net.imglib2.type.numeric.RealType;
-import fr.pasteur.ida.zellige.surfaceConstruction.construction.SurfacesExtraction;
-import net.imglib2.type.numeric.real.FloatType;
 
 
 /**
@@ -63,9 +57,9 @@ public class Main
 
         // Input of the image.
         final String imagePath =
-//        "doc/STK_060.tif";
+        "doc/STK.tif";
 //        "C:\\Users\\ctrebeau\\Desktop\\MoucheAile\\STK\\STK_Mouche_c01_f0001_p005.tif";
-        "C:\\Users\\ctrebeau\\Downloads\\phantom3b_combined.tif";
+//        "C:\\Users\\ctrebeau\\Downloads\\phantom3b_combined.tif";
 //                "C:\\Users\\ctrebeau\\Desktop\\HighRes\\STK_170706_Vangl2-Lp-wt_E14.5_Phall_cochlea_01bHighRes_c01_f0001_p005.tif";
         System.out.println(imagePath);
         // Creation of the image : version with unsigned type. */
@@ -95,15 +89,17 @@ public class Main
         System.out.println( System.lineSeparator() );
         /* End of  Print parameters.*/
 
+        UserParameters userParameters = new UserParameters( amplitude, otsu, sigmas, delta, "MIP" );
+        AdvancedUserParameters advancedUserParameters = new AdvancedUserParameters( k1, percent1, k2, percent2 );
         IJ.log("Type: "+ imgPlus.firstElement().getClass().toGenericString());
 
         if ( stackImage.numDimensions() == 3 )// Is it a stack ?
         {
             ImageJFunctions.show( stackImage, "original" );
             ImageJFunctions.show( TestMIP.findMIP( stackImage, stackImage.factory() ), "MIP" );
-
-            SurfacesExtraction.extract(stackImage, stackImage.factory(),amplitude,otsu, sigmas, false, delta, false,
-                    false, true, "MIP", k1, percent1, k2, percent2);
+            ReferenceSurfaceExtraction rse = new ReferenceSurfaceExtraction<>( stackImage, stackImage.factory(),userParameters, advancedUserParameters );
+            rse.extract();
+            rse.project();
         }
         else
         {
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/OSConstruction.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/OSConstruction.java
deleted file mode 100644
index df468e81..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/OSConstruction.java
+++ /dev/null
@@ -1,244 +0,0 @@
-package fr.pasteur.ida.zellige.surfaceConstruction.construction;
-
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Coordinate;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSE;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSEStartingStatus;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSList;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.TreeMap;
-
-
-/**
- * This class contains a main static method for the construction of OS : {@code findOS}.
- */
-public class OSConstruction
-{
-
-    /**
-     * This method finds all the possible 2D surfaces that can be created from the coordinates detected as
-     * local maximums on a array of {@link }.
-     *
-     * @param rawCoordinates - the raw Coordinates from the projection.
-     * @return all the orthogonal surfaces for the projection as an {@link ArrayList< OSE >}.
-     */
-    public static OSList findOS( Pixels[] rawCoordinates, int dimension , OSEStartingStatus startingStatus)
-    {
-        if ( dimension == 1 )
-        {
-            reset( rawCoordinates );// the number of right and left coordinates are reset to 0.
-        }
-        ArrayList < Coordinate > startingCoordinates = checkForSideCoordinates( rawCoordinates );
-        OSList paths = findSimplePaths( startingCoordinates, rawCoordinates, dimension, startingStatus );
-        OSList finalPaths = findComplexPaths( paths, dimension );
-        if ( dimension == 0 )
-        {
-            finalPaths.removeIf( os -> os.size() < 3 );// shortest ones are removed
-        }
-        for ( OSE os : finalPaths )
-        {
-            os.set(dimension);
-        }
-        finalPaths.reset();
-        return finalPaths;
-    }
-
-    private static OSList findSimplePaths (ArrayList< Coordinate> startingCoordinates, Pixels[] rawCoordinates,
-                                           int dimension, OSEStartingStatus occurrence)
-    {
-        Queue < Coordinate > firstQueue = new LinkedList <>( startingCoordinates );// Add the coordinates with no left coordinates in
-        // the queue
-        OSList smallPath = new OSList();
-        while ( !firstQueue.isEmpty() )
-        {
-            Coordinate current = firstQueue.remove();
-            OSE os = new OSE(occurrence);
-            os.add( current );
-            findSimplePaths( rawCoordinates, smallPath, os, current, dimension, firstQueue );
-        }
-        return smallPath;
-    }
-
-    /**
-     * @param rawCoordinates -  the raw Coordinates from the projection.
-     * @param smallPath      - the one-Z-OS
-     * @param os             - the first OS considered.
-     * @param current        - the starting {@link Coordinate} considered.
-     * @param dimension      - the dimension of the OS construction.
-     */
-    private static void findSimplePaths
-            ( Pixels[] rawCoordinates,
-              ArrayList < OSE > smallPath, OSE os, Coordinate current, int dimension, Queue < Coordinate > queue )
-    {
-        int i;
-        if ( dimension == 0 )
-        {
-            i = current.getX();
-        }
-        else
-        {
-            i = current.getY();
-        }
-        while ( i <= rawCoordinates.length - 2 // x must be < to the length of the image minus 1 because [X + 1]
-                && rawCoordinates[ i ] != null // the contents in the array at index x must not be null
-                && rawCoordinates[ i + 1 ] != null // the contents in the array at index (x +1) must not be null
-                && current!= null )
-        {
-            Coordinate next = current.getNext( rawCoordinates[ i + 1 ], 0 );
-            if ( next != null )//  Conditions :  |x1 - x2 |= 1 => only 1D surface
-            {
-                os.add( next );
-            }
-            else
-            {
-                if ( ( i ) < rawCoordinates.length - 3
-                        && rawCoordinates[ i + 2 ] != null// the contents in the array at index (x +1) must not
-                        // be null
-                        && current.getRightNumber() == 0 )
-                {
-                    next = current.getNext( rawCoordinates[ i + 2 ], 0 );
-                    if ( next != null )//fake coordinate
-                    {
-                        if ( dimension == 0 )
-                        {
-                            os.add( new Coordinate(current.getX() + 1, current.getY(), current.getZ() ) );
-                        }
-                        else
-                        {
-                            os.add( new Coordinate( current.getX(), current.getY() + 1, current.getZ() ) );
-                        }
-                        os.add( next );
-                        queue.remove( next );
-                        i++;
-                    }
-                }
-            }
-            current = next;
-            i++; //increment of the index
-        }
-        smallPath.add( os );
-    }
-
-    /**
-     * @param shortPaths - the list of one-z-OS.
-     * @param dimension  - the dimension considered.
-     * @return - the list of "big paths" OS.
-     */
-    private static OSList findComplexPaths( OSList shortPaths, int dimension )
-    {
-        OSList paths = new OSList();
-        Queue < OSE > queue = new LinkedList <>( shortPaths );
-        while ( !queue.isEmpty() )
-        {
-            OSE first = queue.remove();
-            shortPaths.remove( first );
-            findComplexPaths( first, shortPaths, queue, paths, dimension );
-        }
-        return paths;
-    }
-
-    /**
-     * @param first      - the starting OS.
-     * @param smallPaths - the list of all small path OS.
-     * @param queue      - the remaining OS.
-     * @param longPaths  - the list of long path OS.
-     * @param dimension  - the dimension considered.
-     */
-    private static void findComplexPaths( OSE first,
-                                          ArrayList < OSE > smallPaths,
-                                          Queue < OSE > queue, ArrayList < OSE > longPaths, int dimension )
-    {
-        for ( OSE o : smallPaths )
-        {
-            if ( first.isNextTo( o, dimension ) )
-            {
-                first.addAll( o );
-                o.setVisited( true );
-                queue.remove( o );
-            }
-        }
-        smallPaths.removeIf( OSE::isVisited );
-        longPaths.add( first );
-    }
-
-    /**
-     * Stores the coordinates that don't have a coordinate to the left.
-     *
-     * @param slice - a one-dimensional array containing the local maximums.
-     * @return - a list of coordinates that don't have a coordinate to the left.
-     */
-    private static ArrayList < Coordinate > checkForSideCoordinates( Pixels[] slice )
-    {
-            /* Stores the coordinates that have no coordinates to the left.*/
-            ArrayList < Coordinate > noLeftCoordinates = new ArrayList <>();
-            /* Starting point. */
-            int start = 0;
-            while ( start <= slice.length - 3 && slice[ start ] == null )
-            {
-                start++;//the index starts where a List of Coordinates is found in the array
-            }
-            if ( slice[ start ] != null && slice[ start + 1 ] != null ) //some Coordinates were found
-            {
-                /* For the first list of coordinates. */
-                for ( int i = 0; i <= slice[ start ].size() - 1; i++ )// the first coordinates of the array have obviously no left coordinates
-                {
-                    Coordinate coordinate = slice[ start ].get( i );
-                    noLeftCoordinates.add( coordinate );
-                    coordinate.setRightCoordinates( slice[ start + 1 ] );
-                }
-            }
-            /* For the rest. */
-            for ( int i = start + 1; i <= slice.length - 2; i++ )
-            {
-                if ( slice[ i ] != null )
-                {
-                    for ( Coordinate coordinate : slice[ i ].get() )
-                    {
-                        coordinate.setRightCoordinates( slice[ i + 1 ] );
-                        coordinate.setLeftCoordinates( slice[ i - 1 ] );
-                        boolean hasNoLeft = coordinate.numberOfNeighbours( slice[ i - 1 ], 0 )== 0;
-                        if ( hasNoLeft )
-                        {
-                            noLeftCoordinates.add( coordinate );
-                        }
-                    }
-                }
-            }
-            /* the last one */ //Avoid ArrayOutOfBoundException
-            int end = slice.length - 1;
-            if ( slice[ end ] != null && slice[ end - 1 ] != null )
-            {
-                for ( Coordinate coordinate : slice[ end ].get() )
-                {
-                    coordinate.setLeftCoordinates( slice[ end - 1 ] );
-                    boolean hasNoLeft = coordinate.numberOfNeighbours( slice[ end - 1 ], 0 )== 0;
-                    if ( hasNoLeft )
-                    {
-                        noLeftCoordinates.add( coordinate );
-                    }
-                }
-            }
-            return noLeftCoordinates;
-    }
-
-    /**
-     * Resets the parameters of each {@link Coordinate } for a given {@link Pixels} array
-     * before the Y dimension reconstruction ( rightsNumber , leftsNumber, noLeft, queue ).
-     *
-     * @param slice - the {@link Pixels} array considered.
-     */
-    private static void reset( Pixels[] slice )
-    {
-        for ( Pixels pixels : slice )
-        {
-            if ( pixels != null )
-            {
-                pixels.resetSideCoordinate();
-            }
-        }
-    }
-}
-
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/OSEListConstruction.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/OSEListConstruction.java
new file mode 100644
index 00000000..2b573922
--- /dev/null
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/OSEListConstruction.java
@@ -0,0 +1,272 @@
+package fr.pasteur.ida.zellige.surfaceConstruction.construction;
+
+import fr.pasteur.ida.zellige.surfaceConstruction.element.Coordinate;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSE;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSEList;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSEStartingStatus;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.Queue;
+
+
+/**
+ * This class contains a main method for the construction of OSE : {@code findOS}.
+ */
+public class OSEListConstruction
+{
+    private final Pixels[][] maximums;
+    private final OSEList[] oseLists;
+    private final OSEStartingStatus startingStatus;
+    private final int dimension;
+
+    public OSEListConstruction( Pixels[][] maximums , int dimension)
+    {
+        this.maximums = maximums;
+        this.oseLists = new OSEList[maximums.length];
+        this.dimension = dimension;
+        this.startingStatus = new OSEStartingStatus( dimension );
+    }
+
+    public void run()
+    {
+        for ( int i = 0; i <= maximums.length - 1; i++ )
+        {
+            oseLists[ i ] = findOSE( maximums[ i ] );
+        }
+        startingStatus.setStartingStatus();
+        System.out.println( "Starting size = " + startingStatus.getMinimumSize());
+    }
+    
+        /**
+         * This method finds all the possible 2D surfaces that can be created from the coordinates detected as
+         * local maximums on a array of {@link }.
+         *
+         * @param rawCoordinates - the raw Coordinates from the projection.
+         * @return all the orthogonal surfaces for the projection as an {@link ArrayList<OSE>}.
+         */
+        private OSEList findOSE( Pixels[] rawCoordinates )
+        {
+            if ( dimension == 1 )
+            {
+                reset( rawCoordinates );// the number of right and left coordinates are reset to 0.
+            }
+            ArrayList< Coordinate > startingCoordinates = checkForSideCoordinates( rawCoordinates );
+            OSEList paths = findSimplePaths( startingCoordinates, rawCoordinates );
+            OSEList finalPaths = findComplexPaths( paths );
+            if ( dimension == 0 )
+            {
+                finalPaths.removeIf( ose -> ose.size() < 3 );// shortest ones are removed
+            }
+            for ( OSE ose : finalPaths )
+            {
+                ose.set();
+            }
+            finalPaths.reset();
+            return finalPaths;
+        }
+
+        private OSEList findSimplePaths( ArrayList< Coordinate > startingCoordinates, Pixels[] rawCoordinates )
+        {
+            Queue< Coordinate > firstQueue = new LinkedList<>( startingCoordinates );// Add the coordinates with no left coordinates in
+            // the queue
+            OSEList smallPath = new OSEList();
+            while ( ! firstQueue.isEmpty() )
+            {
+                Coordinate current = firstQueue.remove();
+                OSE ose = new OSE( startingStatus );
+                ose.add( current );
+                findSimplePaths( rawCoordinates, smallPath, ose, current, firstQueue );
+            }
+            return smallPath;
+        }
+
+        /**
+         * @param rawCoordinates -  the raw Coordinates from the projection.
+         * @param smallPath      - the one-Z-OSE
+         * @param ose             - the first OSE considered.
+         * @param current        - the starting {@link Coordinate} considered.
+         */
+        private  void findSimplePaths
+        ( Pixels[] rawCoordinates,
+          ArrayList< OSE > smallPath, OSE ose, Coordinate current, Queue< Coordinate > queue )
+        {
+            int i;
+            if ( dimension == 0 )
+            {
+                i = current.getX();
+            }
+            else
+            {
+                i = current.getY();
+            }
+            while ( i <= rawCoordinates.length - 2 // x must be < to the length of the image minus 1 because [X + 1]
+                    && rawCoordinates[ i ] != null // the contents in the array at index x must not be null
+                    && rawCoordinates[ i + 1 ] != null // the contents in the array at index (x +1) must not be null
+                    && current != null )
+            {
+                Coordinate next = current.getNext( rawCoordinates[ i + 1 ], 0 );
+                if ( next != null )//  Conditions :  |x1 - x2 |= 1 => only 1D surface
+                {
+                    ose.add( next );
+                }
+                else
+                {
+                    if ( ( i ) < rawCoordinates.length - 3
+                            && rawCoordinates[ i + 2 ] != null// the contents in the array at index (x +1) must not
+                            // be null
+                            && current.getRightNumber() == 0 )
+                    {
+                        next = current.getNext( rawCoordinates[ i + 2 ], 0 );
+                        if ( next != null )//fake coordinate
+                        {
+                            if ( dimension == 0 )
+                            {
+                                ose.add( new Coordinate( current.getX() + 1, current.getY(), current.getZ() ) );
+                            }
+                            else
+                            {
+                                ose.add( new Coordinate( current.getX(), current.getY() + 1, current.getZ() ) );
+                            }
+                            ose.add( next );
+                            queue.remove( next );
+                            i++;
+                        }
+                    }
+                }
+                current = next;
+                i++; //increment of the index
+            }
+            smallPath.add( ose );
+        }
+
+        /**
+         * @param shortPaths - the list of one-z-OSE.
+         * @return - the list of "big paths" OSE.
+         */
+        private OSEList findComplexPaths( OSEList shortPaths )
+        {
+            OSEList paths = new OSEList();
+            Queue< OSE > queue = new LinkedList<>( shortPaths );
+            while ( ! queue.isEmpty() )
+            {
+                OSE first = queue.remove();
+                shortPaths.remove( first );
+                findComplexPaths( first, shortPaths, queue, paths );
+            }
+            return paths;
+        }
+
+        /**
+         * @param first      - the starting OSE.
+         * @param smallPaths - the list of all small path OSE.
+         * @param queue      - the remaining OSE.
+         * @param longPaths  - the list of long path OSE.
+         */
+        private  void findComplexPaths( OSE first,
+                                        ArrayList< OSE > smallPaths,
+                                        Queue< OSE > queue, ArrayList< OSE > longPaths )
+        {
+            for ( OSE o : smallPaths )
+            {
+                if ( first.isNextTo( o, dimension ) )
+                {
+                    first.addAll( o );
+                    o.setVisited( true );
+                    queue.remove( o );
+                }
+            }
+            smallPaths.removeIf( OSE::isVisited );
+            longPaths.add( first );
+        }
+
+        /**
+         * Stores the coordinates that don't have a coordinate to the left.
+         *
+         * @param slice - a one-dimensional array containing the local maximums.
+         * @return - a list of coordinates that don't have a coordinate to the left.
+         */
+        private ArrayList< Coordinate > checkForSideCoordinates( Pixels[] slice )
+        {
+            /* Stores the coordinates that have no coordinates to the left.*/
+            ArrayList< Coordinate > noLeftCoordinates = new ArrayList<>();
+            /* Starting point. */
+            int start = 0;
+            while ( start <= slice.length - 3 && slice[ start ] == null )
+            {
+                start++;//the index starts where a List of Coordinates is found in the array
+            }
+            if ( slice[ start ] != null && slice[ start + 1 ] != null ) //some Coordinates were found
+            {
+                /* For the first list of coordinates. */
+                for ( int i = 0; i <= slice[ start ].size() - 1; i++ )// the first coordinates of the array have obviously no left coordinates
+                {
+                    Coordinate coordinate = slice[ start ].get( i );
+                    noLeftCoordinates.add( coordinate );
+                    coordinate.setRightCoordinates( slice[ start + 1 ] );
+                }
+            }
+            /* For the rest. */
+            for ( int i = start + 1; i <= slice.length - 2; i++ )
+            {
+                if ( slice[ i ] != null )
+                {
+                    for ( Coordinate coordinate : slice[ i ].get() )
+                    {
+                        coordinate.setRightCoordinates( slice[ i + 1 ] );
+                        coordinate.setLeftCoordinates( slice[ i - 1 ] );
+                        boolean hasNoLeft = coordinate.numberOfNeighbours( slice[ i - 1 ], 0 ) == 0;
+                        if ( hasNoLeft )
+                        {
+                            noLeftCoordinates.add( coordinate );
+                        }
+                    }
+                }
+            }
+            /* the last one */ //Avoid ArrayOutOfBoundException
+            int end = slice.length - 1;
+            if ( slice[ end ] != null && slice[ end - 1 ] != null )
+            {
+                for ( Coordinate coordinate : slice[ end ].get() )
+                {
+                    coordinate.setLeftCoordinates( slice[ end - 1 ] );
+                    boolean hasNoLeft = coordinate.numberOfNeighbours( slice[ end - 1 ], 0 ) == 0;
+                    if ( hasNoLeft )
+                    {
+                        noLeftCoordinates.add( coordinate );
+                    }
+                }
+            }
+            return noLeftCoordinates;
+        }
+
+        /**
+         * Resets the parameters of each {@link Coordinate } for a given {@link Pixels} array
+         * before the Y dimension reconstruction ( rightsNumber , leftsNumber, noLeft, queue ).
+         *
+         * @param slice - the {@link Pixels} array considered.
+         */
+        private  void reset( Pixels[] slice )
+        {
+            for ( Pixels pixels : slice )
+            {
+                if ( pixels != null )
+                {
+                    pixels.resetSideCoordinate();
+                }
+            }
+        }
+
+
+    public OSEList[] getOseLists()
+    {
+        return oseLists;
+    }
+
+    public OSEStartingStatus getStartingStatus()
+    {
+        return startingStatus;
+    }
+}
+
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/ReferenceSurfaceExtraction.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/ReferenceSurfaceExtraction.java
new file mode 100644
index 00000000..3bd58de8
--- /dev/null
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/ReferenceSurfaceExtraction.java
@@ -0,0 +1,294 @@
+package fr.pasteur.ida.zellige.surfaceConstruction.construction;
+
+import fr.pasteur.ida.zellige.surfaceConstruction.parameters.AdvancedUserParameters;
+import fr.pasteur.ida.zellige.surfaceConstruction.parameters.DisplayParameter;
+import fr.pasteur.ida.zellige.exception.FirstRoundConstructionException;
+import fr.pasteur.ida.zellige.exception.NoSurfaceFoundException;
+import fr.pasteur.ida.zellige.jzy3D.LocalMaximumsDisplay;
+import fr.pasteur.ida.zellige.jzy3D.OSDisplay;
+import fr.pasteur.ida.zellige.jzy3D.SurfaceDisplay;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ReferenceSurface;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.Surface;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSEList;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine.SurfaceLine;
+import fr.pasteur.ida.zellige.surfaceConstruction.parameters.UserParameters;
+import fr.pasteur.ida.zellige.utils.*;
+import net.imglib2.RandomAccessibleInterval;
+import net.imglib2.img.Img;
+import net.imglib2.img.ImgFactory;
+import net.imglib2.img.display.imagej.ImageJFunctions;
+import net.imglib2.type.NativeType;
+import net.imglib2.type.numeric.RealType;
+import net.imglib2.type.numeric.integer.UnsignedShortType;
+import org.jzy3d.analysis.AnalysisLauncher;
+
+import java.util.ArrayList;
+
+
+
+public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T > >
+{
+
+    private final  ArrayList< ReferenceSurface <T>> referenceSurfaces = new ArrayList<>();
+    private final RandomAccessibleInterval< T > input;
+    private final ImgFactory<T> factory;
+    private final UserParameters userParameters;
+    private final AdvancedUserParameters advancedUserParameters;
+    public ReferenceSurfaceExtraction( RandomAccessibleInterval< T > input, ImgFactory<T> factory,
+                                       UserParameters userParameters, AdvancedUserParameters advancedUserParameters)
+    {
+        this.input = input;
+        this.factory = factory;
+        this.userParameters = userParameters;
+        this.advancedUserParameters = advancedUserParameters;
+    }
+
+
+    public   void extract( )
+    {
+        /* First step : Pixel selection */
+        SurfacePixelSelection selection = new SurfacePixelSelection( userParameters );
+        selection.run( input );
+        Pixels[][] maximums = selection.getMaximums();
+        /* Second step : Surface construction in 2 rounds */
+        try
+        {
+            /*  First round construction*/
+            double percent1 = advancedUserParameters.getPercent1();
+            int k1 = advancedUserParameters.getK1();
+            ArrayList< Surface > tempSurfaces = firstRoundConstruction( maximums,  percent1, k1);
+            System.out.println( "first round surfaces = " + tempSurfaces.size() );
+
+            /* Second round construction */
+            double percent2 = advancedUserParameters.getPercent2();
+            int k2 = advancedUserParameters.getK2();
+            ArrayList< Surface > finalSurfaces = secondRoundConstruction( tempSurfaces, percent2, k2 );
+            System.out.println( "second round surfaces = " + finalSurfaces.size() );
+
+            /* Process of zMaps */
+            processZMap( finalSurfaces );
+
+            System.out.println( "The end" );
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /* ----- First and second round construction methods. ----- */
+    private  ArrayList< Surface > firstRoundConstruction( Pixels[][] maximums,  double percent, int k ) throws NoSurfaceFoundException
+    {
+        int dimension = 0;
+        ArrayList<Surface> surfaces = constructSurfaces( maximums, dimension, percent, k );
+        if ( ! surfaces.isEmpty() )
+        {
+            mergeReferenceSurface( surfaces );
+        }
+        else
+        {
+            System.out.println( "No Surface Exception" );
+            throw new FirstRoundConstructionException();
+        }
+        return surfaces;
+    }
+
+    /**
+     * Rebuilds the double pixel array from the {@link SurfaceLine} array
+     * of a {@link Surface} for a construction in the height dimension.
+     *
+     * @param surface - the {@link SurfaceLine}  array of a {@link Surface}
+     * @return a {@link Surface} specific double pixel array.
+     */
+    private  Pixels[][] rebuildPixelsArray( Surface surface )
+    {
+        int width = surface.get().length;
+        int height = surface.get()[0].getLength();
+        Pixels[][] tempCoordinates = new Pixels[ height ][ width ]; // Transposed array
+        for ( int i = 0; i <= width - 1; i++ )
+        {
+            for ( int j = 0; j <= height - 1; j++ )
+            {
+                if ( surface.get( i ) != null )
+                {
+                    tempCoordinates[ j ][ i ] = surface.get( i ).get( j );
+                }
+            }
+        }
+        displayMaximums( tempCoordinates );
+        return tempCoordinates;
+    }
+
+    /**
+     * Reconstructs the TempSurface objects  of the specified list in dimension width.
+     *
+     * @param surfaces - the list of TempSurface objects.
+     */
+    private ArrayList< Surface > secondRoundConstruction( ArrayList< Surface > surfaces,  double percent, int k ) throws NoSurfaceFoundException
+    {
+        int dimension = 1;
+        ArrayList< Surface > finalSurfaces = new ArrayList<>();
+        System.out.println( "========================================" );
+        for ( Surface surface : surfaces )
+        {
+            int width = surface.getHeight();
+            if ( surface.hasDuplicate() )// CoordinateList instead of Coordinate
+            {
+                Pixels[][] maximums = rebuildPixelsArray( surface );
+                ArrayList< Surface > temps = constructSurfaces( maximums,dimension, percent, k);
+                if ( temps.isEmpty() )
+                {
+                    System.out.println( "small surface in second round" );
+//                    throw new SecondRoundConstructionException();
+                }
+                else
+                {
+                    finalSurfaces.addAll( temps );
+                }
+            }
+            else
+            {
+                finalSurfaces.add( surface.transpose(width) );
+            }
+        }
+        mergeReferenceSurface( surfaces);
+        return finalSurfaces;
+
+    }
+
+    private Img<UnsignedShortType> processedZMap(Surface surface)
+    {
+        // First step : fill in the holes with linear interpolation. */
+        Img< UnsignedShortType > interpolated = Interpolation.run( surface.getZMap() );
+        Img< UnsignedShortType > smoothed = interpolated.copy();
+        ImageJFunctions.show( smoothed, "smoothed" );
+        // Second step:  smooth the elevation map with gaussian blur
+        Utils.gaussConvolution( interpolated, smoothed, new double[]{ 1.0, 1.0 } );
+        return smoothed;
+    }
+
+    //TODO Handle the NOSurfaceFoundException dynamically : this particular surface has to be constructed with a
+    // smaller StartingOSMinimumSize but not necessary the other ones.
+    // May be add a static variable to store the maximum OS size per surfaces
+    //
+
+    /**
+     * Merges the TempSurface objects of the specified list.
+     *
+     * @param surfaces - the list to merge
+     */
+    private  void mergeReferenceSurface( ArrayList< Surface > surfaces )
+    {
+        // Merging step.
+        ArrayList< Surface > toRemoved = new ArrayList<>();
+        for ( int i = surfaces.size() - 1; i > 0; i-- )
+        {
+            Surface one = surfaces.get( i );
+            for ( int j = i - 1; j >= 0; j-- )
+            {
+                Surface two = surfaces.get( j );
+                if ( one.sameSurface( two ) )
+                {
+                    two.merge( one );
+                    toRemoved.add( one );
+                }
+            }
+        }
+        surfaces.removeAll( toRemoved );
+    }
+
+    private OSEList[] constructOSLists( Pixels[][] maximums, int dimension)
+    {
+        OSEListConstruction construction = new OSEListConstruction( maximums, dimension );
+        construction.run();
+        return  construction.getOseLists();
+    }
+
+
+    private ArrayList<Surface> constructSurfaces(Pixels[][] maximums, int dimension, double percent, int k)
+    {
+        int surfaceLineLength = maximums[0].length;
+        OSEList[] oseLists = constructOSLists( maximums, dimension );
+        SurfacesReconstruction surfacesReconstruction = new SurfacesReconstruction(dimension, oseLists,surfaceLineLength, percent, k);
+        surfacesReconstruction.buildSurfaces(  );
+        System.out.println(" Small Surface count : " + surfacesReconstruction.getSmallSurfaceCount());
+        return surfacesReconstruction.getSurfaces();
+    }
+
+    private void processZMap(ArrayList<Surface> surfaces)
+    {
+        int index = 0;
+        for( Surface surface : surfaces )
+        {
+            displaySurface( surface );
+            Img< UnsignedShortType > processedZMap = processedZMap( surface );
+            ReferenceSurface< T > referenceSurface = new ReferenceSurface<>( input, factory, processedZMap, index++ );
+            referenceSurfaces.add( referenceSurface );
+        }
+    }
+
+    public void project()
+    {
+        for(ReferenceSurface<T> referenceSurface : referenceSurfaces)
+        {
+            referenceSurface.setProjection( userParameters.getProjectionType(), userParameters.getDelta() );
+            DisplayParameter displayParameter = new DisplayParameter( userParameters.getDelta(), true,
+                    true, true, true );
+            referenceSurface.display( displayParameter );
+        }
+    }
+
+
+    /* -----  Displaying methods -----*/
+    /**
+     * Displays the local maximums found using jzy3D package.
+     */
+    public static void displayMaximums( Pixels[][] maximums )
+    {
+        try
+        {
+            LocalMaximumsDisplay localMaximumsDisplay = new LocalMaximumsDisplay( maximums );
+            AnalysisLauncher.open( localMaximumsDisplay );
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Displays the local maximums found using jzy3D package.
+     */
+    public static void displayOS( OSEList[] oseLists )
+    {
+        try
+        {
+            OSDisplay display = new OSDisplay( oseLists );
+            AnalysisLauncher.open( display );
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+
+
+    public static void displaySurface( Surface surface )
+    {
+        try
+        {
+            SurfaceDisplay s = new SurfaceDisplay( surface );
+            AnalysisLauncher.open( s );
+        }
+        catch ( Exception e )
+        {
+            e.printStackTrace();
+        }
+
+    }
+
+}
+
+
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/SurfacePixelSelection.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacePixelSelection.java
similarity index 77%
rename from src/main/java/fr/pasteur/ida/zellige/utils/SurfacePixelSelection.java
rename to src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacePixelSelection.java
index 7691c3e8..aa34c762 100644
--- a/src/main/java/fr/pasteur/ida/zellige/utils/SurfacePixelSelection.java
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacePixelSelection.java
@@ -1,12 +1,13 @@
-package fr.pasteur.ida.zellige.utils;
+package fr.pasteur.ida.zellige.surfaceConstruction.construction;
 
 import fr.pasteur.ida.zellige.jzy3D.LocalMaximumsDisplay;
+import fr.pasteur.ida.zellige.surfaceConstruction.parameters.UserParameters;
 import fr.pasteur.ida.zellige.surfaceConstruction.element.Coordinate;
 import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
+import fr.pasteur.ida.zellige.utils.*;
 import net.imglib2.RandomAccess;
 import net.imglib2.RandomAccessibleInterval;
 import net.imglib2.converter.Converters;
-import net.imglib2.converter.RealFloatConverter;
 import net.imglib2.converter.readwrite.RealFloatSamplerConverter;
 import net.imglib2.img.Img;
 import net.imglib2.img.ImgFactory;
@@ -16,34 +17,36 @@ import net.imglib2.type.NativeType;
 import net.imglib2.type.logic.BitType;
 import net.imglib2.type.numeric.RealType;
 import net.imglib2.type.numeric.real.FloatType;
-import net.imglib2.util.ImgUtil;
 import org.jzy3d.analysis.AnalysisLauncher;
 
 public class SurfacePixelSelection
 {
 
+    private final UserParameters userParameters;
+    private Pixels[][] maximums;
+
+    public SurfacePixelSelection( UserParameters userParameters )
+    {
+        this.userParameters = userParameters;
+    }
 
     /**
      *
      * @param source
-     * @param amplitude
-     * @param threshold
-     * @param sigmas
      * @param <T>
      * @return
      */
-    public static < T extends RealType< T > & NativeType< T > > Pixels[][] run( RandomAccessibleInterval< T > source, double amplitude, double threshold, int sigmas )
+    public < T extends RealType< T > & NativeType< T > > void run( RandomAccessibleInterval< T > source )
     {
         /* Pretreatment of the image.*/
         Img< FloatType > normalized = pretreatment( source );
         ImageJFunctions.show( normalized.copy(), "converted, blurred and normalized " );
         ImgFactory<FloatType> factory = normalized.factory();
         /* Local maximum search and selection */
-        Pixels[][] maximums  = maximumSearch( normalized, factory, amplitude,threshold, sigmas );
+        maximums  = maximumSearch( normalized, factory );
 
         /* Output  */
         displayMaximums( maximums );
-        return maximums;
     }
 
     /**
@@ -52,7 +55,7 @@ public class SurfacePixelSelection
      * @param <T>
      * @return
      */
-    private static < T extends RealType< T > & NativeType< T > >Img<FloatType> pretreatment( RandomAccessibleInterval< T > source )
+    private  < T extends RealType< T > & NativeType< T > >Img<FloatType> pretreatment( RandomAccessibleInterval< T > source )
     {
         // Conversion into FloatType for the derivative computation (negative values)
         RandomAccessibleInterval< FloatType > converted = Converters.convert( source, new RealFloatSamplerConverter< T >() );
@@ -65,44 +68,41 @@ public class SurfacePixelSelection
        return Utils.normalizeImage( c, c.factory());
     }
 
-
     /**
      *
      * @param input
-     * @param amplitude
-     * @param threshold
-     * @param sigma
+     * @param factory
      * @param <T>
      * @return
      */
-    private static < T extends RealType< T > & NativeType< T > > Pixels[][] maximumSearch( RandomAccessibleInterval< T > input,ImgFactory<T> factory, double amplitude, double threshold, int sigma  )
+    private  < T extends RealType< T > & NativeType< T > > Pixels[][] maximumSearch( RandomAccessibleInterval< T > input,ImgFactory<T> factory )
     {
         /* Grid of amplitude thresholds */
-        Img< FloatType > amplitudeImg = MaximumAmplitudeClassification.find(input,factory, amplitude, 0.10);
+        Img< FloatType > amplitudeImg = MaximumAmplitudeClassification.find(input,factory,userParameters.getAmplitude() , 0.10);
         ImageJFunctions.show( amplitudeImg," amplitude" );
 
         /* Grid of local thresholds*/
-        Img< BitType > thresholds = LocalOtsuClassification.find( input, factory, threshold );
+        Img< BitType > thresholds = LocalOtsuClassification.find( input, factory, userParameters.getThreshold());
 
         /* Pixel selection */
         Img<FloatType> finalList = Threshold.classification( amplitudeImg, amplitudeImg.factory(), thresholds );
 
         /* Dilatation of the resulting image*/
+        double sigma = userParameters.getSigmas();
         Utils.gaussConvolution( finalList.copy(), finalList, new double[]{ sigma, sigma, 1 } );
         ImageJFunctions.show(finalList, "blurred maximums" );
 
         /* Local maximum detection due to previous smoothing*/
-        finalList = LocalMaximumDetection.findMaximums( finalList.copy(), finalList.factory() );
+        finalList = LocalExtremaDetection.findMaxima( finalList.copy(), finalList.factory() );
         return buildPixelArray( finalList );
     }
-
     /**
      *
      * @param stack
      * @param <T>
      * @return
      */
-    public static < T extends RealType< T > & NativeType< T > > Pixels[][] buildPixelArray(
+    public  < T extends RealType< T > & NativeType< T > > Pixels[][] buildPixelArray(
             final RandomAccessibleInterval< T > stack )
     {
         RandomAccess< T > access = stack.randomAccess();
@@ -147,4 +147,8 @@ public class SurfacePixelSelection
         }
     }
 
+    public Pixels[][] getMaximums()
+    {
+        return maximums;
+    }
 }
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacesExtraction.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacesExtraction.java
deleted file mode 100644
index e6272016..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacesExtraction.java
+++ /dev/null
@@ -1,338 +0,0 @@
-package fr.pasteur.ida.zellige.surfaceConstruction.construction;
-
-import fr.pasteur.ida.zellige.exception.FirstRoundConstructionException;
-import fr.pasteur.ida.zellige.exception.NoSurfaceFoundException;
-import fr.pasteur.ida.zellige.jzy3D.LocalMaximumsDisplay;
-import fr.pasteur.ida.zellige.jzy3D.OSDisplay;
-import fr.pasteur.ida.zellige.jzy3D.SurfaceDisplay;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Surface;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSE;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSEStartingStatus;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSList;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine.SurfaceLine;
-import fr.pasteur.ida.zellige.utils.*;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.img.Img;
-import net.imglib2.img.ImgFactory;
-import net.imglib2.img.display.imagej.ImageJFunctions;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.type.numeric.integer.UnsignedShortType;
-import org.jzy3d.analysis.AnalysisLauncher;
-
-import java.util.ArrayList;
-
-
-
-public class SurfacesExtraction
-{
-
-    public static < T extends RealType< T > & NativeType< T > > void extract(
-            RandomAccessibleInterval< T > input, ImgFactory<T> factory,double amplitude, double threshold, int sigmas,
-            boolean zMapDisplay, int delta,
-            boolean extractedStackDisplay,
-            boolean heightMapDisplay,
-            boolean projectionDisplay,
-            String projectionType ,
-            int k1, double percent1, int k2, double percent2)
-    {
-        /* First step : Pixel selection */
-        Pixels[][] maximums = SurfacePixelSelection.run( input, amplitude, threshold, sigmas );
-        int width = ( int ) input.dimension( 0 );
-        int height = ( int ) input.dimension( 1 );
-        try
-        {
-            /*  First round construction*/
-            ArrayList< Surface > surfaces = firstRoundConstruction( maximums, width, height , percent1, k1);
-            System.out.println( "first round surfaces = " + surfaces.size() );
-//
-            for (Surface surface : surfaces) {
-                displaySurface(surface);
-            }
-            // Second round construction
-            ArrayList< Surface > finalSurfaces = secondRoundConstruction( surfaces, width, height, percent2, k2 );
-//            if ( !finalSurfaces.isEmpty() )
-//            {
-            int index = 0;
-            for ( Surface surface : finalSurfaces )
-            {
-                System.out.println( "Surface number " + index );
-//                displaySurface(surface);
-                Img< UnsignedShortType > zMap = surface.getZMap();
-                projection( input, factory,delta, zMap, zMapDisplay,
-                        extractedStackDisplay, heightMapDisplay,
-                        projectionDisplay, projectionType, index );
-                index++;
-            }
-
-//            // Display the projection
-            System.out.println( "The end" );
-        }
-        catch ( Exception e )
-        {
-            e.printStackTrace();
-        }
-    }
-
-
-    /**
-     * Creates the OS for each orthogonal section from the maximum coordinates found according to the dimension.
-     *
-     * @param maximums     - the local maximums found with the {@link LocalMaximumDetection} class.
-     * @param osListsArray - the OS corresponding to a 1D surface.
-     */
-    private static void set( Pixels[][] maximums, OSList[] osListsArray, int dimension, OSEStartingStatus startingStatus )
-    {
-
-
-        for ( int i = 0; i <= maximums.length - 1; i++ )
-        {
-            osListsArray[ i ] = OSConstruction.findOS( maximums[ i ], dimension, startingStatus );
-        }
-        startingStatus.setStartingStatus();
-    }
-
-    /* ----- First and second round construction methods. ----- */
-    private static ArrayList< Surface > firstRoundConstruction( Pixels[][] maximums, int width, int height, double percent, int k ) throws NoSurfaceFoundException
-    {
-        int dimension = 0;
-        // Setting and storage of the OS build in the X dimension according to the user thresholds settings.
-        OSEStartingStatus startingStatus = new OSEStartingStatus( dimension );
-        OSList[] osListsArrayX = new OSList[ height ];
-        set( maximums, osListsArrayX, dimension, startingStatus );
-//        displayOS(osListsArrayX);
-        System.out.println( "OS.count = " + OSE.getCount() );
-        /* Construction of the tempSurfaces*/
-        ArrayList< Surface > surfaces =
-                SurfacesReconstruction.buildSurfaces( 0, osListsArrayX, width, height, percent, k );
-        if ( ! surfaces.isEmpty() )
-        {
-            mergeReferenceSurface( surfaces );
-        }
-        else
-        {
-            System.out.println( "No Surface Exception" );
-            throw new FirstRoundConstructionException();
-        }
-        return surfaces;
-    }
-
-    /**
-     * Rebuilds the double pixel array from the {@link SurfaceLine} array
-     * of a {@link Surface} for a construction in the height dimension.
-     *
-     * @param surface - the {@link SurfaceLine}  array of a {@link Surface}
-     * @return a {@link Surface} specific double pixel array.
-     */
-    private static Pixels[][] rebuildPixelsArray( Surface surface, int width, int height )
-    {
-        Pixels[][] tempCoordinates = new Pixels[ width ][ height ]; // Transposed array
-        for ( int i = 0; i <= height - 1; i++ )
-        {
-            for ( int j = 0; j <= width - 1; j++ )
-            {
-                if ( surface.get( i ) != null )
-                {
-                    tempCoordinates[ j ][ i ] = surface.get( i ).get( j );
-                }
-            }
-        }
-        displayMaximums( tempCoordinates );
-        return tempCoordinates;
-    }
-
-    /**
-     * Converts and transposes the specified Surface object into the specified OSList array.
-     *
-     * @param surface       - the Surface object to process
-     * @param osListsArrayY -the output OSList array
-     */
-    private static void transposeSurfaceLines( Surface surface, OSList[] osListsArrayY, int width, int height )
-    {
-        int dimension = 1;
-        Pixels[][] pixels = rebuildPixelsArray( surface, width, height );
-        /* OS construction in dimension height.*/
-        OSEStartingStatus startingStatus = new OSEStartingStatus( dimension );
-        set( pixels, osListsArrayY, dimension, startingStatus );
-    }
-
-
-    /* -----  Other displaying methods -----*/
-
-    /**
-     * Reconstructs the TempSurface objects  of the specified list in dimension width.
-     *
-     * @param surfaces - the list of TempSurface objects.
-     * @return a list of reconstructed Tempsurface objects
-     */
-    private static ArrayList< Surface > secondRoundConstruction( ArrayList< Surface > surfaces, int width, int height, double percent, int k ) throws NoSurfaceFoundException
-    {
-        System.out.println( "========================================" );
-        ArrayList< Surface > finalSurfaces = new ArrayList<>();
-
-        for ( Surface surface : surfaces )
-        {
-            if ( surface.hasDuplicate() )// CoordinateList instead of Coordinate
-            {
-                OSList[] osListsArrayY = new OSList[ width ];
-
-                transposeSurfaceLines( surface, osListsArrayY, width, height );
-                OSE.setStartingStatus( 1 );
-                System.out.println( "OS.count = " + OSE.getCount() );
-
-//                displayOS( osListsArrayY );
-                ArrayList< Surface > temps = SurfacesReconstruction.buildSurfaces( 1, osListsArrayY, width, height, percent, k );
-                if ( temps.isEmpty() )
-                {
-                    System.out.println( "small surface in second round" );
-//                    throw new SecondRoundConstructionException();
-                }
-                else
-                {
-                    finalSurfaces.addAll( temps );
-                }
-            }
-            else
-            {
-                finalSurfaces.add( surface.transpose() );
-            }
-        }
-        mergeReferenceSurface( finalSurfaces );
-        return finalSurfaces;
-    }
-    //TODO Handle the NOSurfaceFoundException dynamically : this particular surface has to be constructed with a
-    // smaller StartingOSMinimumSize but not necessary the other ones.
-    // May be add a static variable to store the maximum OS size per surfaces
-    //
-
-    /**
-     * Merges the TempSurface objects of the specified list.
-     *
-     * @param surfaces - the list to merge
-     */
-    private static void mergeReferenceSurface( ArrayList< Surface > surfaces )
-    {
-        // Merging step.
-        ArrayList< Surface > toRemoved = new ArrayList<>();
-        for ( int i = surfaces.size() - 1; i > 0; i-- )
-        {
-            Surface one = surfaces.get( i );
-            for ( int j = i - 1; j >= 0; j-- )
-            {
-                Surface two = surfaces.get( j );
-                if ( one.sameSurface( two ) )
-                {
-                    two.merge( one );
-                    toRemoved.add( one );
-                }
-            }
-        }
-        surfaces.removeAll( toRemoved );
-    }
-
-
-    private static < R extends RealType< R > & NativeType< R > > void projection(
-            RandomAccessibleInterval< R > original, ImgFactory<R> factory, int delta, Img< UnsignedShortType > zMap,
-            boolean zMapDisplay,
-            boolean extractedStackDisplay,
-            boolean heightMapDisplay,
-            boolean projectionDisplay,
-            String projectionType, int index )
-    {
-
-        // First step : fill in the holes. */
-        Img< UnsignedShortType > interpolated = Interpolation.execute( zMap );
-        Img< UnsignedShortType > smoothed = interpolated.copy();
-        Utils.gaussConvolution( interpolated, smoothed, new double[]{ 1.0, 1.0 } );
-//         Second step smoothed the elevation map
-        if ( zMapDisplay )
-        {
-            ImageJFunctions.show( smoothed, "Elevation map" + "RS n°" + index );
-        }
-
-        Img< R > extractedStack = StackProjection.getExtractedStack( original, factory, smoothed, delta );
-        if ( extractedStackDisplay )
-        {
-            ImageJFunctions.show( extractedStack,
-                    "Extracted stack (delta = " + delta + ")" + "RS n°" + index );
-        }
-        if ( projectionDisplay )
-        {
-            // A heightmap can be displayed
-            if ( projectionType.equals( "MIP" ) ||
-                    projectionType.equals( "Minimum Intensity" ) )
-            {
-                Img< UnsignedShortType > heightMap = StackProjection.getHeightMap
-                        ( original, smoothed, projectionType, delta );
-                if ( heightMapDisplay )
-                {
-                    ImageJFunctions.show( heightMap, "Height Map with " +
-                            projectionType + " RS n°" + index );
-                }
-
-                Img< R > projection = StackProjection.projection1( original,factory, heightMap, projectionType );
-                ImageJFunctions.show( projection, "Projection with " + projectionType + " RS n°" + index );
-            }
-            else
-            {
-
-                Img< R > projection = StackProjection.projection2( StackProjection.getHeightMapStack( original, factory,zMap, delta ),factory, projectionType );
-                ImageJFunctions.show( projection, "Projection with " + projectionType + " RS n°" + index );
-
-            }
-//            ImageJFunctions.show(StackProjection.getHeightMapStack(original, zMap, delta), "HMS");
-        }
-
-    }
-
-    /**
-     * Displays the local maximums found using jzy3D package.
-     */
-    public static void displayMaximums( Pixels[][] maximums )
-    {
-        try
-        {
-            LocalMaximumsDisplay localMaximumsDisplay = new LocalMaximumsDisplay( maximums );
-            AnalysisLauncher.open( localMaximumsDisplay );
-        }
-        catch ( Exception e )
-        {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Displays the local maximums found using jzy3D package.
-     */
-    public static void displayOS( OSList[] osLists )
-    {
-        try
-        {
-            OSDisplay display = new OSDisplay( osLists );
-            AnalysisLauncher.open( display );
-        }
-        catch ( Exception e )
-        {
-            e.printStackTrace();
-        }
-    }
-
-
-    public static void displaySurface( Surface surface )
-    {
-        try
-        {
-            SurfaceDisplay s = new SurfaceDisplay( surface );
-            AnalysisLauncher.open( s );
-        }
-        catch ( Exception e )
-        {
-            e.printStackTrace();
-        }
-
-    }
-
-}
-
-
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacesReconstruction.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacesReconstruction.java
index 020be569..35b57ad6 100644
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacesReconstruction.java
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacesReconstruction.java
@@ -1,8 +1,8 @@
 package fr.pasteur.ida.zellige.surfaceConstruction.construction;
 
 
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSE;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSList;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSE;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSEList;
 import fr.pasteur.ida.zellige.surfaceConstruction.element.Surface;
 import fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine.SurfaceLine;
 import fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine.SurfaceLineX;
@@ -17,33 +17,46 @@ import java.util.ArrayList;
 public class SurfacesReconstruction
 {
 
-    private static int smallSurfaceCount;
+    private final ArrayList< Surface > surfaces = new ArrayList<>();
+    private final int dimension;
+    private final OSEList[] oseLists;
+    private final int surfaceLineLength;
+    private final double percent;
+    private final int k;
+
+    private int smallSurfaceCount;
+
+    public SurfacesReconstruction( int dimension, OSEList[] oseLists, int surfaceLineLength, double percent, int k )
+    {
+        this.dimension = dimension;
+        this.oseLists = oseLists;
+        this.surfaceLineLength = surfaceLineLength;
+        this.percent = percent;
+        this.k = k;
+    }
+
     /**
      * Returns a list of TempSurface constructed from the specified OSList array.
      *
-     * @param dimension - the dimension in which the construction have to be made.
-     * @param osLists   - the array of OSList
-     * @return a list of TempSurface
      */
-    public static ArrayList< Surface > buildSurfaces( int dimension, OSList[] osLists, int width, int height , double percent, int k)
+    public void buildSurfaces()
     {
         // Construction of the list of output TempSurface.
-        ArrayList< Surface > surfaces = new ArrayList<>();
         smallSurfaceCount = 0;
-        int finalIndex = findIndexValue( osLists, 0, dimension, width, height );
+        int finalIndex = findIndexValue( 0 );
         do
         {
             // All the OSLists are set to "not visited".
-            reset( osLists );
+            reset();
             int startingIndex = finalIndex;
-            OSE firstOSE = getFirstOs( osLists, finalIndex );
+            OSE firstOSE = getFirstOs( finalIndex );
 //            osLists[finalIndex].remove( firstOS );//TODO remove or not
             if ( firstOSE != null )
             {
-                Surface surface = createSurface( firstOSE, dimension, width, height);
-                buildSurface( osLists, surface, finalIndex, width, height , percent, k);
+                Surface surface = createSurface( firstOSE, surfaceLineLength );
+                buildSurface(  surface, finalIndex );
                 //it is really a reference surface ?
-                if ( surface.getSize() >= width * height * 0.01 )
+                if ( surface.getSize() >= surfaceLineLength * oseLists.length * 0.01 )
                 {
                     surfaces.add( surface );
                 }
@@ -52,33 +65,30 @@ public class SurfacesReconstruction
                     smallSurfaceCount++;
                     System.out.println( "searching.....from " );
                 }
-                finalIndex = findIndexValue( osLists, startingIndex, dimension, width, height );
+                finalIndex = findIndexValue( startingIndex );
             }
         }
-        while ( finalIndex <= osLists.length - 2
-                && ( osLists[ finalIndex ] != null
-                && ! osLists[ finalIndex ].isEmpty()
-                && osLists[ finalIndex ].containsAStart() ) );
-        System.out.println( "Starting size = " + OSE.getStartingSize());
+        while ( finalIndex <= oseLists.length - 2
+                && ( oseLists[ finalIndex ] != null
+                && ! oseLists[ finalIndex ].isEmpty()
+                && oseLists[ finalIndex ].containsAStart() ) );
         System.out.println( "smallSurfaceCount = " + smallSurfaceCount );
-        return surfaces;
     }
 
     /**
      * Adds new SurfaceLine to a specified TempSurface.
      *
-     * @param osLists - the OSList array in which to search
-     * @param surface - the TempSurface to construct
-     * @param index   - the position in the TempSurface
+     * @param surface  - the TempSurface to construct
+     * @param index    - the position in the TempSurface
      */
-    private static void buildSurface( OSList[] osLists, Surface surface, int index, int width, int height, double percent, int k  )
+    private void buildSurface(  Surface surface, int index )
     {
         /* First round of the construction -> top to bottom in the dimension.*/
         SurfaceLine current = surface.get( index );
         SurfaceLine next;
         while ( current != null )
         {
-            next = searchForward( osLists, current, width, height , percent, k);
+            next = searchForward( current );
             if ( next != null )
             {
                 surface.set( next.getLine(), next );
@@ -91,11 +101,11 @@ public class SurfacesReconstruction
         while ( size != surface.getSize() )
         {
             size = surface.getSize();
-            for ( int i = surface.getLength() - 1; i > 0; i-- )
+            for ( int i = surface.getHeight() - 1; i > 0; i-- )
             {
                 if ( surface.get( i ) != null )
                 {
-                    SurfaceLine previous = searchBackward( osLists, surface.get( i ), percent, k );
+                    SurfaceLine previous = searchBackward( surface.get( i ) );
                     if ( previous != null )
                     {
                         if ( surface.get( i - 1 ) != null )
@@ -109,11 +119,11 @@ public class SurfacesReconstruction
                     }
                 }
             }
-            for ( int i = 0; i <= surface.getLength() - 2; i++ )
+            for ( int i = 0; i <= surface.getHeight() - 2; i++ )
             {
                 if ( surface.get( i ) != null )
                 {
-                    next = searchForward( osLists, surface.get( i ), width, height , percent, k);
+                    next = searchForward( surface.get( i ) );
                     if ( next != null )
                     {
                         if ( surface.get( i + 1 ) != null )
@@ -132,24 +142,23 @@ public class SurfacesReconstruction
 
 
     /**
-     * @param firstOSE   - the first surface element.
-     * @param dimension - the construction dimension
+     * @param firstOSE  - the first surface element.
      * @return a surface as a {@link Surface}
      */
-    private static Surface createSurface( OSE firstOSE, int dimension, int width, int height)
+    private Surface createSurface( OSE firstOSE, int surfaceLineLength )
     {
-        Surface surface = new Surface( dimension, width, height );
+        Surface surface = new Surface( dimension, oseLists.length );
 
         int i;
         if ( dimension == 0 )
         {
             i = firstOSE.get( 0 ).getY();
-            surface.set( i, new SurfaceLineX( width, firstOSE ) );
+            surface.set( i, new SurfaceLineX( surfaceLineLength, firstOSE ) );
         }
         else
         {
             i = firstOSE.get( 0 ).getX();
-            surface.set( i, new SurfaceLineY(height,  firstOSE ) );
+            surface.set( i, new SurfaceLineY( surfaceLineLength, firstOSE ) );
         }
         return surface;
     }
@@ -157,28 +166,19 @@ public class SurfacesReconstruction
     /**
      * Returns the index value of the first OSList containing a starting OS.
      *
-     * @param osLists   - the OSList array in which to search
-     * @param index     - the previous index value
-     * @param dimension - the dimension in which the construction has to occur
+     * @param index    - the previous index value
      * @return the value of the first OSList containing a starting OS
      */
-    private static int findIndexValue( OSList[] osLists, int index, int dimension, int width, int height )
+    private int findIndexValue( int index )
     {
         int i = index;
         int limitValue;
-        if ( dimension == 0 )
-        {
-            limitValue = height - 1;
-        }
-        else
-        {
-            limitValue = width - 1;
-        }
+        limitValue = oseLists.length - 1;
         while ( i <= limitValue - 2 )
         {
-            if ( osLists[ i ] != null
-                    && ! osLists[ i ].isEmpty()
-                    && osLists[ i ].containsAStart() )
+            if ( oseLists[ i ] != null
+                    && ! oseLists[ i ].isEmpty()
+                    && oseLists[ i ].containsAStart() )
             {
                 return i;
             }
@@ -191,13 +191,12 @@ public class SurfacesReconstruction
     /**
      * Returns the first OS with a start status in the OSList array.
      *
-     * @param osLists - the OSList array in which to search
-     * @param index   - the previous index value
+     * @param index the previous index value
      * @return the first OS with a true Start status
      */
-    private static OSE getFirstOs( OSList[] osLists, int index )
+    private OSE getFirstOs( int index )
     {
-        for ( OSE os : osLists[ index ] )
+        for ( OSE os : oseLists[ index ] )
         {
             if ( os.isAStart() )
             {
@@ -216,20 +215,8 @@ public class SurfacesReconstruction
      * @param j           - the direction of the search (1 or -1)
      * @return the OSList matching SurfaceLine
      */
-    private static SurfaceLine search( OSList next, SurfaceLine currentLine, int j ,  double percent, int k)
-    {// TODO USER PARAMETER
-//        double percent;
-//        int k;
-//        if ( currentLine instanceof SurfaceLineX )
-//        {
-//            percent = 0.6;//TODO user parameter ?
-//            k = 5;
-//        }
-//        else
-//        {
-//            percent = 0.7;
-//            k = 2;
-//        }
+    private SurfaceLine search( OSEList next, SurfaceLine currentLine, int j )
+    {
         ArrayList< SurfaceLine > list = new ArrayList<>();
         for ( OSE os : next )
         {
@@ -257,25 +244,15 @@ public class SurfacesReconstruction
     /**
      * Returns the SurfaceLine generated from the specified OSList array matching the current SurfaceLine
      *
-     * @param osLists - the OSList array in which to search
-     * @param current - the {@link SurfaceLine } to match
+     * @param current  - the {@link SurfaceLine } to match
      * @return the SurfaceLine generated from the specified OSList array matching the current SurfaceLine
      */
-    private static SurfaceLine searchForward( OSList[] osLists, SurfaceLine current , int width, int height, double percent, int k)
+    private SurfaceLine searchForward( SurfaceLine current )
     {
-        int length;
-        if ( current instanceof SurfaceLineX )
-        {
-            length = height;
-        }
-        else
-        {
-            length = width;
-        }
 
-        if ( current.getLine() + 1 <= length - 1 )
+        if ( current.getLine() + 1 <= oseLists.length - 1 )
         {
-            return search( osLists[ current.getLine() + 1 ], current, 1 , percent, k);
+            return search( oseLists[ current.getLine() + 1 ], current, 1 );
         }
         else
         {
@@ -284,15 +261,14 @@ public class SurfacesReconstruction
     }
 
     /**
-     * @param osLists - the {@link OSList} to search in.
-     * @param current - the current SurfaceLine to match with.
+     * @param current  - the current SurfaceLine to match with.
      * @return - the matching SurfaceLine.
      */
-    private static SurfaceLine searchBackward( OSList[] osLists, SurfaceLine current, double percent, int k)
+    private SurfaceLine searchBackward( SurfaceLine current )
     {
         if ( current.getCoordinatesNumber() != 0 && current.getLine() > 0 )
         {
-            return search( osLists[ current.getLine() - 1 ], current, - 1, percent, k );
+            return search( oseLists[ current.getLine() - 1 ], current, - 1 );
         }
         else
         {
@@ -305,7 +281,7 @@ public class SurfacesReconstruction
      *
      * @param list - the list to merge.
      */
-    private static void merge( ArrayList< SurfaceLine > list )
+    private void merge( ArrayList< SurfaceLine > list )
     {
         if ( list.size() >= 2 ) //more than one SurfaceLine
         {
@@ -322,16 +298,25 @@ public class SurfacesReconstruction
     /**
      * Resets the "visited" value of each OS of each OSList to FALSE.
      *
-     * @param osLists - an array of {@link OSList} to reset.
      */
-    private static void reset( OSList[] osLists )
+    private void reset()
     {
-        for ( OSList osList : osLists )
+        for ( OSEList oseList : oseLists )
         {
-            if ( osList != null )
+            if ( oseList != null )
             {
-                osList.reset();
+                oseList.reset();
             }
         }
     }
+
+    public int getSmallSurfaceCount()
+    {
+        return smallSurfaceCount;
+    }
+
+    public ArrayList< Surface > getSurfaces()
+    {
+        return surfaces;
+    }
 }
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ReferenceSurface.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ReferenceSurface.java
new file mode 100644
index 00000000..0ab013ec
--- /dev/null
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ReferenceSurface.java
@@ -0,0 +1,88 @@
+package fr.pasteur.ida.zellige.surfaceConstruction.element;
+
+import fr.pasteur.ida.zellige.surfaceConstruction.parameters.DisplayParameter;
+import fr.pasteur.ida.zellige.utils.StackProjection;
+import net.imglib2.RandomAccessibleInterval;
+import net.imglib2.img.Img;
+import net.imglib2.img.ImgFactory;
+import net.imglib2.img.display.imagej.ImageJFunctions;
+import net.imglib2.type.NativeType;
+import net.imglib2.type.numeric.RealType;
+import net.imglib2.type.numeric.integer.UnsignedShortType;
+
+public class ReferenceSurface< T extends RealType< T > & NativeType< T > >
+{
+    private final RandomAccessibleInterval<T> input;
+    private final ImgFactory<T> factory;
+    private final Img< UnsignedShortType > zMap;
+    private Img<T> extractedStack;
+    private Img< UnsignedShortType > elevationMap;
+    private Img< T > projection;
+    private Img< T > heightMapStack;
+    private int index;
+    private int delta;
+    private String projectionType;
+
+
+    public ReferenceSurface( RandomAccessibleInterval<T> input,
+                             ImgFactory<T> factory, Img< UnsignedShortType > zMap, int index)
+    {
+        this.input = input;
+        this.factory = factory;
+        this.zMap = zMap;
+        this.index = index;
+    }
+
+    public void setProjection( String projectionType, int delta)
+    {
+        this.delta = delta;
+        this.projectionType = projectionType;
+        ImageJFunctions.show( zMap, "input zMap" );
+        extractedStack = StackProjection.getExtractedStack( input, factory, zMap, delta );
+
+        if ( projectionType.equals( "MIP" ) ||
+                projectionType.equals( "Minimum Intensity" ) )
+        {
+            elevationMap = StackProjection.getElevationMap ( input, zMap, projectionType, delta );
+             projection = StackProjection.projection1( input,factory, elevationMap, projectionType );
+        }
+        else
+        {
+           heightMapStack = StackProjection.getHeightMapStack( input, factory,zMap, delta );
+            projection = StackProjection.projection2( heightMapStack,factory, projectionType );
+        }
+
+    }
+
+    public   void display( DisplayParameter displayParameter )
+    {
+        if ( projection != null )
+        {
+            if ( displayParameter.iszMapDisplay() )
+            {
+                ImageJFunctions.show( zMap, "Elevation map" + "RS n°" + index );
+            }
+
+
+            if ( displayParameter.isExtractedStackDisplay() )
+
+            {
+                ImageJFunctions.show( extractedStack,
+                        "Extracted stack (delta = " + delta + ")" + "RS n°" + index );
+            }
+            if ( displayParameter.isProjectionDisplay() )
+            {
+                ImageJFunctions.show( projection, "Projection with " + projectionType + " RS n°" + index );
+                // A heightmap can be displayed
+            }
+            if ( displayParameter.isElevationMapDisplay() )
+            {
+                ImageJFunctions.show( elevationMap, "Height Map with " +
+                        projectionType + " RS n°" + index );
+            }
+        }
+    }
+
+}
+
+
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/Surface.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/Surface.java
index ec5214dc..9d460f5c 100644
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/Surface.java
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/Surface.java
@@ -1,6 +1,6 @@
 package fr.pasteur.ida.zellige.surfaceConstruction.element;
 
-import fr.pasteur.ida.zellige.surfaceConstruction.construction.SurfacesExtraction;
+import fr.pasteur.ida.zellige.surfaceConstruction.construction.ReferenceSurfaceExtraction;
 import fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine.SurfaceLine;
 import fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine.SurfaceLineX;
 import fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine.SurfaceLineY;
@@ -9,6 +9,7 @@ import net.imglib2.FinalDimensions;
 import net.imglib2.RandomAccess;
 import net.imglib2.img.Img;
 import net.imglib2.img.ImgFactory;
+import net.imglib2.img.display.imagej.ImageJFunctions;
 import net.imglib2.type.numeric.integer.UnsignedShortType;
 import net.imglib2.util.Util;
 
@@ -19,23 +20,10 @@ public class Surface
 
     private final SurfaceLine[] surfaceLines;
     private final int dimension;
-    private  final int width;
-    private final int height;
 
 
-    public Surface( int dimension, int width, int height )
+    public Surface( int dimension, int length )
     {
-        this.width = width;
-        this.height = height;
-        int length;
-        if ( dimension == 0 )
-        {
-            length = height;
-        }
-        else
-        {
-            length = width;
-        }
         this.dimension = dimension;
         this.surfaceLines = new SurfaceLine[ length ];
     }
@@ -48,7 +36,7 @@ public class Surface
      */
     public boolean hasDuplicate()
     {
-        for ( int i = 0; i <= this.getLength() - 1; i++ )
+        for ( int i = 0; i <= this.getHeight() - 1; i++ )
         {
             SurfaceLine s = this.get( i );
             if ( s != null && s.hasDuplicate() )
@@ -122,7 +110,7 @@ public class Surface
     {
         int count = 0;
         int common = 0;
-        for ( int i = 0; i <= this.getLength() - 1; i++ )
+        for ( int i = 0; i <= this.getHeight() - 1; i++ )
         {
             if ( this.get( i ) != null && other.get( i ) != null )// There is a SurfaceLine at index i in both TempSurface
             {
@@ -143,7 +131,7 @@ public class Surface
      */
     public void merge( Surface otherSurface )
     {
-        for ( int i = 0; i <= this.getLength() - 1; i++ )
+        for ( int i = 0; i <= this.getHeight() - 1; i++ )
         {
             if ( this.get( i ) != null &&
                     otherSurface.get( i ) != null &&
@@ -159,23 +147,21 @@ public class Surface
      *
      * @return the identical transposed {@link Surface}
      */
-    public Surface transpose()
+    public Surface transpose(int length)
     {
-        Surface surface = new Surface( Math.abs( this.dimension - 1 ), width, height );
+        Surface surface = new Surface( Math.abs( this.dimension - 1 ), length );
         Class< ? > theClass;
-        int length;
+
         if ( this.dimension == 0 )
         {
             theClass = SurfaceLineY.class;
-            length = height;
         }
         else
         {
             theClass = SurfaceLineX.class;
-            length = width;
         }
 
-        for ( int i = 0; i <= this.getLength() - 1; i++ )
+        for ( int i = 0; i <= this.getHeight() - 1; i++ )
         {
             SurfaceLine surfaceLine = this.get( i );
             if ( surfaceLine != null )
@@ -243,8 +229,9 @@ public class Surface
 
     public Img< UnsignedShortType > getZMap()
     {
+        ReferenceSurfaceExtraction.displaySurface( this );
         int count = 0;
-        Dimensions dim = FinalDimensions.wrap( new long[]{width,height });
+        Dimensions dim = FinalDimensions.wrap( new long[]{surfaceLines.length,surfaceLines[0].getLength() });
         ImgFactory< UnsignedShortType > factory = Util.getArrayOrCellImgFactory(dim, new UnsignedShortType());
         Img< UnsignedShortType > zMap = factory.create(dim);
         RandomAccess< UnsignedShortType > randomAccess = zMap.randomAccess();
@@ -278,6 +265,7 @@ public class Surface
                 }
             }
         }
+        ImageJFunctions.show( zMap, "after getzmap" );
         System.out.println(" Thre count =  " + count);
         return zMap;
     }
@@ -319,7 +307,7 @@ public class Surface
 
 
 
-    public int getLength()
+    public int getHeight()
     {
         return this.surfaceLines.length;
     }
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/os/OSE.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ose/OSE.java
similarity index 67%
rename from src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/os/OSE.java
rename to src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ose/OSE.java
index db4332f6..eeddbe41 100644
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/os/OSE.java
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ose/OSE.java
@@ -1,4 +1,4 @@
-package fr.pasteur.ida.zellige.surfaceConstruction.element.os;
+package fr.pasteur.ida.zellige.surfaceConstruction.element.ose;
 
 import fr.pasteur.ida.zellige.surfaceConstruction.element.Coordinate;
 
@@ -10,14 +10,10 @@ import java.util.*;
  */
 public class OSE extends ArrayList< Coordinate >
 {
-    private static TreeSet <Integer> list = new TreeSet<>();
-    private static TreeMap<Integer, Integer> occ = new TreeMap<>();
-    private static int startingSize;
-    private  OSEStartingStatus startingStatus;
-
+    public static int sizeSum = 0;
     /* Not necessary for the program.*/
     private static int count = 0;
-    public static int sizeSum = 0;
+    private final OSEStartingStatus startingStatus;
     private int name;
     /*-------------*/
 
@@ -30,47 +26,32 @@ public class OSE extends ArrayList< Coordinate >
      */
     private boolean start = true;
 
-    public OSE(OSEStartingStatus startingStatus )
+    public OSE( OSEStartingStatus startingStatus )
     {
         this.startingStatus = startingStatus;
     }
 
+    public static int getCount()
+    {
+        return count;
+    }
+
     /**
      * Sets the start status to false if the size is inferior to the OS start minimum size.
      * Default value = 70 Pixels.
      * {@link Coordinate} of the OS
      */
-    public void set( )
+    public void set()
     {
-        list.add( this.size() );
-
-
-        /* Not necessary for the program.*/
-        this.name = count;
-        /*----------------*/
-        sizeSum = sizeSum + this.size();
-        count++;
-    }
-
-    public void set( int dimension )
-    {
-        list.add( this.size() );
-        Integer j = startingStatus.get(this.size() );
-
+        Integer j = startingStatus.get( this.size() );
+        startingStatus.put( this.size(), ( j == null ) ? 1 : j + 1 );
         /* Not necessary for the program.*/
         this.name = count;
         /*----------------*/
         sizeSum = sizeSum + this.size();
         count++;
-
-//        if(dimension == 0)
-        startingStatus.put( this.size(), ( j == null ) ? 1 : j + 1 );
-
-
-
     }
 
-
     /**
      * Test if the current instance is adjacent to the next OS instance.
      *
@@ -96,7 +77,6 @@ public class OSE extends ArrayList< Coordinate >
         }
     }
 
-
     /**
      * Returns true if the OS has been visited.
      *
@@ -107,16 +87,6 @@ public class OSE extends ArrayList< Coordinate >
         return visited;
     }
 
-    /**
-     * Sets the visited status to true (the instance belongs to a ReferenceSurface)
-     * and therefore sets the start status to false.
-     */
-    public void setVisited()
-    {
-        this.visited = true;
-        this.start = false;
-    }
-
     /**
      * Sets the visited parameter to the specified value.
      *
@@ -127,6 +97,15 @@ public class OSE extends ArrayList< Coordinate >
         this.visited = visited;
     }
 
+    /**
+     * Sets the visited status to true (the instance belongs to a ReferenceSurface)
+     * and therefore sets the start status to false.
+     */
+    public void setVisited()
+    {
+        this.visited = true;
+        this.start = false;
+    }
 
     /**
      * Indicates whether some other object is "equal to" this one
@@ -153,12 +132,7 @@ public class OSE extends ArrayList< Coordinate >
      */
     public boolean isAStart()
     {
-        return (this.size() >= this.startingStatus.getMinimumSize() && start);
-    }
-
-    public boolean isAStart(int minimumSize)
-    {
-        return (this.size() >= this.startingStatus.getMinimumSize() && start);
+        return ( this.size() >= this.startingStatus.getMinimumSize() && start );
     }
 
     /* Not necessary for the program.*/
@@ -167,54 +141,4 @@ public class OSE extends ArrayList< Coordinate >
         return ( " " + name );
     }
 
-public static void setStartingStatus(int dimension)
-{
-    //TODO user parameter ?
-    if (list.size() != 0)
-    {
-        startingSize = 0;
-        if ( dimension == 0 )
-        {
-                for ( int i = 0; list.size() > 20 && i <= list.size()* 0.75 ;i++ )
-            {
-                list.remove( list.last() );
-            }
-        }
-        else
-        {
-            for ( int i = 0; list.size() > 2 && i <= list.size() / 10; i++ )
-            {
-                list.remove( list.last() );
-            }
-        }
-        startingSize = list.last();
-        list = new TreeSet<>();
-    }}
-
-
-    public static void setStartingStatusStats(int dimension)
-    {
-            startingSize = list.last();
-}
-
-
-    public static int getCount()
-    {
-        return count;
-    }
-
-    public static void setCount( int count )
-    {
-        OSE.count = count;
-    }
-
-    public  TreeMap< Integer, Integer > getOcc()
-    {
-        return startingStatus;
-    }
-
-    public static int getStartingSize()
-    {
-        return startingSize;
-    }
 }
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/os/OSList.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ose/OSEList.java
similarity index 91%
rename from src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/os/OSList.java
rename to src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ose/OSEList.java
index 1bfe8bc4..c1c69856 100644
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/os/OSList.java
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ose/OSEList.java
@@ -1,4 +1,4 @@
-package fr.pasteur.ida.zellige.surfaceConstruction.element.os;
+package fr.pasteur.ida.zellige.surfaceConstruction.element.ose;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -6,11 +6,11 @@ import java.util.Collection;
 /**
  * An OSList object is simply an ArrayList of {@link OSE}
  */
-public class OSList extends ArrayList < OSE >
+public class OSEList extends ArrayList < OSE >
 {
 
 
-    public OSList( )
+    public OSEList( )
     {
     }
 
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/os/OSEStartingStatus.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ose/OSEStartingStatus.java
similarity index 93%
rename from src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/os/OSEStartingStatus.java
rename to src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ose/OSEStartingStatus.java
index 05c93286..be3f4c29 100644
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/os/OSEStartingStatus.java
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ose/OSEStartingStatus.java
@@ -1,4 +1,4 @@
-package fr.pasteur.ida.zellige.surfaceConstruction.element.os;
+package fr.pasteur.ida.zellige.surfaceConstruction.element.ose;
 
 import java.util.TreeMap;
 
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLine.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLine.java
index c6f09804..54321fb7 100644
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLine.java
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLine.java
@@ -2,8 +2,7 @@ package fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine;
 
 import fr.pasteur.ida.zellige.surfaceConstruction.element.Coordinate;
 import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSE;
-import fr.pasteur.ida.zellige.surfaceConstruction.construction.SurfacesExtraction;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSE;
 
 public abstract class SurfaceLine
 {
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLineX.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLineX.java
index 1fa11ca2..9fe02a4d 100644
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLineX.java
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLineX.java
@@ -1,7 +1,7 @@
 package fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine;
 
 import fr.pasteur.ida.zellige.surfaceConstruction.element.Coordinate;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSE;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSE;
 
 public class SurfaceLineX extends SurfaceLine
 {
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLineY.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLineY.java
index be9f4b50..9204b511 100644
--- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLineY.java
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/surfaceLine/SurfaceLineY.java
@@ -1,7 +1,7 @@
 package fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine;
 
 import fr.pasteur.ida.zellige.surfaceConstruction.element.Coordinate;
-import fr.pasteur.ida.zellige.surfaceConstruction.element.os.OSE;
+import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSE;
 
 public class SurfaceLineY extends SurfaceLine
 {
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/AdvancedUserParameters.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/AdvancedUserParameters.java
new file mode 100644
index 00000000..1f916320
--- /dev/null
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/AdvancedUserParameters.java
@@ -0,0 +1,57 @@
+package fr.pasteur.ida.zellige.surfaceConstruction.parameters;
+
+public class AdvancedUserParameters
+{
+    private int k1;
+    private double percent1;
+    private int k2;
+    private double percent2;
+
+    public AdvancedUserParameters( int k1, double percent1, int k2, double percent2 )
+    {
+        this.k1 = k1;
+        this.percent1 = percent1;
+        this.k2 = k2;
+        this.percent2 = percent2;
+    }
+
+    public int getK1()
+    {
+        return k1;
+    }
+
+    public void setK1( int k1 )
+    {
+        this.k1 = k1;
+    }
+
+    public double getPercent1()
+    {
+        return percent1;
+    }
+
+    public void setPercent1( double percent1 )
+    {
+        this.percent1 = percent1;
+    }
+
+    public int getK2()
+    {
+        return k2;
+    }
+
+    public void setK2( int k2 )
+    {
+        this.k2 = k2;
+    }
+
+    public double getPercent2()
+    {
+        return percent2;
+    }
+
+    public void setPercent2( double percent2 )
+    {
+        this.percent2 = percent2;
+    }
+}
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/DisplayParameter.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/DisplayParameter.java
new file mode 100644
index 00000000..5b0ad598
--- /dev/null
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/DisplayParameter.java
@@ -0,0 +1,40 @@
+package fr.pasteur.ida.zellige.surfaceConstruction.parameters;
+
+public class DisplayParameter
+{
+
+    private final  boolean zMapDisplay;
+    private final boolean extractedStackDisplay;
+    private final boolean elevationMapDisplay;
+    private final boolean projectionDisplay;
+    private final int delta;
+
+    public DisplayParameter(int delta,  boolean zMapDisplay, boolean extractedStackDisplay, boolean elevationMapDisplay, boolean projectionDisplay )
+    {
+        this.delta = delta;
+        this.zMapDisplay = zMapDisplay;
+        this.extractedStackDisplay = extractedStackDisplay;
+        this.elevationMapDisplay = elevationMapDisplay;
+        this.projectionDisplay = projectionDisplay;
+    }
+
+    public boolean iszMapDisplay()
+    {
+        return zMapDisplay;
+    }
+
+    public boolean isExtractedStackDisplay()
+    {
+        return extractedStackDisplay;
+    }
+
+    public boolean isElevationMapDisplay()
+    {
+        return elevationMapDisplay;
+    }
+
+    public boolean isProjectionDisplay()
+    {
+        return projectionDisplay;
+    }
+}
diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/UserParameters.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/UserParameters.java
new file mode 100644
index 00000000..f9a48c64
--- /dev/null
+++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/UserParameters.java
@@ -0,0 +1,72 @@
+package fr.pasteur.ida.zellige.surfaceConstruction.parameters;
+
+public class UserParameters
+{
+
+    private double amplitude;
+    private double threshold;
+    private int sigmas;
+    private int delta;
+    private String projectionType;
+
+
+    public UserParameters( double amplitude, double threshold, int sigmas, int delta , String projectionType)
+    {
+        this.amplitude = amplitude;
+        this.threshold = threshold;
+        this.sigmas = sigmas;
+        this.delta = delta;
+        this.projectionType = projectionType;
+
+    }
+
+    public double getAmplitude()
+    {
+        return amplitude;
+    }
+
+    public void setAmplitude( double amplitude )
+    {
+        this.amplitude = amplitude;
+    }
+
+    public double getThreshold()
+    {
+        return threshold;
+    }
+
+    public void setThreshold( double threshold )
+    {
+        this.threshold = threshold;
+    }
+
+    public int getSigmas()
+    {
+        return sigmas;
+    }
+
+    public void setSigmas( int sigmas )
+    {
+        this.sigmas = sigmas;
+    }
+
+    public int getDelta()
+    {
+        return delta;
+    }
+
+    public void setDelta( int delta )
+    {
+        this.delta = delta;
+    }
+
+    public String getProjectionType()
+    {
+        return projectionType;
+    }
+
+    public void setProjectionType( String projectionType )
+    {
+        this.projectionType = projectionType;
+    }
+}
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/BasePixFilter.java b/src/main/java/fr/pasteur/ida/zellige/utils/BasePixFilter.java
deleted file mode 100644
index 872a4e4e..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/BasePixFilter.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-
-import net.imglib2.Cursor;
-import net.imglib2.IterableInterval;
-import net.imglib2.RandomAccess;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.algorithm.neighborhood.CenteredRectangleShape;
-import net.imglib2.algorithm.neighborhood.Neighborhood;
-import net.imglib2.algorithm.neighborhood.RectangleShape;
-import net.imglib2.algorithm.neighborhood.RectangleShape.NeighborhoodsAccessible;
-import net.imglib2.img.Img;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.view.IntervalView;
-import net.imglib2.view.Views;
-
-import static net.imglib2.util.ImgUtil.copy;
-
-
-//TODO Javadoc
-
-/**
- * @param <T> the type of the source image.
- * @author Céline Trébeau - 2020
- */
-public class BasePixFilter<T extends RealType<T> & NativeType<T>> {
-
-
-    public static <T extends RealType<T> & NativeType<T>> Img<T> run(Img<T> source) {
-        BasePixOperator<T> basePixOperator = new BasePixOperator<>( source);
-        basePixOperator.process();
-        return basePixOperator.getResult();
-    }
-
-
-    private static class BasePixOperator<T extends RealType<T> & NativeType<T>> {
-        private final Img<T> source;
-
-        private final Img<T> output;
-
-
-
-
-        /**
-         * Instantiate a new median filter that will operate on the specified
-         * source.
-         *
-         * @param source the source to operate on.
-         */
-        public BasePixOperator(final Img<T> source) {
-            this.source = source;
-            this.output = source.factory().create(source);
-            copy(source, output);
-        }
-
-        //    public void process() {
-//
-//        Img<T> temp = source.factory().create(source);//TODO may be 2 different neighbour number to reduce the iteration
-//        copy(source,temp);
-//
-//        for(int i = 0 ; i <= iter - 1; i ++)
-//        {
-//           process(temp, output, n);
-//           temp = output.copy();
-////            ImageJFunctions.show( output, "iteration "+ i );
-//            }
-//    }
-        public  void process() {
-            for (int z = 0; z < source.dimension(2); z++) {//TODO why use long ?
-                final IntervalView<T> slice = Views.hyperSlice(source, 2, z);
-                final IntervalView<T> outputSlice = Views.hyperSlice(output, 2, z);
-                processSlice(slice, outputSlice);
-
-            }
-//        System.out.println("-------------------------" );
-        }
-
-
-        private void processSlice(final RandomAccessibleInterval<T> in, final IterableInterval<T> out) {
-            final Cursor<T> cursor = out.cursor();
-            final CenteredRectangleShape shape = new CenteredRectangleShape(new int[]{1, 2}, false);
-            final CenteredRectangleShape shape2 = new CenteredRectangleShape(new int[]{2, 1}, false);
-            final NeighborhoodsAccessible<T> accessible = shape.neighborhoodsRandomAccessible(Views.extendZero(in));
-            final NeighborhoodsAccessible<T> accessible2 = shape.neighborhoodsRandomAccessible(Views.extendZero(in));
-            final RandomAccess<Neighborhood<T>> nra1 = accessible.randomAccess(in);
-            final RandomAccess<Neighborhood<T>> nra2 = accessible.randomAccess(in);
-            int count = 0;
-
-//        final int size = (int) nra.get().size();
-            // Fill buffer with median values.
-            while (cursor.hasNext()) {
-                int values = 0;
-                int values2 = 0;
-                cursor.fwd();
-                if (cursor.get().getRealFloat() != 0) {
-                    nra1.setPosition(cursor);
-                    nra2.setPosition(cursor);
-                    for (final T pixel : nra1.get()) {
-                        if (pixel.getRealFloat() > 0) {
-                            values++;
-                        }
-                    }
-                    for (final T pixel : nra2.get()) {
-                        if (pixel.getRealFloat() > 0) {
-                            values2++;
-                        }
-                    }
-
-                    if (values < 6 && values2 <6) {
-                        cursor.get().setReal(0);
-                        count++;
-                    }
-                }
-
-            }
-//        System.out.println(count + " pixels removed");
-        }
-
-
-        public Img<T> getResult() {
-            return output;
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/Filter2D.java b/src/main/java/fr/pasteur/ida/zellige/utils/Filter2D.java
deleted file mode 100644
index 0974e99f..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/Filter2D.java
+++ /dev/null
@@ -1,182 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-import ij.IJ;
-import net.imglib2.Cursor;
-import net.imglib2.IterableInterval;
-import net.imglib2.RandomAccess;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.algorithm.neighborhood.Neighborhood;
-import net.imglib2.algorithm.neighborhood.RectangleShape;
-import net.imglib2.img.Img;
-import net.imglib2.img.display.imagej.ImageJFunctions;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.view.IntervalView;
-import net.imglib2.view.Views;
-
-import java.util.Arrays;
-
-public class Filter2D<T extends RealType<T> & NativeType<T>> {
-
-
-    public static <T extends RealType<T> & NativeType<T>> Img<T> median(final Img<T> source, final int radius) {
-        Process<T> p = new Process<>(source, radius, "median");
-        p.run();
-        return p.output;
-    }
-
-    public static <T extends RealType<T> & NativeType<T>> Img<T> variance(final Img<T> source, final int radius) {
-        Process<T> p = new Process<>(source, radius, "variance");
-        p.run();
-        return p.output;
-    }
-
-    public static <T extends RealType<T> & NativeType<T>> Img<T> SD(final Img<T> source, final int radius) {
-        Process<T> p = new Process<>(source, radius, "sd");
-        p.run();
-        return p.output;
-    }
-
-    public static <T extends RealType<T> & NativeType<T>> Img<T> mean(final Img<T> source, final int radius) {
-        Process<T> p = new Process<>(source, radius, "mean");
-        p.run();
-
-        return p.output;
-    }
-
-    public static class Process<T extends RealType<T> & NativeType<T>> {
-        private final Img<T> source;
-
-        private final Img<T> output;
-
-        private final int radius;
-        private final String method;
-
-        public Process(Img<T> source, int radius, String method) {
-            this.source = source;
-            this.radius = radius;
-            this.output = source.factory().create(source.dimension(0), source.dimension(1), source.dimension(2));
-            this.method = method;
-        }
-
-        public void run() {
-            final long nz = source.dimension(2);
-            for (long z = 0; z < nz; z++) {
-                final IntervalView<T> slice = Views.hyperSlice(source, 2, z);
-                final IntervalView<T> outputSlice = Views.hyperSlice(output, 2, z);
-                ProcessSlice<T> p = new ProcessSlice<>(slice, outputSlice, radius);
-                p.run(method);
-            }ImageJFunctions.show( output.copy(), method );
-        }
-
-    }
-
-    public static class ProcessSlice<T extends RealType<T> & NativeType<T>> {
-
-        final Cursor<T> cursor;
-        final RandomAccess<Neighborhood<T>> nra;
-
-        private ProcessSlice(final RandomAccessibleInterval<T> in, final IterableInterval<T> out, int radius) {
-            cursor = out.cursor();
-            final RectangleShape shape = new RectangleShape(radius, false);
-            final RectangleShape.NeighborhoodsAccessible<T> accessible = shape.neighborhoodsRandomAccessible(Views.extendZero(in));
-            nra = accessible.randomAccess(in);
-
-
-        }
-
-        private void run(String method) {
-            final int size = (int) nra.get().size();
-            final double[] values = new double[size];
-            while (cursor.hasNext()) {
-                cursor.fwd();
-                nra.setPosition(cursor);
-                double v = 0;
-                if (method.endsWith("mean")) {
-                    v = computeMean(nra, values);
-                } else if (method.equals("median")) {
-                    v = computeMedian(nra, values);
-                } else if (method.equals("sd")) {
-                    v = computeSD(nra, values);
-                } else if (method.equals("variance")) {
-                    v = computeVariance(nra, values);
-                } else {
-                    IJ.log("This method doesn't exist, try something else");
-                }
-
-                cursor.get().setReal(v); /* Not variance but SD*/
-            }
-        }
-    }
-
-    public static <T extends RealType<T> & NativeType<T>> double
-    computeMean(RandomAccess<Neighborhood<T>> nra, double[] values) {
-        int index = 0;
-        double sum = 0;
-        for (final T pixel : nra.get()) {
-            double value = pixel.getRealDouble();
-            if(value != 0)
-            {
-                values[ index ] = value;
-                sum = sum + value;
-                index++;
-            }
-        }
-        return sum / (index);
-
-    }
-
-    public static <T extends RealType<T> & NativeType<T>> double
-    computeSD(RandomAccess<Neighborhood<T>> nra, double[] values) {
-        int index = 0;
-        double sum = 0;
-        for (final T pixel : nra.get()) {
-            double value = pixel.getRealDouble();
-            values[index] = value;
-            sum = sum + value;
-            index++;
-        }
-        double mean = sum / (index);
-        return Math.sqrt(computeVariance(values, mean));
-    }
-
-    public static <T extends RealType<T> & NativeType<T>> double
-    computeMedian(RandomAccess<Neighborhood<T>> nra, double[] values) {
-        int index = 0;
-        double sum = 0;
-        for (final T pixel : nra.get()) {
-            double value = pixel.getRealDouble();
-            values[index] = value;
-            sum = sum + value;
-            index++;
-        }
-        Arrays.sort(values, 0, index);
-        return values[(index - 1) / 2];
-    }
-
-    public static <T extends RealType<T> & NativeType<T>> double
-    computeVariance(RandomAccess<Neighborhood<T>> nra, double[] values) {
-        int index = 0;
-        double sum = 0;
-        for (final T pixel : nra.get()) {
-            double value = pixel.getRealDouble();
-            values[index] = value;
-            sum = sum + value;
-            index++;
-        }
-        double mean = sum / (index);
-        return computeVariance(values, mean);
-    }
-
-
-    public static double computeVariance(double[] values, double mean) {
-        double variance = 0;
-        for (int i = 0; i <= values.length - 1; i++) {
-            double v = values[i] - mean;
-            double vSquare = v * v;
-            variance = variance + (vSquare);
-        }
-        return variance / values.length;
-
-    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/Histogram2D.java b/src/main/java/fr/pasteur/ida/zellige/utils/Histogram2D.java
deleted file mode 100644
index b4410140..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/Histogram2D.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-import net.imglib2.Cursor;
-import net.imglib2.RandomAccess;
-import net.imglib2.img.Img;
-import net.imglib2.img.display.imagej.ImageJFunctions;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-
-public class Histogram2D < T extends RealType< T > & NativeType< T >>{
-
-    Img<T> img1,  img2;
-    int [][] histogram;
-//    int [] binNums;
-    double [] min;
-    double [] max;
-
-
-    public Histogram2D(Img<T> img1, Img <T> img2, int bin1, int bin2, boolean zero, boolean zero2) {
-        this.img1 = img1;
-        this.img2 = img2;
-      histogram = new int[bin2][bin1];
-      double min1 = Threshold.findMin(this.img1, zero).getRealDouble();
-      double min2 = Threshold.findMin(this.img2, zero2).getRealDouble() ;
-      min = new double[]{min1, min2};
-
-      double max1 = Threshold.findMax(this.img1).getRealDouble();
-      double max2 = Threshold.findMax(this.img2).getRealDouble();
-      max = new double[]{max1, max2};
-    }
-
-    public void process()
-    {
-        final Cursor <T> cursor1 = img1.localizingCursor();
-        final Cursor <T> cursor2 = img2.cursor();
-        double binWidth1 = (max[0] - min[0])/ histogram[0].length ;
-        double binWidth2 = (max[1] - min[1])/ histogram.length ;
-        while (cursor1.hasNext())
-        {
-            cursor1.fwd();
-            cursor2.fwd();
-
-            final double t1 = cursor1.get().getRealDouble();final double t2 = cursor2.get().getRealDouble();
-            if (t1 != 0 && t2!= 0) {
-
-                int index0 = (int) ((t1 - min[0]) / binWidth1);
-                int index1 = (int) ((t2 - min[1]) / binWidth2);
-                try {
-                    histogram[index1][index0]++;
-                } catch (ArrayIndexOutOfBoundsException a) {
-                    if (index0 == histogram[0].length) {
-                        index0 = histogram[0].length - 1;
-                    }
-                    if (index1 == histogram.length) {
-                        index1 = histogram.length - 1;
-                    }
-                    histogram[index1][index0]++;
-
-                }
-            }
-
-        }
-    }
-
-    public void display()
-    {
-        Img<T> hist = img1.factory().create(histogram[0].length, histogram.length);
-        RandomAccess <T> randomAccess = hist.randomAccess();
-        for(int i = 0; i <= histogram[0].length - 1; i++)
-        {
-            for (int j = 0; j <= histogram.length - 1; j++)
-            {
-               final T value = Utils.setPositionAndGet(randomAccess, i, j);
-               if (histogram[j][i] != 0)
-//                value.setReal(100);
-                value.setReal(histogram[j][i]);
-            }
-        }
-        ImageJFunctions.show(hist, "histogram");
-    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/Interpolation.java b/src/main/java/fr/pasteur/ida/zellige/utils/Interpolation.java
index 034e03af..76a1a0a6 100644
--- a/src/main/java/fr/pasteur/ida/zellige/utils/Interpolation.java
+++ b/src/main/java/fr/pasteur/ida/zellige/utils/Interpolation.java
@@ -2,200 +2,226 @@ package fr.pasteur.ida.zellige.utils;
 
 import net.imglib2.Cursor;
 import net.imglib2.RandomAccess;
+import net.imglib2.RandomAccessibleInterval;
 import net.imglib2.img.Img;
+import net.imglib2.img.ImgFactory;
+import net.imglib2.img.array.ArrayImgFactory;
 import net.imglib2.img.display.imagej.ImageJFunctions;
 import net.imglib2.type.numeric.integer.UnsignedShortType;
+import net.imglib2.util.ImgUtil;
 
 
 /**
  * @author ctrebeau
- * Methods to perform 2D linear interpolation on a 2D {@link Double } array.
+ * Methods to perform 2D linear interpolation on a 2D {@link Img<UnsignedShortType> }.
  */
 public class Interpolation
 {
 
-    /**
-     * Determines the slope of the linear equation y = ax + b given 2 points P1(x1, y1) and P2 (x2, y2).
-     *
-     * @param x1 - x coordinates for the first point.
-     * @param x2 - x coordinates for the second point.
-     * @param z1 - z coordinates for the first point.
-     * @param z2 - z coordinates for the second point.
-     * @return the slope of the linear equation y = ax + b.
-     */
-    private static double getA( int x1, int x2, double z1, double z2 )
+    public static Img<UnsignedShortType> run( RandomAccessibleInterval< UnsignedShortType > input )
     {
-        return ( z2 - z1 ) / ( double ) ( x2 - x1 );
+        InterpolationOperator operator = new InterpolationOperator( input );
+        ImageJFunctions.show( operator.getOutput() );
+        return operator.getOutput();
     }
 
+    public static class InterpolationOperator
+    {
+        private final RandomAccessibleInterval< UnsignedShortType > input;
+        private  Img < UnsignedShortType > output;
 
 
-    /**
-     * Determines the constant b of the linear equation y = ax + b given one point P1(x1, y1) and the slope a.
-     *
-     * @param a  - the slope a of the linear equation y = ax + b.
-     * @param x1 - x coordinates for the first point.
-     * @param z1 - z coordinates for the first point.
-     * @return the b constant of the linear equation y = ax + b.
-     */
-    private static double getB( double a, int x1, double z1 )
-    {
-        return z1 - ( a * x1 );
-    }
+        public InterpolationOperator( RandomAccessibleInterval< UnsignedShortType > input )
+        {
+            this.input = input;
+            execute();
+        }
 
+        /**
+         * Returns an interpolated version of the specified image.
+         * The interpolation is the mean of the interpolated image in both dimensions dimension.
+         */
+        private void execute()
+        {
+            ImageJFunctions.show( input, "zMap" );
+            Img< UnsignedShortType > interpolated0 = execute( input, 0 );
+        ImageJFunctions.show( interpolated0, "interpolated 0" );
+            Img< UnsignedShortType > interpolated1 = execute( input, 1 );
+        ImageJFunctions.show( interpolated1, "interpolated 1" );
+            Cursor< UnsignedShortType > cursor0 = interpolated0.cursor();
+            Cursor< UnsignedShortType > cursor1 = interpolated1.cursor();
+
+            while ( cursor0.hasNext() )
+            {
+                cursor0.fwd();
+                cursor1.fwd();
+                int type0 = cursor0.get().getInteger();
+                int type1 = cursor1.get().getInteger();
+                if ( type0 != 0 )
+                {
+                    if ( type1 != 0 )
+                    {
+                        cursor0.get().set( ( type0 + type1 ) / 2 );
+                    }
+                }
+                else if ( type1 != 0 )
+                {
+                    cursor0.get().set( cursor1.get() );
+                }
+            }
+            this.output = interpolated0;
+        }
 
-    /**
-     * Determines the unknown z coordinate of a point P given its x coordinate,
-     * the slope and the constant of the linear equation y = ax + b.
-     *
-     * @param a - the slope a of the linear equation y = ax + b.
-     * @param b - the b constant of the linear equation y = ax + b.
-     * @param x - the x coordinate of a point with unknown z coordinate.
-     * @return - the z coordinate corresponding to the x coordinate.
-     */
-    private static int executeInt( double a, double b, int x )
-    {
-        return ( int ) Math.round( a * x + b );
-    }
+        /**
+         * Determines the slope of the linear equation y = ax + b given 2 points P1(x1, y1) and P2 (x2, y2).
+         *
+         * @param x1 - x coordinates for the first point.
+         * @param x2 - x coordinates for the second point.
+         * @param z1 - z coordinates for the first point.
+         * @param z2 - z coordinates for the second point.
+         * @return the slope of the linear equation y = ax + b.
+         */
+        private double getA( int x1, int x2, double z1, double z2 )
+        {
+            return ( z2 - z1 ) / ( double ) ( x2 - x1 );
+        }
 
+        /**
+         * Determines the constant b of the linear equation y = ax + b given one point P1(x1, y1) and the slope a.
+         *
+         * @param a  - the slope a of the linear equation y = ax + b.
+         * @param x1 - x coordinates for the first point.
+         * @param z1 - z coordinates for the first point.
+         * @return the b constant of the linear equation y = ax + b.
+         */
+        private double getB( double a, int x1, double z1 )
+        {
+            return z1 - ( a * x1 );
+        }
 
 
-    /**
-     * Determines the unknown z coordinate of a point P using the linear equation y = ax + b,
-     * given its x coordinate and  2 points P1(x1, y1) and P2 (x2, y2).
-     *
-     * @param x1 - x coordinates for the first point.
-     * @param x2 - x coordinates for the second point.
-     * @param z1 - z coordinates for the first point.
-     * @param z2 - z coordinates for the second point.
-     * @param x  - the x coordinate of a point with unknown z coordinate.
-     * @return * @return - the z coordinate corresponding to the x coordinate.
-     */
-    private static int executeInt( int x1, int x2, double z1, double z2, int x )
-    {
-        double a = getA( x1, x2, z1, z2 );
-        double b = getB( a, x1, z1 );
-        return executeInt( a, b, x );
-    }
+        /**
+         * Determines the unknown z coordinate of a point P given its x coordinate,
+         * the slope and the constant of the linear equation y = ax + b.
+         *
+         * @param a - the slope a of the linear equation y = ax + b.
+         * @param b - the b constant of the linear equation y = ax + b.
+         * @param x - the x coordinate of a point with unknown z coordinate.
+         * @return - the z coordinate corresponding to the x coordinate.
+         */
+        private int executeInt( double a, double b, int x )
+        {
+            return ( int ) Math.round( a * x + b );
+        }
 
 
-    /**
-     * Returns an interpolated version of the specified image in the specified dimension.
-     *
-     * @param zMap      the image to interpolate.
-     * @param dimension the dimension of the interpolation
-     * @return the interpolated image in the specified dimension
-     */
-    private static Img< UnsignedShortType > execute( Img< UnsignedShortType > zMap, int dimension )
-    {
-        Img< UnsignedShortType > interpolated = zMap.copy();
-        RandomAccess< UnsignedShortType > interpolatedAccess = interpolated.randomAccess();
-        RandomAccess< UnsignedShortType > zMapAccess = zMap.randomAccess();
-        int secondDimension = Math.abs( dimension - 1 );
-        int indexMax = ( int ) zMap.dimension( secondDimension ) - 1;
+        /**
+         * Determines the unknown z coordinate of a point P using the linear equation y = ax + b,
+         * given its x coordinate and  2 points P1(x1, y1) and P2 (x2, y2).
+         *
+         * @param x1 - x coordinates for the first point.
+         * @param x2 - x coordinates for the second point.
+         * @param z1 - z coordinates for the first point.
+         * @param z2 - z coordinates for the second point.
+         * @param x  - the x coordinate of a point with unknown z coordinate.
+         * @return * @return - the z coordinate corresponding to the x coordinate.
+         */
+        private int executeInt( int x1, int x2, double z1, double z2, int x )
+        {
+            double a = getA( x1, x2, z1, z2 );
+            double b = getB( a, x1, z1 );
+            return executeInt( a, b, x );
+        }
 
-        for ( int u = 0; u <= zMap.dimension( dimension ) - 1; u++ )
+        /**
+         * Returns an interpolated version of the specified image in the specified dimension.
+         *
+         * @param input      the image to interpolate.
+         * @param dimension the dimension of the interpolation
+         * @return the interpolated image in the specified dimension
+         */
+        private  Img< UnsignedShortType > execute( RandomAccessibleInterval< UnsignedShortType > input, int dimension )
         {
-            zMapAccess.setPosition( u, dimension );
-            interpolatedAccess.setPosition( u, dimension );
-            int X1;
-            int X2;
-            for ( int v = 0; v <= zMap.dimension( secondDimension ) - 1; v++ )
+            ImgFactory<UnsignedShortType> factory = new ArrayImgFactory<>(new UnsignedShortType());
+            Img< UnsignedShortType > interpolated =  factory.create( input );
+            ImgUtil.copy( input, interpolated );
+            RandomAccess< UnsignedShortType > interpolatedAccess = interpolated.randomAccess();
+            RandomAccess< UnsignedShortType > zMapAccess = input.randomAccess();
+            int secondDimension = Math.abs( dimension - 1 );
+            int indexMax = ( int ) input.dimension( secondDimension ) - 1;
+            for ( int u = 0; u <= input.dimension( dimension ) - 1; u++ )
             {
+                zMapAccess.setPosition( u, dimension );
+                interpolatedAccess.setPosition( u, dimension );
+                int X1;
+                int X2;
+                for ( int v = 0; v <= input.dimension( secondDimension ) - 1; v++ )
+                {
 
-                zMapAccess.setPosition( v, secondDimension );
+                    zMapAccess.setPosition( v, secondDimension );
 
-                interpolatedAccess.setPosition( v, secondDimension );
-                if ( zMapAccess.get().getInteger() == 0 )// there no value at this position
-                {
-                    X1 = v - 1;// the previous index.
-                    if ( X1 >= 0 )
+                    interpolatedAccess.setPosition( v, secondDimension );
+                    if ( zMapAccess.get().getInteger() == 0 )// there no value at this position
                     {
-                        zMapAccess.setPosition( X1, secondDimension );
-                        int Y1 = zMapAccess.get().copy().getInteger();
-                        if ( Y1 != 0 )
+                        X1 = v - 1;// the previous index.
+                        if ( X1 >= 0 )
                         {
-                            X2 = searchX2( zMapAccess, v, indexMax, secondDimension );
-                            if ( X2 < indexMax && X2 - X1 <= 250 ) //an interpolation can only be done for a distance of less or equals to 10 pixels.
+                            zMapAccess.setPosition( X1, secondDimension );
+                            int Y1 = zMapAccess.get().copy().getInteger();
+                            if ( Y1 != 0 )
                             {
-                                zMapAccess.setPosition( X2, secondDimension );
-                                int Y2 = zMapAccess.get().copy().getInteger();
-
-                                for ( int i = v; i <= X2; i++ )// interpolation between the interval [X1, X2].
+                                X2 = searchX2( zMapAccess, v, indexMax, secondDimension );
+                                if ( X2 < indexMax && X2 - X1 <= 250 ) //an interpolation can only be done for a distance of less or equals to 10 pixels.
                                 {
-                                    int result = executeInt( X1, X2, Y1, Y2, i );
-                                    interpolatedAccess.setPosition( i, secondDimension );
-                                    interpolatedAccess.get().set( result );
+                                    zMapAccess.setPosition( X2, secondDimension );
+                                    int Y2 = zMapAccess.get().copy().getInteger();
+
+                                    for ( int i = v; i <= X2; i++ )// interpolation between the interval [X1, X2].
+                                    {
+                                        int result = executeInt( X1, X2, Y1, Y2, i );
+                                        interpolatedAccess.setPosition( i, secondDimension );
+                                        interpolatedAccess.get().set( result );
+                                    }
                                 }
-                            }
 
-                            v = X2;// we don't need to search in the interval [X1, X2].
+                                v = X2;// we don't need to search in the interval [X1, X2].
+                            }
                         }
                     }
                 }
             }
+            return interpolated;
         }
-        return interpolated;
-    }
 
-    /**
-     * Returns an interpolated version of the specified image.
-     * The interpolation is the mean of the interpolated image in both dimensions dimension.
-     *
-     * @param zMap the image to interpolate
-     * @return the interpolated resulting image
-     */
-    public static Img< UnsignedShortType > execute( Img< UnsignedShortType > zMap )
-    {
-        ImageJFunctions.show( zMap, "zMap" );
-        Img< UnsignedShortType > interpolated0 = execute( zMap, 0 );
-//        ImageJFunctions.show( interpolated0, "interpolated 0" );
-        Img< UnsignedShortType > interpolated1 = execute( zMap, 1 );
-//        ImageJFunctions.show( interpolated1, "interpolated 1" );
-        Cursor< UnsignedShortType > cursor0 = interpolated0.cursor();
-        Cursor< UnsignedShortType > cursor1 = interpolated1.cursor();
-
-        while ( cursor0.hasNext() )
+
+        /**
+         * This method returns the first position  where the pixel value is different from 0 or the maximum index otherwise.
+         *
+         * @param randomAccess the {@link RandomAccess} of the image to interpolate.
+         * @param x            the starting index.
+         * @param max          the maximum index value.
+         * @param dim          - the dimension to search in.
+         * @return the index at which there is a value > 0 or the maximum index value otherwise.
+         */
+        private int searchX2( RandomAccess< UnsignedShortType > randomAccess, int x, int max, int dim )
         {
-            cursor0.fwd();
-            cursor1.fwd();
-            int type0 = cursor0.get().getInteger();
-            int type1 = cursor1.get().getInteger();
-            if ( type0 != 0 )
+            while ( x + 1 <= max )
             {
-                if ( type1 != 0 )
+                randomAccess.setPosition( x + 1, dim );
+                if ( randomAccess.get().copy().getInteger() != 0 )
                 {
-                    cursor0.get().set( ( type0 + type1 ) / 2 );
+                    return x + 1;
                 }
+                x++;
             }
-            else if ( type1 != 0 )
-            {
-                cursor0.get().set( cursor1.get() );
-            }
+            return max;
         }
-        return interpolated0;
-    }
 
-    /**
-     * This method returns the first position  where the pixel value is different from 0 or the maximum index otherwise.
-     *
-     * @param randomAccess the {@link RandomAccess} of the image to interpolate.
-     * @param x            the starting index.
-     * @param max          the maximum index value.
-     * @param dim          - the dimension to search in.
-     * @return the index at which there is a value > 0 or the maximum index value otherwise.
-     */
-    private static int searchX2( RandomAccess< UnsignedShortType > randomAccess, int x, int max, int dim )
-    {
-        while ( x + 1 <= max )
+        public Img< UnsignedShortType > getOutput()
         {
-            randomAccess.setPosition( x + 1, dim );
-            if ( randomAccess.get().copy().getInteger() != 0 )
-            {
-                return x + 1;
-            }
-            x++;
+            return output;
         }
-        return max;
     }
+
+
 }
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/IsolatedPixFilter.java b/src/main/java/fr/pasteur/ida/zellige/utils/IsolatedPixFilter.java
deleted file mode 100644
index 74507ba3..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/IsolatedPixFilter.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-
-import net.imglib2.Cursor;
-import net.imglib2.IterableInterval;
-import net.imglib2.RandomAccess;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.algorithm.neighborhood.Neighborhood;
-import net.imglib2.algorithm.neighborhood.RectangleShape;
-import net.imglib2.algorithm.neighborhood.RectangleShape.NeighborhoodsAccessible;
-import net.imglib2.img.Img;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.view.IntervalView;
-import net.imglib2.view.Views;
-
-import static net.imglib2.util.ImgUtil.copy;
-
-
-//TODO Javadoc
-/**
- *
- * @author Céline Trébeau - 2020
- */
-
-public class IsolatedPixFilter {
-
-    public static <T extends RealType<T> & NativeType<T>>Img<T> run(final Img<T> source, int radius, int iter, int n){
-        IsolatedPixOperator <T> isolatedPixOperator = new IsolatedPixOperator<>(source,radius, iter, n);
-        isolatedPixOperator.process();
-        return isolatedPixOperator.getResult();
-
-    }
-
-    private static class IsolatedPixOperator<T extends RealType<T> & NativeType<T>> {
-
-        private final Img<T> source;
-
-        private final Img<T> output;
-
-        private final int iter;
-
-        private final int radius;
-
-        private final int n;
-
-
-        /**
-         * Instantiate a new median filter that will operate on the specified
-         * source.
-         *
-         * @param source the source to operate on.
-         */
-        public IsolatedPixOperator(final Img<T> source,int  radius, int iter, int n) {
-            this.source = source;
-            this.output = source.copy();
-            this.radius = radius;
-            this.iter = iter;
-            this.n = n;
-
-        }
-
-        public void process() {
-
-            Img<T> temp = source.factory().create(source);//TODO may be 2 different neighbour number to reduce the iteration
-            copy(source, temp);
-
-            for (int i = 0; i <= iter - 1; i++) {
-                process(temp, output,radius, n);
-                temp = output.copy();
-//            ImageJFunctions.show( output, "iteration "+ i );
-            }
-        }
-
-        public void process(Img<T> source, Img<T> output,int radius,  int n) {
-            for (long z = 0; z < source.dimension(2); z++) {//TODO why use long ?
-                final IntervalView<T> slice = Views.hyperSlice(source, 2, z);
-                final IntervalView<T> outputSlice = Views.hyperSlice(output, 2, z);
-                processSlice(slice, outputSlice, radius, n);
-
-            }
-//        System.out.println("-------------------------" );
-        }
-
-
-        private void processSlice(final RandomAccessibleInterval<T> in, final IterableInterval<T> out,int radius,  int n) {
-            final Cursor<T> cursor = out.cursor();
-            final RectangleShape shape = new RectangleShape(radius, true);
-            final NeighborhoodsAccessible<T> accessible = shape.neighborhoodsRandomAccessible(Views.extendZero(in));
-            final RandomAccess<Neighborhood<T>> nra = accessible.randomAccess(in);
-            int count = 0;
-            while (cursor.hasNext()) {
-                int values = 0;
-                cursor.fwd();
-                if (cursor.get().getRealFloat() != 0)
-                {
-                    nra.setPosition(cursor);
-                    for (final T pixel : nra.get()) {
-                        if (pixel.getRealFloat() > 0) {
-                            values++;
-                        }
-                    }
-                    if (values < n) {
-                        cursor.get().setReal(0);
-                        count++;
-                    }
-                }
-            }
-//        System.out.println(count + " pixels removed");
-        }
-
-
-        public Img<T> getResult() {
-            return output;
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/LocalExtremaDetection.java b/src/main/java/fr/pasteur/ida/zellige/utils/LocalExtremaDetection.java
new file mode 100644
index 00000000..7bd2c3d0
--- /dev/null
+++ b/src/main/java/fr/pasteur/ida/zellige/utils/LocalExtremaDetection.java
@@ -0,0 +1,154 @@
+package fr.pasteur.ida.zellige.utils;
+
+import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
+import net.imglib2.RandomAccess;
+import net.imglib2.RandomAccessibleInterval;
+import net.imglib2.img.Img;
+import net.imglib2.img.ImgFactory;
+import net.imglib2.type.NativeType;
+import net.imglib2.type.numeric.RealType;
+import net.imglib2.view.IntervalView;
+import net.imglib2.view.Views;
+
+public class LocalExtremaDetection
+{
+
+
+    public static < T extends RealType< T > & NativeType< T > > Img< T > findMinima( RandomAccessibleInterval< T > input,
+                                                                                     ImgFactory< T > factory )
+    {
+        Img< T > minima = factory.create( input.dimension( 0 ), input.dimension( 1 ), input.dimension( 2 ) );
+        new LocalExtremaDetectionOperator<>( input, factory, minima, "min" );
+        return minima;
+    }
+
+
+    public static < T extends RealType< T > & NativeType< T > > Img< T > findMaxima( RandomAccessibleInterval< T > input,
+                                                                                     ImgFactory< T > factory )
+    {
+        Img< T > maxima = factory.create( input.dimension( 0 ), input.dimension( 1 ), input.dimension( 2 ) );
+        new LocalExtremaDetectionOperator<>( input, factory, maxima, "max" );
+        return maxima;
+    }
+
+    private static class LocalExtremaDetectionOperator< T extends RealType< T > & NativeType< T > >
+    {
+
+        private final RandomAccessibleInterval< T > input;
+        private final ImgFactory< T > factory;
+        private final RandomAccessibleInterval< T > output;
+        private final String type;
+
+        public LocalExtremaDetectionOperator( RandomAccessibleInterval< T > input, ImgFactory< T > factory,
+                                              RandomAccessibleInterval< T > output, String type )
+        {
+            this.input = input;
+            this.factory = factory;
+            this.output = output;
+            this.type = type;
+            findExtrema();
+        }
+
+        /**
+         * Finds all the local extrema of an input stack image,
+         * according to given local and global thresholds by first using a gaussian blur.
+         * The local maximums are stored in a 2D {@link Pixels} array.
+         */
+        private void
+        findExtrema()
+        {
+            // For each individual orthogonal XZ sections.*/
+            for ( int x = 0; x <= input.dimension( 0 ) - 1; x++ )// iteration on dimension X
+            {
+                try
+                {
+                    // The YZ section.
+                    IntervalView< T > intervalView = Views.hyperSlice( this.input, 0, x );
+                    // Each maximum found is stored in double Pixel array .
+                    getExtrema( intervalView, x );
+                }
+                catch ( Exception e )
+                {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+
+        /**
+         * Finds all the local maximums of an 2D image,
+         * according to given local and global thresholds by first using a gaussian blur and then a partial derivative
+         * The local maximums are stored in a 2D {@link Pixels} array.
+         *
+         * @param YZProjection - An orthogonal section (2 dimensions).
+         * @param x            - the index of the orthogonal section AKA the stack index in dimension X.
+         */
+        private void
+        getExtrema( RandomAccessibleInterval< T > YZProjection, int x )
+        {
+            // Output for partial derivative.
+            // Addition of one supplementary line, in case the last slice contains some local maximums
+            RandomAccessibleInterval< T > partialDerivative = factory.create( YZProjection.dimension( 0 ) + 1,
+                    YZProjection.dimension( 1 ) + 1 );
+            // Partial derivative computation */
+            Utils.derivative( YZProjection, partialDerivative );
+            getExtrema( partialDerivative, YZProjection, x );
+        }
+
+
+        /**
+         * @param partialDerivative the x-positioned partial derivative section of the input image as a {@link RandomAccessibleInterval}
+         * @param x                 the index in dimension X
+         */
+        private void
+        getExtrema
+        ( RandomAccessibleInterval< T > partialDerivative, RandomAccessibleInterval< T > original, int x )
+        {
+            RandomAccess< T > derivativeAccess = partialDerivative.randomAccess();
+            RandomAccess< T > maxAccess = output.randomAccess();
+            RandomAccess< T > oriAccess = original.randomAccess();
+
+            for ( int y = 0; y <= output.dimension( 1 ) - 1; y++ )
+            {
+                derivativeAccess.setPosition( y, 0 );
+                for ( int z = 0; z <= output.dimension( 2 ) - 1; z++ )
+                {
+                    if ( isALocalExtrema( derivativeAccess, z ) )
+                    {
+                        Utils.setPosition( oriAccess, y, z );
+                        Utils.setPosition( maxAccess, x, y, z );
+                        maxAccess.get().set( oriAccess.get() );
+                    }
+                }
+            }
+        }
+
+
+        /**
+         * Method to find if a pixel of a given stack is a local maximum.
+         * <p>
+         * (X or Y for respectively XZ sections and YZ sections).
+         *
+         * @param derivative - the first {@link RandomAccess} for the partial derivative image
+         *                   set at index v for dimension 0.
+         * @param z          - the index of the Z dimension
+         * @return - true if the position (v, z) is a local maximum false otherwise.
+         */
+        private boolean isALocalExtrema( RandomAccess< T > derivative, int z ) //throws Exception
+        {
+            derivative.setPosition( z, 1 );
+            final double tZero = derivative.get().getRealDouble();
+            derivative.setPosition( ( z + 1 ), 1 );
+            final double tOne = derivative.get().getRealDouble();
+            if ( type.equals( "max" ) )
+            {
+                return ( tZero >= 0 && tOne < 0 );
+            }
+            else
+            {
+                return ( tZero < 0 && tOne >= 0 );
+            }
+        }
+
+    }
+}
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/LocalMaximumDetection.java b/src/main/java/fr/pasteur/ida/zellige/utils/LocalMaximumDetection.java
deleted file mode 100644
index b40c774a..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/LocalMaximumDetection.java
+++ /dev/null
@@ -1,174 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
-import net.imglib2.RandomAccess;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.img.Img;
-import net.imglib2.img.ImgFactory;
-import net.imglib2.img.display.imagej.ImageJFunctions;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.view.IntervalView;
-import net.imglib2.view.Views;
-
-
-/**
- * @author ctrebeau
- * This class is used to select local maximums of a stack image  (3 dimensions) by using the static method
- * findMaximums().
- * First a gaussian convolution (anisotropic ) is performed then for each orthogonal section (XZ section)
- * the local maximums are found by the determination of the partial derivative in the section first dimension
- * AKA dimension Y.
- */
-
-public class LocalMaximumDetection
-{
-
-    /**
-     * Finds all the local maximums of an input stack image,
-     * according to given local and global thresholds by first using a gaussian blur.
-     * The local maximums are stored in a 2D {@link Pixels} array.
-     *
-     * @param zStack - the z-stack to analysed.
-     * @param <T>    - the type of the z-stack.
-     */
-
-
-    public static < T extends RealType< T > & NativeType< T > > Img< T >
-    findMaximums( RandomAccessibleInterval< T > zStack, ImgFactory< T > factory )
-    {
-//        Img< T > maximums = factory.create( zStack );
-        Img< T > maximums = factory.create( zStack.dimension( 0 ), zStack.dimension( 1 ), zStack.dimension( 2 ) );
-
-        // For each individual orthogonal XZ sections.*/
-        for ( int x = 0; x <= zStack.dimension( 0 ) - 1; x++ )// iteration on dimension X
-        {
-            try
-            {
-                // The YZ section.
-                IntervalView< T > intervalView = Views.hyperSlice( zStack, 0, x );
-                // Each maximum found is stored in double Pixel array .
-                findListOfMaximums( intervalView, factory, x, maximums );
-            }
-            catch ( Exception e )
-            {
-                e.printStackTrace();
-            }
-        }
-        return maximums;
-    }
-
-
-    /**
-     * Finds all the local maximums of an 2D image,
-     * according to given local and global thresholds by first using a gaussian blur and then a partial derivative
-     * The local maximums are stored in a 2D {@link Pixels} array.
-     *
-     * @param YZProjection - An orthogonal section (2 dimensions).
-     * @param x            - the index of the orthogonal section AKA the stack index in dimension X.
-     * @param <T>          - the YZProjection type.
-     */
-    private static < T extends RealType< T > & NativeType< T > > void
-    findListOfMaximums( RandomAccessibleInterval< T > YZProjection, ImgFactory< T > factory, int x,
-                        RandomAccessibleInterval< T > maximums )
-    {
-
-        // Output for partial derivative.
-        // Addition of one supplementary line, in case the last slice contains some local maximums
-        RandomAccessibleInterval< T > partialDerivative = factory.create( YZProjection.dimension( 0 ) + 1,
-                YZProjection.dimension( 1 ) + 1 );
-        // Partial derivative computation */
-        Utils.derivative( YZProjection, partialDerivative );
-        getListOfLocalMaximum( maximums, partialDerivative,YZProjection, x );
-    }
-
-
-    /**
-     * @param max               the output image containing the local maximums as a {@link RandomAccessibleInterval}
-     * @param partialDerivative the x-positioned partial derivative section of the input image as a {@link RandomAccessibleInterval}
-     * @param x                 the index in dimension X
-     * @param <T>               the type of both {@link RandomAccessibleInterval}
-     */
-    private static < T extends RealType< T > & NativeType< T > > void
-    getListOfLocalMaximum
-    ( RandomAccessibleInterval< T > max,
-      RandomAccessibleInterval< T > partialDerivative,
-      int x
-    )
-    {
-        RandomAccess< T > derivativeAccess = partialDerivative.randomAccess();
-        RandomAccess< T > maxAccess = max.randomAccess();
-
-        for ( int y = 0; y <= max.dimension( 1 ) - 1; y++ )
-        {
-            derivativeAccess.setPosition( y, 0 );
-            for ( int z = 0; z <= max.dimension( 2 ) - 1; z++ )
-            {
-                if ( isALocalMaximum( derivativeAccess, z ) )
-                {
-                    Utils.setPosition( maxAccess, x, y, z );
-                    maxAccess.get().setOne();
-                }
-            }
-        }
-    }
-
-    private static < T extends RealType< T > & NativeType< T > > void
-    getListOfLocalMaximum
-            ( RandomAccessibleInterval< T > notMax,
-              RandomAccessibleInterval< T > partialDerivative,
-              RandomAccessibleInterval <T> original,
-              int x
-            )
-    {
-        RandomAccess< T > derivativeAccess = partialDerivative.randomAccess();
-        RandomAccess< T > maxAccess = notMax.randomAccess();
-        RandomAccess< T > oriAccess = original.randomAccess();
-
-        for ( int y = 0; y <= notMax.dimension( 1 ) - 1; y++ )
-        {
-            derivativeAccess.setPosition( y, 0 );
-            for ( int z = 0; z <= notMax.dimension( 2 ) - 1; z++ )
-            {
-                if ( isALocalMaximum( derivativeAccess, z ) )
-                {
-                    Utils.setPosition( oriAccess, y, z );
-                    Utils.setPosition( maxAccess, x, y, z );
-                    maxAccess.get().set( oriAccess.get() );
-//                    maxAccess.get().setOne();
-                }
-            }
-        }
-    }
-
-    /**
-     * Method to find if a pixel of a given stack is a local maximum.
-     * <p>
-     * (X or Y for respectively XZ sections and YZ sections).
-     *
-     * @param derivative - the first {@link RandomAccess} for the partial derivative image
-     *                   set at index v for dimension 0.
-     * @param z          - the index of the Z dimension
-     * @param <T>        - the type of the image
-     * @return - true if the position (v, z) is a local maximum false otherwise.
-     */
-    private static < T extends RealType< T > & NativeType< T > > boolean isALocalMaximum
-    ( RandomAccess< T > derivative, int z )
-    {
-        derivative.setPosition( z, 1 );
-        final double tZero = derivative.get().getRealDouble();
-        derivative.setPosition( ( z + 1 ), 1 );
-        final double tOne = derivative.get().getRealDouble();
-        return ( tZero >= 0 && tOne < 0 );
-    }
-    private static < T extends RealType< T > & NativeType< T > > boolean isALocalMinimum
-            ( RandomAccess< T > derivative, int z )
-    {
-        derivative.setPosition( z, 1 );
-        final double tZero = derivative.get().getRealDouble();
-        derivative.setPosition( ( z + 1 ), 1 );
-        final double tOne = derivative.get().getRealDouble();
-        return ( tZero <0  && tOne >= 0 );
-    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/LocalMinimumDetection.java b/src/main/java/fr/pasteur/ida/zellige/utils/LocalMinimumDetection.java
deleted file mode 100644
index f54f2647..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/LocalMinimumDetection.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-
-import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels;
-import net.imglib2.RandomAccess;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.img.Img;
-import net.imglib2.img.ImgFactory;
-import net.imglib2.img.display.imagej.ImageJFunctions;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.util.ImgUtil;
-import net.imglib2.view.IntervalView;
-import net.imglib2.view.Views;
-
-
-/**
- * @author ctrebeau
- * This class is used to select local maximums of a stack image  (3 dimensions) by using the static method
- * findMaximums().
- * First a gaussian convolution (anisotropic ) is performed then for each orthogonal section (XZ section)
- * the local maximums are found by the determination of the partial derivative in the section first dimension
- * AKA dimension Y.
- */
-
-public class LocalMinimumDetection
-{
-
-    /**
-     * Finds all the local maximums of an input stack image,
-     * according to given local and global thresholds by first using a gaussian blur.
-     * The local maximums are stored in a 2D {@link Pixels} array.
-     *
-     * @param zStack - the z-stack to analysed.
-     * @param <T>    - the type of the z-stack.
-     */
-
-
-    public static < T extends RealType< T > & NativeType< T > > Img< T >
-    findMinimums( RandomAccessibleInterval< T > zStack, ImgFactory< T > factory )
-    {
-        Img< T > minimums = factory.create( zStack.dimension( 0 ), zStack.dimension( 1 ), zStack.dimension( 2 ) );
-//        ImgUtil.copy( zStack, minimums );
-        // For each individual orthogonal XZ sections.*/
-        for ( int x = 0; x <= zStack.dimension( 0 ) - 1; x++ )// iteration on dimension X
-        {
-            try
-            {
-                // The YZ section.
-                IntervalView< T > intervalView = Views.hyperSlice( zStack, 0, x );
-//                if (x == 15)
-//                {
-//                    ImageJFunctions.show(intervalView);
-//                }
-                // Each maximum found is stored in double Pixel array .
-                findListOfMinimum( intervalView, factory, x, minimums );
-            }
-            catch ( Exception e )
-            {
-                e.printStackTrace();
-            }
-        }
-        return minimums;
-    }
-
-
-    /**
-     * Finds all the local maximums of an 2D image,
-     * according to given local and global thresholds by first using a gaussian blur and then a partial derivative
-     * The local maximums are stored in a 2D {@link Pixels} array.
-     *
-     * @param YZProjection - An orthogonal section (2 dimensions).
-     * @param x            - the index of the orthogonal section AKA the stack index in dimension X.
-     * @param <T>          - the YZProjection type.
-     */
-    private static < T extends RealType< T > & NativeType< T > > void
-    findListOfMinimum( RandomAccessibleInterval< T > YZProjection, ImgFactory< T > factory, int x,
-                        RandomAccessibleInterval< T > maximums )
-    {
-        // Output for partial derivative.
-        // Addition of one supplementary line, in case the last slice contains some local maximums
-        RandomAccessibleInterval< T > partialDerivative = factory.create( YZProjection.dimension( 0 ) + 1,
-                YZProjection.dimension( 1 ) + 1 );
-        // Partial derivative computation */
-        Utils.derivative( YZProjection, partialDerivative );
-//        if (x == 15)
-//        {
-//            ImageJFunctions.show(partialDerivative);
-//        }
-        getListOfLocalMinimum( maximums, partialDerivative,YZProjection, x );
-    }
-
-
-    /**
-     * @param max               the output image containing the local maximums as a {@link RandomAccessibleInterval}
-     * @param partialDerivative the x-positioned partial derivative section of the input image as a {@link RandomAccessibleInterval}
-     * @param x                 the index in dimension X
-     * @param <T>               the type of both {@link RandomAccessibleInterval}
-     */
-    private static < T extends RealType< T > & NativeType< T > > void
-    getListOfLocalMinimum
-    ( RandomAccessibleInterval< T > max,
-      RandomAccessibleInterval< T > partialDerivative,
-      int x
-    )
-    {
-        RandomAccess< T > derivativeAccess = partialDerivative.randomAccess();
-        RandomAccess< T > maxAccess = max.randomAccess();
-
-        for ( int y = 0; y <= max.dimension( 1 ) - 1; y++ )
-        {
-            derivativeAccess.setPosition( y, 0 );
-            for ( int z = 0; z <= max.dimension( 2 ) - 1; z++ )
-            {
-                if ( isALocalMinimum( derivativeAccess, z ) )
-                {
-                    Utils.setPosition( maxAccess, x, y, z );
-                    maxAccess.get().setOne();
-                }
-            }
-        }
-    }
-
-    private static < T extends RealType< T > & NativeType< T > > void
-    getListOfLocalMinimum
-            ( RandomAccessibleInterval< T > minimums,
-              RandomAccessibleInterval< T > partialDerivative,
-              RandomAccessibleInterval <T> original,
-              int x
-            )
-    {
-        RandomAccess< T > derivativeAccess = partialDerivative.randomAccess();
-        RandomAccess< T > minAccess = minimums.randomAccess();
-        RandomAccess< T > oriAccess = original.randomAccess();
-
-        for ( int y = 0; y <= minimums.dimension( 1 ) - 1; y++ )
-        {
-            derivativeAccess.setPosition( y, 0 );
-            for ( int z = 0; z <= minimums.dimension( 2 ) - 1; z++ )
-            {
-                if ( isALocalMinimum( derivativeAccess, z ) )
-                {
-                    Utils.setPosition( oriAccess, y, z );
-                    Utils.setPosition( minAccess, x, y, z );
-                    minAccess.get().set( oriAccess.get() );
-//                    maxAccess.get().setOne();
-                }
-            }
-        }
-    }
-
-    /**
-     * Method to find if a pixel of a given stack is a local maximum.
-     * <p>
-     * (X or Y for respectively XZ sections and YZ sections).
-     *
-     * @param derivative - the first {@link RandomAccess} for the partial derivative image
-     *                   set at index v for dimension 0.
-     * @param z          - the index of the Z dimension
-     * @param <T>        - the type of the image
-     * @return - true if the position (v, z) is a local maximum false otherwise.
-     */
-
-    private static < T extends RealType< T > & NativeType< T > > boolean isALocalMinimum
-            ( RandomAccess< T > derivative, int z )
-    {
-        derivative.setPosition( z, 1 );
-        final double tZero = derivative.get().getRealDouble();
-        derivative.setPosition( ( z + 1 ), 1 );
-        final double tOne = derivative.get().getRealDouble();
-        return ( tZero <0  && tOne >= 0 );
-    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/LocalOtsuTest.java b/src/main/java/fr/pasteur/ida/zellige/utils/LocalOtsuTest.java
deleted file mode 100644
index f7dfb8ae..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/LocalOtsuTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-import net.imglib2.Interval;
-import net.imglib2.algorithm.util.Grids;
-
-import java.util.List;
-
-
-
-class LocalOtsuTest
-{
-
-
-    public void grid()
-    {
-        List< Interval > intervals = Grids.collectAllContainedIntervals( new long[]{ 300, 420, 20 },
-                new int[]{ 100, 100, 30} );
-        System.out.println("youhou");
-    }
-
-    public static void main( String[] args )
-    {
-        LocalOtsuTest l = new LocalOtsuTest();
-        l.grid();
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/MaximumAmplitudeClassification.java b/src/main/java/fr/pasteur/ida/zellige/utils/MaximumAmplitudeClassification.java
index bb15d942..88314c5a 100644
--- a/src/main/java/fr/pasteur/ida/zellige/utils/MaximumAmplitudeClassification.java
+++ b/src/main/java/fr/pasteur/ida/zellige/utils/MaximumAmplitudeClassification.java
@@ -1,6 +1,5 @@
 package fr.pasteur.ida.zellige.utils;
 
-import fr.pasteur.ida.zellige.surfaceConstruction.construction.SurfacesExtraction;
 import net.imglib2.Cursor;
 import net.imglib2.Interval;
 import net.imglib2.RandomAccess;
@@ -173,9 +172,11 @@ public class MaximumAmplitudeClassification
 
         public void run()
         {
-            Img< T > maximums = LocalMaximumDetection.findMaximums( input, factory );
-            Img< T > minimums = LocalMinimumDetection.findMinimums( input, factory );
-            Img< T > amp = getAmplitude( maximums, factory, minimums );
+//            Img< T > maximums = LocalMaximumDetection.findMaximums( input, factory );
+            Img< T > maximums = LocalExtremaDetection.findMaxima( input, factory );
+//            Img< T > minimums = LocalMinimumDetection.findMinimums( input, factory );
+            Img< T > minimums = LocalExtremaDetection.findMinima( input, factory );
+                    Img< T > amp = getAmplitude( maximums, factory, minimums );
             T TMax = Threshold.getFirstMaxValue( maximums, false );
             TMax.mul( amplitudeThreshold );
             this.amplitude = Thresholder.threshold( amp.copy(), TMax, true, 2 );
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/MaximumVarianceFilter.java b/src/main/java/fr/pasteur/ida/zellige/utils/MaximumVarianceFilter.java
deleted file mode 100644
index 8aaededd..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/MaximumVarianceFilter.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-import net.imglib2.Cursor;
-import net.imglib2.img.Img;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-
-public class MaximumVarianceFilter <T extends RealType<T> & NativeType<T>>
-{
-
-    private final Img<T> variance;
-
-    private final Img<T> max;
-    private Img<T> output;
-
-    public MaximumVarianceFilter(Img <T> max, final Img<T> variance) {
-        this.max = max;
-        this.variance = variance;
-        this.output = variance.factory().create(variance.dimension(0), variance.dimension(1), variance.dimension(2));
-//        copy(max, output);
-    }
-
-    public void process() {
-
-
-        Cursor<T> varCursor = variance.cursor();
-        Cursor<T> maxCursor = max.cursor();
-        Cursor<T> outCursor = output.cursor();
-        while (varCursor.hasNext())
-        {
-            varCursor.fwd();
-            maxCursor.fwd();
-            outCursor.fwd();
-            final double var = varCursor.get().getRealDouble();
-            final double m = maxCursor.get().getRealDouble();
-            if (m!= 0 && var != 0)
-
-            {
-                outCursor.get().setReal(1);
-            }
-        }
-
-        output = IsolatedPixFilter.run(output.copy(),1,  5, 2);
-
-    }
-
-
-    public Img<T> getResult() {
-        return output;
-    }
-
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/MedianSkipZeros.java b/src/main/java/fr/pasteur/ida/zellige/utils/MedianSkipZeros.java
deleted file mode 100644
index 1c5bd8eb..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/MedianSkipZeros.java
+++ /dev/null
@@ -1,197 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.stream.Collectors;
-
-import ij.IJ;
-import ij.ImagePlus;
-import net.imagej.ImageJ;
-import net.imglib2.Cursor;
-import net.imglib2.Interval;
-import net.imglib2.RandomAccess;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.algorithm.neighborhood.Neighborhood;
-import net.imglib2.algorithm.neighborhood.RectangleShape;
-import net.imglib2.algorithm.neighborhood.RectangleShape.NeighborhoodsAccessible;
-import net.imglib2.img.Img;
-import net.imglib2.img.ImgFactory;
-import net.imglib2.img.display.imagej.ImageJFunctions;
-import net.imglib2.loops.IntervalChunks;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.util.Util;
-import net.imglib2.view.IntervalView;
-import net.imglib2.view.Views;
-
-public class MedianSkipZeros
-{
-
-    /**
-     * Apply a 3x3 median to a nD image, possibly skipping for pixel with
-     * 0-values. The computation is multithreaded.
-     *
-     * @param <T>
-     *            the pixel type of the source image.
-     * @param source
-     *            the source image.
-     * @param skipZeros
-     *            if <code>true</code>, pixels with 0-value will be skipped.
-     * @return a new image of the same pixel type that of the source.
-     */
-    public static final < T extends RealType< T > & NativeType< T > > Img< T > median( final RandomAccessibleInterval< T > source, final boolean skipZeros )
-    {
-        // Prepare output.
-        final ImgFactory< T > factory = Util.getArrayOrCellImgFactory( source, Util.getTypeFromInterval( source ) );
-        final Img< T > output = factory.create( source );
-
-        // Create the neighborhoods.
-        final RectangleShape kernel = new RectangleShape( 1, false );
-        final NeighborhoodsAccessible< T > neighborhoods = kernel.neighborhoodsRandomAccessible( Views.extendMirrorDouble( source ) );
-
-        // Divide into chunks.
-        final int numberOfChunks = Runtime.getRuntime().availableProcessors() / 2; // Only one proc
-        final List< Interval > chunks = IntervalChunks.chunkInterval( source, numberOfChunks );
-
-        // Create tasks.
-        final List< Runnable > runnables = ( skipZeros )
-                ? chunks.stream()
-                .map( chunk -> new MedianOperatorSkipZeros<>( chunk, output, source, neighborhoods ) )
-                .collect( Collectors.toList() )
-                : chunks.stream()
-                .map( chunk -> new MedianOperator<>( chunk, output, source, neighborhoods ) )
-                .collect( Collectors.toList() );
-
-        // Launch computation on several threads
-        final ExecutorService executorService = Executors.newFixedThreadPool( numberOfChunks );
-        runnables.forEach( executorService::submit );
-        executorService.shutdown();
-
-        return output;
-    }
-
-    private static final class MedianOperator< T extends RealType< T > & NativeType< T > > implements Runnable
-    {
-
-        private final Interval chunk;
-
-        private final Img< T > output;
-
-        private final RandomAccessibleInterval< T > source;
-
-        private final NeighborhoodsAccessible< T > neighborhoods;
-
-        private MedianOperator( final Interval chunk, final Img< T > output, final RandomAccessibleInterval< T > source, final NeighborhoodsAccessible< T > neighborhoods )
-        {
-            this.chunk = chunk;
-            this.output = output;
-            this.source = source;
-            this.neighborhoods = neighborhoods;
-        }
-
-        @Override
-        public void run()
-        {
-            final IntervalView< T > interval = Views.interval( source, chunk );
-
-            final Cursor< T > sourceCursor = interval.localizingCursor();
-            final RandomAccess< T > raOutput = output.randomAccess( chunk );
-            final RandomAccess< Neighborhood< T > > raNeighborhoods = neighborhoods.randomAccess( chunk );
-
-            final int size = ( int ) raNeighborhoods.get().size();
-            final double[] values = new double[ size ];
-
-            while ( sourceCursor.hasNext() )
-            {
-                sourceCursor.fwd();
-
-                raNeighborhoods.setPosition( sourceCursor );
-                int index = 0;
-                for ( final T pixel : raNeighborhoods.get() )
-                    values[ index++ ] = pixel.getRealDouble();
-
-                Arrays.sort( values, 0, index );
-                final double median = values[ ( index - 1 ) / 2 ];
-
-                raOutput.setPosition( sourceCursor );
-                raOutput.get().setReal( median );
-            }
-        }
-    }
-
-    private static final class MedianOperatorSkipZeros< T extends RealType< T > & NativeType< T > > implements Runnable
-    {
-
-        private final Interval chunk;
-
-        private final Img< T > output;
-
-        private final RandomAccessibleInterval< T > source;
-
-        private final NeighborhoodsAccessible< T > neighborhoods;
-
-        private MedianOperatorSkipZeros( final Interval chunk, final Img< T > output, final RandomAccessibleInterval< T > source, final NeighborhoodsAccessible< T > neighborhoods )
-        {
-            this.chunk = chunk;
-            this.output = output;
-            this.source = source;
-            this.neighborhoods = neighborhoods;
-        }
-
-        @Override
-        public void run()
-        {
-            final IntervalView< T > interval = Views.interval( source, chunk );
-
-            final Cursor< T > sourceCursor = interval.localizingCursor();
-            final RandomAccess< T > raOutput = output.randomAccess( chunk );
-            final RandomAccess< Neighborhood< T > > raNeighborhoods = neighborhoods.randomAccess( chunk );
-
-            final int size = ( int ) raNeighborhoods.get().size();
-            final double[] values = new double[ size ];
-
-            while ( sourceCursor.hasNext() )
-            {
-                sourceCursor.fwd();
-                if ( sourceCursor.get().getRealDouble() == 0 )
-                {
-                    raOutput.setPosition( sourceCursor );
-                    raOutput.get().set( sourceCursor.get() );
-                    continue;
-                }
-
-                raNeighborhoods.setPosition( sourceCursor );
-                int index = 0;
-                for ( final T pixel : raNeighborhoods.get() )
-                    values[ index++ ] = pixel.getRealDouble();
-
-                Arrays.sort( values, 0, index );
-                final double median = values[ ( index - 1 ) / 2 ];
-
-                raOutput.setPosition( sourceCursor );
-                raOutput.get().setReal( median );
-            }
-        }
-    }
-
-    /*
-     * DEMO
-     */
-
-    public static < T extends RealType< T > & NativeType< T > > void main( final String[] args )
-    {
-        final ImageJ ij = new ImageJ();
-        ij.launch( args );
-
-        final String imgFile = "doc/STK.tif";
-        final ImagePlus imp = IJ.openImage( imgFile );
-        imp.show();
-
-        final Img< T > wrap = ImageJFunctions.wrap( imp );
-        final Img< T > output = MedianSkipZeros.median( wrap, true );
-        ImageJFunctions.show( output, "Median skip 0" );
-
-    }
-}
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/Otsu.java b/src/main/java/fr/pasteur/ida/zellige/utils/Otsu.java
index c1032b1f..ef76fce2 100644
--- a/src/main/java/fr/pasteur/ida/zellige/utils/Otsu.java
+++ b/src/main/java/fr/pasteur/ida/zellige/utils/Otsu.java
@@ -11,9 +11,9 @@ import java.util.TreeMap;
 public class Otsu
 {
 
-    public static < T extends RealType< T > & NativeType< T > > T getThreshold( IterableInterval< T > source)
+    public static < T extends RealType< T > & NativeType< T > > T getThreshold( IterableInterval< T > source )
     {
-        OtsuOperator<T> otsuOperator = new OtsuOperator<>( source );
+        OtsuOperator< T > otsuOperator = new OtsuOperator<>( source );
         otsuOperator.process();
         T threshold = source.firstElement().createVariable();
         threshold.setReal( otsuOperator.getThreshold() );
@@ -61,8 +61,7 @@ public class Otsu
 
             for ( int i = 0; i <= n0.length - 1; i++ )
             {
-
-                output[ i ] = (double) n0[i] / ( double ) N;
+                output[ i ] = ( double ) n0[ i ] / ( double ) N;
             }
             return output;
         }
@@ -73,7 +72,7 @@ public class Otsu
             double[] output = new double[ M0.length ];
             for ( int i = 0; i <= M0.length - 1; i++ )
             {
-                output[ i ] = M0[ i ] / n0[ i ] ;
+                output[ i ] = M0[ i ] / n0[ i ];
             }
             return output;
         }
@@ -83,30 +82,30 @@ public class Otsu
             double[] output = new double[ M0.length ];
             for ( int i = 0; i <= M0.length - 1; i++ )
             {
-                output[ i ] = (N * mTot - M0[ i ]) / (N-n0[ i ]) ;
+                output[ i ] = ( N * mTot - M0[ i ] ) / ( N - n0[ i ] );
             }
             return output;
         }
 
-        public static double[] getVB( double mTot, double[] m0, double [] m1 , double [] p0, double [] p1)
+        public static double[] getVB( double mTot, double[] m0, double[] m1, double[] p0, double[] p1 )
         {
             double[] vb = new double[ m0.length ];
             for ( int i = 0; i <= m0.length - 1; i++ )
             {
-                vb[ i ] = p0[i] * Math.pow( (m0[i] - mTot), 2) +  p1[i] * Math.pow((m1[i] - mTot), 2);
+                vb[ i ] = p0[ i ] * Math.pow( ( m0[ i ] - mTot ), 2 ) + p1[ i ] * Math.pow( ( m1[ i ] - mTot ), 2 );
             }
             return vb;
         }
 
-        public static int findKMax(double [] vb)
+        public static int findKMax( double[] vb )
         {
             double max = 0;
             int k = 0;
-            for(int i = 0 ; i<= vb.length - 1; i ++)
+            for ( int i = 0; i <= vb.length - 1; i++ )
             {
-                if (vb[i] > max)
+                if ( vb[ i ] > max )
                 {
-                    max = vb[i];
+                    max = vb[ i ];
                     k = i;
                 }
             }
@@ -114,13 +113,12 @@ public class Otsu
         }
 
 
-
-        public static double[] getP1( double [] p0)
+        public static double[] getP1( double[] p0 )
         {
             double[] p1 = new double[ p0.length ];
             for ( int i = 0; i <= p0.length - 1; i++ )
             {
-                p1[ i ] = 1 - p0[i];
+                p1[ i ] = 1 - p0[ i ];
             }
             return p1;
         }
@@ -133,8 +131,8 @@ public class Otsu
             while ( cursor.hasNext() )
             {
                 cursor.fwd();
-                final double value =  cursor.get().getRealDouble();
-                Integer j = hm.get(value );
+                final double value = cursor.get().getRealDouble();
+                Integer j = hm.get( value );
                 hm.put( value, ( j == null ) ? 1 : j + 1 );
 
             }
@@ -159,22 +157,22 @@ public class Otsu
             // Setting of mean and number of pixels
 
             int N = 1;
-            for(int d = 0 ; d<= source.numDimensions() - 1; d ++)
+            for ( int d = 0; d <= source.numDimensions() - 1; d++ )
             {
-                N = N* (int) source.dimension( d );
+                N = N * ( int ) source.dimension( d );
             }
             double mTot = sum / N;
 
             // Cumulative arrays
             int[] n0 = makeCumulativeSum( histogram );
             double[] M0 = makeCumulativeWeightedSum( histogram, intensities );
-            double [] m0 = getLittleM0( M0, n0 );
-            double [] p0 = getP0( n0, N );
-            double [] m1 = getM1( N, mTot, M0, n0 );
-            double [] p1 = getP1( p0 );
-            double[] vb = getVB( mTot, m0, m1, p0, p1  );
+            double[] m0 = getLittleM0( M0, n0 );
+            double[] p0 = getP0( n0, N );
+            double[] m1 = getM1( N, mTot, M0, n0 );
+            double[] p1 = getP1( p0 );
+            double[] vb = getVB( mTot, m0, m1, p0, p1 );
             int k = findKMax( vb );
-            threshold = intensities[k];
+            threshold = intensities[ k ];
 
 
         }
@@ -184,10 +182,10 @@ public class Otsu
             return threshold;
         }
 
-        public double sum(double [] array)
+        public double sum( double[] array )
         {
             double sum = 0;
-            for (double d : array )
+            for ( double d : array )
             {
                 sum = d + sum;
             }
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/StackProjection.java b/src/main/java/fr/pasteur/ida/zellige/utils/StackProjection.java
index de605624..5128dd09 100644
--- a/src/main/java/fr/pasteur/ida/zellige/utils/StackProjection.java
+++ b/src/main/java/fr/pasteur/ida/zellige/utils/StackProjection.java
@@ -78,7 +78,7 @@ public class StackProjection
      * @param <T>
      * @return
      */
-    public static < T extends RealType< T > & NativeType< T > > Img< UnsignedShortType > getHeightMap
+    public static < T extends RealType< T > & NativeType< T > > Img< UnsignedShortType > getElevationMap
     ( RandomAccessibleInterval< T > stack, RandomAccessibleInterval< UnsignedShortType > zMap, String method, int delta )
     {
         ImgFactory< UnsignedShortType > imgFactory = new ArrayImgFactory<>( new UnsignedShortType() );
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/Threshold.java b/src/main/java/fr/pasteur/ida/zellige/utils/Threshold.java
index 81afcb9a..a4dc029d 100644
--- a/src/main/java/fr/pasteur/ida/zellige/utils/Threshold.java
+++ b/src/main/java/fr/pasteur/ida/zellige/utils/Threshold.java
@@ -116,7 +116,7 @@ public class Threshold
         // ported to ImageJ plugin by G.Landini
 
         int ih;
-        int threshold = - 1;
+        int threshold;
         int num_pixels = 0;
         double total_mean;    /* mean gray-level for the whole image */
         double bcv, term;    /* between-class variance, scaling term */
diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/VarianceFilter2D.java b/src/main/java/fr/pasteur/ida/zellige/utils/VarianceFilter2D.java
deleted file mode 100644
index bd53a0bb..00000000
--- a/src/main/java/fr/pasteur/ida/zellige/utils/VarianceFilter2D.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package fr.pasteur.ida.zellige.utils;
-
-import net.imglib2.Cursor;
-import net.imglib2.IterableInterval;
-import net.imglib2.RandomAccess;
-import net.imglib2.RandomAccessibleInterval;
-import net.imglib2.algorithm.neighborhood.Neighborhood;
-import net.imglib2.algorithm.neighborhood.RectangleShape;
-import net.imglib2.img.Img;
-import net.imglib2.type.NativeType;
-import net.imglib2.type.numeric.RealType;
-import net.imglib2.view.IntervalView;
-import net.imglib2.view.Views;
-
-public class VarianceFilter2D<T extends RealType<T> & NativeType<T>> {
-
-    private final Img<T> source;
-
-    private final Img<T> output;
-
-    private final int radius;
-
-    /**
-     * Instantiate a new variance filter that will operate on the specified
-     * source.
-     *
-     * @param source the source to operate on.
-     * @param radius determines the size of the neighborhood. In 2D or 3D, a radius
-     *               of 1 will generate a 3x3 neighborhood.
-     */
-    public VarianceFilter2D(final Img<T> source, final int radius) {
-        this.source = source;
-        this.radius = radius;
-        this.output = source.factory().create(source.dimension( 0 ), source.dimension( 1 ), source.dimension( 2 ));
-    }
-
-    public void process() {
-            final long nz = source.dimension(2);
-            for (long z = 0; z < nz; z++) {
-                final IntervalView<T> slice = Views.hyperSlice(source, 2, z);
-                final IntervalView<T> outputSlice = Views.hyperSlice(output, 2, z);
-                processSlice(slice, outputSlice);
-            }
-    }
-
-    private void processSlice(final RandomAccessibleInterval<T> in, final IterableInterval<T> out) {
-        final Cursor<T> cursor = out.cursor();
-        final RectangleShape shape = new RectangleShape(radius, false);
-        final RectangleShape.NeighborhoodsAccessible<T> accessible = shape.neighborhoodsRandomAccessible(Views.extendZero(in));
-        final RandomAccess<Neighborhood<T>> nra = accessible.randomAccess(in);
-
-        final int size = (int) nra.get().size();
-        final double[] values = new double[size];
-
-        while (cursor.hasNext()) {
-            cursor.fwd();
-            nra.setPosition(cursor);
-            double v = computeVariance(nra, values);
-            cursor.get().setReal( Math.sqrt( v ) ); /* Not variance but SD*/
-        }
-    }
-
-
-    public static < T extends RealType< T > & NativeType< T > >  double
-    computeVariance(RandomAccess<Neighborhood<T>> nra, double[] values)
-    {
-        int index = 0;
-        double sum = 0;
-        for (final T pixel : nra.get())
-        {
-            double value = pixel.getRealDouble();
-            values[index] = value;
-            sum = sum + value;
-            index++;
-        }
-        double mean = sum / ( index );
-       return computeVariance( values, mean );
-        }
-
-
-
-
-
-    public static double computeVariance(double[] values, double mean) {
-        double variance = 0;
-        for (int i = 0; i <= values.length - 1; i++) {
-            double v = values[i] - mean;
-            double vSquare = v * v;
-            variance = variance + (vSquare);
-        }
-        return variance / values.length;
-
-    }
-
-    public Img<T> getResult() {
-        return output.copy();
-    }
-
-
-}
-- 
GitLab