diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000000000000000000000000000000000..88e34589b7bd2dbc5264bb8f7118c1e2dfb3159c
--- /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 0000000000000000000000000000000000000000..ed1286ba3c280b2164817d93e514acfba090e24b
--- /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 9c0c4c3fe8c0765ec3df25a9884e4b1fffe8879b..1217020f467ce7d90a2e76a27056c09b44bac865 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 ed2a32fd47b36d1083a6653e2e3c833d44c645b9..e37a8e35963a6dfec8110fc16d49c1b07b779020 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 b4768efec9c7b1bb60c775c72a30d340e7104314..0000000000000000000000000000000000000000
--- 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 30575cb21b87348cbbfb9edc1f5a945bc3051774..0000000000000000000000000000000000000000
--- 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 32e3f46b614ef10cbd71ebb2e67619c39d837f72..0000000000000000000000000000000000000000
--- 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 ec7eb2db8b73c480f630829ab6e7a11c63defa7c..0000000000000000000000000000000000000000
--- 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 34d2a93ec9b5fe8fddb25fd1a734cab52746cf73..0000000000000000000000000000000000000000
--- 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 a6a3eccb8d252c510ba9999db858fc6a04caafc7..0000000000000000000000000000000000000000
--- 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 642d8714840c1f6c10f8f9152f6f2e989c45742a..0000000000000000000000000000000000000000
--- 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 acf9a3c164eaf884dc822a5189e5d19a42c26c76..0000000000000000000000000000000000000000
--- 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 fbcb55ca25aa185c012a915e1c764fed26036934..0000000000000000000000000000000000000000
--- 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 0c2152b73eca3a27115cc60d9ebec7efb7a58830..b1d8a7ba26d9de079fa5d2a922bb9fcc26bd26e7 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 7ef37fdf2137b4c858c92489ea36b14ec52d9c18..0000000000000000000000000000000000000000
--- 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 f909aaa44f7b9349a56fbcfd750d3aeff876f1bc..0000000000000000000000000000000000000000
--- 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 58384f1668c67f7cb5fc0c483a786377e4e18c34..0000000000000000000000000000000000000000
--- 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 c26cdcd0be19db68812e19aa709cdcfa43caeb0c..641b78de5702bf07a6fba08d26180040321420f6 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 f014ae61912712e9f1ce429887bdc6982da94899..0be1b5d25c4afe8e372632f074828b6f5cbc9675 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 df468e813fadf5af7ca6305e5147d503f4b18d4c..0000000000000000000000000000000000000000
--- 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 0000000000000000000000000000000000000000..2b573922e769630c45f3880564aa02fce662197a
--- /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 0000000000000000000000000000000000000000..3bd58de8119623e4ad034cd4a17295ae0c9cc090
--- /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 7691c3e86b9ba9d70b83c2bf3a844e38533da7aa..aa34c762171b31e780f748682c82a7d96833466b 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 e62720161e0951a3b7ee6fe2f08fd8bd731dbf0b..0000000000000000000000000000000000000000
--- 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 020be56967116bac4b3d82ce47198b5f2aa36b5d..35b57ad6fbf2238ebbd6f80d07cfad71f7474cbd 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 0000000000000000000000000000000000000000..0ab013ec3ae2e4f4b2526dd83bdb68afc13c165c
--- /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 ec5214dcde63236e53432f61ec078858fc8e3f5f..9d460f5c639350e4d0552a7f9487f018e553c614 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 db4332f6ed6612c9fbe91d4b5c26185449fe66b8..eeddbe41f8c6d65723c4691953535537e58d2670 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 1bfe8bc40680120bf0ca0ecf84f478cf503d16f2..c1c69856fc4ffbaff319ea3cb47e10b3cf8edf3f 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 05c93286a6ce162b9aab7544dbcb3a3368536304..be3f4c2906574bb0fac1b2df050b34369c97338a 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 c6f098045f624414a96eefdef2f22cb0a8de77ba..54321fb750330488b0fa68f5a2f988cd11a30b23 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 1fa11ca2cefd0c6d4625e836d85344c35649e4c1..9fe02a4d25843339ccdf4aaa82439701bdfaed4d 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 be9f4b50d684fc29ee8a30924c669ce597b5d4c1..9204b511cf3cdbfd54b4bc70a0eeda5065000278 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 0000000000000000000000000000000000000000..1f91632024362c725cdfba3dca8391f57afff9c2
--- /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 0000000000000000000000000000000000000000..5b0ad5983b06cc04ccc55cfc7424160a777cc3d3
--- /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 0000000000000000000000000000000000000000..f9a48c64817e1cb8a31776a14076d8f5596d1cfc
--- /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 872a4e4e0ef35dbbd10fe64ef9f7cd357ca358db..0000000000000000000000000000000000000000
--- 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 0974e99fbca6d94d95edf84a0c8da4c640a12b01..0000000000000000000000000000000000000000
--- 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 b4410140173d9bebe7da7ce3fa8134f105f8932f..0000000000000000000000000000000000000000
--- 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 034e03afb3d10854259420db77eb3317e1db4b77..76a1a0a6bcb10d75ee0f9d30a1abda5701cf368b 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 74507ba399709d9cb1eb7e0e94e9871f8011babb..0000000000000000000000000000000000000000
--- 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 0000000000000000000000000000000000000000..7bd2c3d0d45d511c3dcdba8a59ec5ca022f20e37
--- /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 b40c774a40377c2fb20776500641c127b5bd8fdf..0000000000000000000000000000000000000000
--- 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 f54f264769c5bfa141305e0a7854ad12376f6664..0000000000000000000000000000000000000000
--- 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 f7dfb8ae099f3eb1f845930a7cec25c46089ac90..0000000000000000000000000000000000000000
--- 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 bb15d9423c986d0e0fd71cf42bd76a12adf4e5a5..88314c5a9b614b19cfbde095b8204463d0c1b1e8 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 8aaededdeae158de75c3cfaae42df59742739b11..0000000000000000000000000000000000000000
--- 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 1c5bd8eba7930c69255b8dd5b67e1aff1080ab58..0000000000000000000000000000000000000000
--- 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 c1032b1f0418513fbc7f9b2b4597f0c6c7632044..ef76fce22980e707c314ca731c76d7821383a74f 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 de605624d3050b6c4a99ae92d9c36c1182b9a0ce..5128dd0992434473847959b1900d32cae3e28f3e 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 81afcb9a2eed4c52b89aa0808503bdf528d2e2c4..a4dc029d92aebf9ef39746c0aac196a559e8b45e 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 bd53a0bbb00662f265f8e375ce3008b550f5be2d..0000000000000000000000000000000000000000
--- 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();
-    }
-
-
-}