diff --git a/src/main/java/fr/pasteur/ida/zellige/Main.java b/src/main/java/fr/pasteur/ida/zellige/Main.java
index 6e481005b5e9f80746c73bdbabca8290d3139696..787eac3bb89bbc3944f452f20b551a8af76ff571 100644
--- a/src/main/java/fr/pasteur/ida/zellige/Main.java
+++ b/src/main/java/fr/pasteur/ida/zellige/Main.java
@@ -29,30 +29,49 @@
 package fr.pasteur.ida.zellige;
 
 
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.FileAppender;
+import fr.pasteur.ida.zellige.element.ReferenceSurface;
+import fr.pasteur.ida.zellige.steps.construction.Construction;
 import fr.pasteur.ida.zellige.steps.construction.rounds.ConstructionParameters;
-import fr.pasteur.ida.zellige.steps.projection.DisplayParameters;
 import fr.pasteur.ida.zellige.steps.projection.ProjectionParameters;
+import fr.pasteur.ida.zellige.steps.projection.ReferenceSurfaceProjection;
+import fr.pasteur.ida.zellige.steps.selection.Selection;
 import fr.pasteur.ida.zellige.steps.selection.classification.ClassificationParameters;
 import fr.pasteur.ida.zellige.steps.selection.postTreatment.PostTreatmentParameters;
 import fr.pasteur.ida.zellige.steps.selection.pretreatment.PretreatmentParameters;
-import fr.pasteur.ida.zellige.utils.Util;
-import ij.IJ;
-import io.scif.img.IO;
+import fr.pasteur.ida.zellige.steps.selection.util.ArgumentCheck;
+import io.scif.img.ImgSaver;
 import net.imagej.Dataset;
 import net.imagej.ImageJ;
-import net.imagej.display.ImageDisplayService;
+import net.imagej.ImgPlus;
 import net.imglib2.RandomAccessibleInterval;
+import net.imglib2.display.ColorTable;
 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 net.imglib2.type.numeric.real.FloatType;
 import net.imglib2.view.Views;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.text.RandomStringGenerator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.awt.*;
-import java.io.File;
-import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static fr.pasteur.ida.zellige.utils.Util.create4dimImage;
 
 
 /**
@@ -62,148 +81,363 @@ public class Main
 {
 
     private final static Logger LOGGER = LoggerFactory.getLogger( Main.class );
-
+    private static final String SEMI_COLON_DELIMITER = ";";
+    private static final  int RADIUS = 2;
+    private static final String FILTER = "GaussianBlur";
+    private static final  int CONNEXITY = 4;
+    private static LogFile fileAppender;
     @SuppressWarnings( "unchecked" )
     public static < T extends RealType< T > & NativeType< T > > void main( String[] args ) throws Exception
-    {
-        // Launch ImageJ.
 
-
-
-        // Input of the image.
-        final String imagePath = "doc/Scan1_volume_crop.tif";
-                //args[ 0 ]; /* The image path goes here !!!! */
-                //args[ 0 ]; /* The image path goes here !!!! */
-        LOGGER.debug( imagePath );
-        /* JY version for opening files. */
-//        final SCIFIOImgPlus< ? > imgPlus = IO.openAll( imagePath ).get( 0 );
-//        final Img< T > stackImage = ( Img< T > )
-                IO.openAll( imagePath ).get( 0 ).getImg(); // TODO
-// Load the image.
+    {
+//        // Launch ImageJ.
+//
+//
+//        // Input of the image.
+//        final String imagePath = "doc/Scan1_volume_crop.tif";
+//        //args[ 0 ]; /* The image path goes here !!!! */
+//        //args[ 0 ]; /* The image path goes here !!!! */
+//        LOGGER.debug( imagePath );
+//        /* JY version for opening files. */
+////        final SCIFIOImgPlus< ? > imgPlus = IO.openAll( imagePath ).get( 0 );
+////        final Img< T > stackImage = ( Img< T > )
+//        IO.openAll( imagePath ).get( 0 ).getImg();
+//// Load the image.
+//
+//        // Launch ImageJ.
+//        ImageJ ij = new ImageJ();
+//        ij.launch( args );
+//        String currentFolder = FileSystems.getDefault()
+//                .getPath( "" )
+//                .toAbsolutePath()
+//                .toString();
+//        String imageFilePath = "doc/Cochlée1.tif";
+//        Object obj = ij.io().
+//                open( new File( currentFolder, imageFilePath ).getAbsolutePath() );
+//
+//        // Display it.
+//        ij.ui().show( obj );
+//        Dataset dataset = ij.imageDisplay().getActiveDataset( ij.context().getService( ImageDisplayService.class ).getImageDisplays().get( 0 ) );
+//
+//        final Img< T > stackImage = ( Img< T > ) dataset.getImgPlus().getImg();
+//
+//        //final Img< T > stackImage = ( Img< T > ) imgPlus.getImg();
+////        final Img< ? > image = imgPlus.getImg();
+//        int i  = -1;
+//        /* User Parameters AKA arguments to run the program*/
+////        int bin = Integer.parseInt( args [i++=)] );//TODO order of arguments
+////        int channel =  Integer.parseInt(args [i++] );
+////        int amplitude = Integer.parseInt( args [i++] );
+////        int otsu = Integer.parseInt( args [i++] );
+////        int islandSize = Integer.parseInt( args [i++] );
+////        int connexity = Integer.parseInt( args [i++] );
+////        double sigmaXY = Double.parseDouble( args [i++] );
+////        double sigmaZ = Double.parseDouble( args [i++] );
+////        double startingOsSize1 = Double.parseDouble( args [i++] );
+////        int overlap1 = Integer.parseInt( args [i++] );
+////        double connexityRate1 = Double.parseDouble( args [i++] );
+////        double startingOsSize2 = Double.parseDouble( args [i++] );
+////        int overlap2 = Integer.parseInt( args [i++] );
+////        double connexityRate2 = Double.parseDouble( args [i++] );
+////        double surfaceMinSizeFactor = Double.parseDouble( args [i++] );
+////        int delta = Integer.parseInt( args [i++] );
+//        /* End of parameters. */
+//
+//
+//        int bin = 2;//TODO order of arguments
+//        int channel = 0;
+//        int amplitude = 10;
+//        int otsu = 10;
+//        int islandSize = 5;
+//        int connexity = 4;
+//        double sigmaXY = 3;
+//        double sigmaZ = 1;
+//        double startingOsSize1 = 0.7;
+//        int overlap1 = 10;
+//        double connexityRate1 = 0.6;
+//        double startingOsSize2 = 0.1;
+//        int overlap2 = 5;
+//        double connexityRate2 = 0.9;
+//        double surfaceMinSizeFactor = 0.4;
+//        int delta = 2;
+//        // Fixed parameters for now...
+//        String filter = "GaussianBlur";
+//        double filterParameter = 2;
+//
+//
+//        /* Print parameters.*/
+//        LOGGER.info( "Input image : " + imagePath );
+//        LOGGER.info( "Preprocessing Parameters" );
+//        LOGGER.info( "------------------------" );
+//        LOGGER.info( "bin = {}", bin );
+//        LOGGER.info( "Channel: {}", channel );
+//        LOGGER.info( "filter : {}", filter );
+//        LOGGER.info( "filter parameter : {}", filterParameter );
+//        LOGGER.info( "Selection Parameters" );
+//        LOGGER.info( "------------------------" );
+//        LOGGER.info( "amplitude  : {}", amplitude );
+//        LOGGER.info( "threshold  : {}", otsu );
+//        LOGGER.info( "connexity : {}", connexity );
+//        LOGGER.info( "island size : {}", islandSize );
+//        LOGGER.info( "sigmaXY : {}", sigmaXY );
+//        LOGGER.info( "sigmaZ : {}", sigmaZ );
+//        LOGGER.info( "Construction Parameters" );
+//        LOGGER.info( "------------------------" );
+//        LOGGER.info( "starting os size1 : {}", startingOsSize1 );
+//        LOGGER.info( "overlap1 :{}", overlap1 );
+//        LOGGER.info( "connexityRate1  :{}", connexityRate1 );
+//        LOGGER.info( "starting os size2 : {}", startingOsSize2 );
+//        LOGGER.info( "overlap2 :{}", overlap2 );
+//        LOGGER.info( "connexityRate2  :{}", connexityRate2 );
+//        LOGGER.info( "surface Minimum size factor : {}", surfaceMinSizeFactor );
+//        LOGGER.info( "Projection Parameters" );
+//        LOGGER.info( "------------------------" );
+//        LOGGER.info( "delta : {}", delta );
+//        LOGGER.info( System.lineSeparator() );
+//        /* End of  Print parameters.*/
+//
+//        PretreatmentParameters pretreatmentParameters = new PretreatmentParameters( filter, filterParameter, bin );
+//        ClassificationParameters classificationParameters = new ClassificationParameters( amplitude, otsu );
+//        PostTreatmentParameters postTreatmentParameters = new PostTreatmentParameters( sigmaXY, sigmaZ, islandSize, connexity );
+//        ProjectionParameters projectionParameters = new ProjectionParameters( delta, "MIP" );// no other method implemented yet.
+//        ConstructionParameters[] constructionParameters = new ConstructionParameters[]{
+//                new ConstructionParameters( startingOsSize1, overlap1, connexityRate1, surfaceMinSizeFactor ),
+//                new ConstructionParameters( startingOsSize2, overlap2, connexityRate2, surfaceMinSizeFactor ) };
+//
+//
+//        DisplayParameters displayParameters = new DisplayParameters(
+//                true,
+//                false,
+//                false,
+//                true,
+//                false, false );
+//        IJ.log( "Type: " + stackImage.firstElement().getClass().toGenericString() );
+//
+//        if ( stackImage.numDimensions() == 3 )// Is it a stack ?
+//        {
+//            Img< T > temp = Util.create4dimImage( dataset );
+//            RandomAccessibleInterval< T > input = Views.hyperSlice( temp, 2, channel );
+//            ReferenceSurfaceExtraction< T > rse = new ReferenceSurfaceExtraction<>
+//                    ();
+//            rse.select( input, pretreatmentParameters, classificationParameters, postTreatmentParameters );
+//            rse.construct( input, ( ( Img< T > ) dataset.getImgPlus().getImg() ).factory(), constructionParameters );
+//            if ( ! GraphicsEnvironment.isHeadless() )
+//            {
+//                try
+//                {
+//                    rse.project( projectionParameters, displayParameters );
+//                }
+//                catch ( Exception e )
+//                {
+//                    LOGGER.debug( e.getMessage() );
+//                }
+//            }
+//        }
+//        else
+//        {
+//            LOGGER.debug( " This image has to be a z-stack ! " );
+//        }
 
         // Launch ImageJ.
         ImageJ ij = new ImageJ();
-        ij.launch( args );
-        String currentFolder = FileSystems.getDefault()
-                .getPath( "" )
-                .toAbsolutePath()
-                .toString();
-        String imageFilePath = "doc/Cochlée1.tif";
-        Object obj = ij.io().
-                open( new File( currentFolder, imageFilePath ).getAbsolutePath() );
-
-        // Display it.
-        ij.ui().show( obj );
-        Dataset dataset = ij.imageDisplay().getActiveDataset(ij.context().getService( ImageDisplayService.class ).getImageDisplays().get( 0 ));
-        Thread.sleep( 7000 );
-        final Img< T > stackImage = ( Img< T > ) dataset.getImgPlus().getImg();
-
-        //final Img< T > stackImage = ( Img< T > ) imgPlus.getImg();
-//        final Img< ? > image = imgPlus.getImg();
-
-        /* User Parameters AKA arguments to run the program*/
-//        int bin = Integer.parseInt( args [15] );//TODO order of arguments
-//        int amplitude = Integer.parseInt( args[ 1 ] );
-//        int otsu = Integer.parseInt( args[ 2 ] );
-//        int islandSize = Integer.parseInt( args[ 3 ] );
-//        int connexity = Integer.parseInt( args[ 4 ] );
-//        double sigmaXY = Double.parseDouble( args[ 5 ] );
-//        double sigmaZ = Double.parseDouble( args[ 6 ] );
-//        double startingOsSize1 = Double.parseDouble( args[ 7 ] );
-//        int overlap1 = Integer.parseInt( args[ 8 ] );
-//        double connexityRate1 = Double.parseDouble( args[ 9 ] );
-//        double startingOsSize2 = Double.parseDouble( args[ 10 ] );
-//        int overlap2 = Integer.parseInt( args[ 11 ] );
-//        double connexityRate2 = Double.parseDouble( args[ 12 ] );
-//        double surfaceMinSizeFactor = Double.parseDouble( args[ 13 ] );
-//        int delta = Integer.parseInt( args[ 14 ] );
-        /* End of parameters. */
-
-
-
-        int bin = 2;//TODO order of arguments
-        int channel = 0;
-        int amplitude = 10;
-        int otsu = 10;
-        int islandSize =5;
-        int connexity =4 ;
-        double sigmaXY = 3;
-        double sigmaZ = 1;
-        double startingOsSize1 = 0.7 ;
-        int overlap1 = 10;
-        double connexityRate1 =0.6 ;
-        double startingOsSize2 = 0.1;
-        int overlap2 = 5;
-        double connexityRate2 = 0.9;
-        double surfaceMinSizeFactor = 0.4;
-        int delta = 2;
-        // Fixed parameters for now...
-        String filter = "GaussianBlur";
-        double filterParameter = 2;
-
-
-        /* Print parameters.*/
-        LOGGER.debug( "Input image : " + imagePath );
-        LOGGER.debug( "bin = {}", bin);
-        LOGGER.debug( "filter : " + filter );
-        LOGGER.debug( "filter parameter : " + filterParameter );
-        LOGGER.debug( "amplitude  : " + amplitude );
-        LOGGER.debug( "threshold  : " + otsu );
-        LOGGER.debug( "connexity : " + connexity );
-        LOGGER.debug( "island size : " + islandSize );
-        LOGGER.debug( "sigmaXY : " + sigmaXY );
-        LOGGER.debug( "sigmaZ : " + sigmaZ );
-        LOGGER.debug( "starting os size1 : " + startingOsSize1 );
-        LOGGER.debug( "overlap1 :" + overlap1 );
-        LOGGER.debug( "connexityRate1  :" + connexityRate1 );
-        LOGGER.debug( "starting os size2 : " + startingOsSize2 );
-        LOGGER.debug( "overlap2 :" + overlap2 );
-        LOGGER.debug( "connexityRate2  :" + connexityRate2 );
-        LOGGER.debug( "surface Minimum size factor : " + surfaceMinSizeFactor );
-        LOGGER.debug( "delta : " + delta );
-        LOGGER.debug( System.lineSeparator() );
-        /* End of  Print parameters.*/
-
-        PretreatmentParameters pretreatmentParameters = new PretreatmentParameters( filter, filterParameter,bin );
-        ClassificationParameters classificationParameters = new ClassificationParameters( amplitude, otsu );
-        PostTreatmentParameters postTreatmentParameters = new PostTreatmentParameters( sigmaXY, sigmaZ, islandSize, connexity );
-        ProjectionParameters projectionParameters = new ProjectionParameters( delta, "MIP" );// no other method implemented yet.
-        ConstructionParameters[] constructionParameters = new ConstructionParameters[]{
-                new ConstructionParameters( startingOsSize1, overlap1, connexityRate1, surfaceMinSizeFactor ),
-                new ConstructionParameters( startingOsSize2, overlap2, connexityRate2, surfaceMinSizeFactor ) };
-
-
-        DisplayParameters displayParameters = new DisplayParameters(
-                true,
-                false,
-                false,
-                true,
-                false, false );
-        IJ.log( "Type: " + stackImage.firstElement().getClass().toGenericString() );
-
-        if ( stackImage.numDimensions() == 3 )// Is it a stack ?
+//        ij.launch( args );
+        String CSV_FILE = "doc/test.csv"; //args[ 0 ];
+        setLogStatus();
+        try ( Stream< String > lines = Files.lines( Paths.get( CSV_FILE ) ) )
         {
-            Img<T> temp = Util.create4dimImage(dataset);
-            RandomAccessibleInterval<T> input = Views.hyperSlice(temp, 2, channel);
-            ReferenceSurfaceExtraction< T > rse = new ReferenceSurfaceExtraction<>
-                    ( );
-            rse.select( input,pretreatmentParameters, classificationParameters, postTreatmentParameters );
-            rse.construct( input, ( ( Img<T> ) dataset.getImgPlus().getImg() ).factory(), constructionParameters );
-            if ( ! GraphicsEnvironment.isHeadless() )
+            List< List< String > > records = lines.map( line -> Arrays.asList( line.split( SEMI_COLON_DELIMITER ) ) )
+                    .collect( Collectors.toList() );
+            LOGGER.debug( "the csv is loaded" );
+            for ( int i = 1; i < records.size(); i++ ) // skip the header
             {
-                try
+                List< String > line = records.get( i );
+                // Input
+                String inputPath = line.get( 0 );
+                Dataset dataset = ArgumentCheck.input( ij.scifio().datasetIO().open( inputPath ) );
+                String inputName = FilenameUtils.removeExtension(dataset.getName());
+                String id = uniqueID();
+                Path datasetLocation = Paths.get(inputPath).getParent();
+
+                Path outputPath = Files.createDirectories(Paths.get(String.format("%s\\%s%s",datasetLocation.toString() , inputName, id)));
+                setLogFilePath( String.format("%s\\log.txt", outputPath) );
+
+                int nbChannel = ( int ) dataset.getChannels() > 0 ? ( int ) dataset.getChannels(): 1;
+                ArrayList<ColorTable> colorTables = new ArrayList<>();
+                for ( int channel = 0; channel < nbChannel ; channel++ )
+                {
+                    colorTables.add(dataset.getImgPlus().getColorTable( channel ));
+                }
+
+                // Preprocessing Parameters
+                LOGGER.info( "Preprocessing parameters" );
+                LOGGER.info( "------------------------" );
+                int bin = ArgumentCheck.bin( line.get( 1 ) );
+                int channel = ArgumentCheck.channel( line.get( 2 ), nbChannel );
+
+
+                // Selection Parameters
+                LOGGER.info( "Selection parameters" );
+                LOGGER.info( "--------------------" );
+                int amplitude = ArgumentCheck.amplitude( line.get( 3 ) );
+                int otsu = ArgumentCheck.otsu( line.get( 4 ) );
+                int islandSize = ArgumentCheck.islandSize( line.get( 5 ) );
+                double sigmaXY = ArgumentCheck.sigmaXY( line.get( 6 ) );
+                double sigmaZ = ArgumentCheck.sigmaZ( line.get( 7 ) );
+
+                // Construction Parameters
+                LOGGER.info( "Construction parameters" );
+                LOGGER.info( "-----------------------" );
+                int FIRST_ROUND = 1;
+                double startingOsSize1 = ArgumentCheck.startingOsSize( line.get( 8 ), FIRST_ROUND );
+                int overlap1 = ArgumentCheck.overlap( line.get( 9 ), FIRST_ROUND );
+                double connexityRate1 = ArgumentCheck.connexity( line.get( 10 ), FIRST_ROUND );
+                int SECOND_ROUND = 2;
+                double startingOsSize2 = ArgumentCheck.startingOsSize( line.get( 11 ), SECOND_ROUND );
+                int overlap2 = ArgumentCheck.overlap( line.get( 12 ), SECOND_ROUND );
+                double connexityRate2 = ArgumentCheck.connexity( line.get( 13 ), SECOND_ROUND );
+                double surfaceMinSizeFactor = Double.parseDouble( line.get( 14 ) );
+
+                // Projection Parameters
+                LOGGER.info( "\nProjection parameters" );
+                LOGGER.info( "--------------------" );
+                ArrayList< ProjectionParameters > projectionParameters = new ArrayList<>();
+                for ( int n = 0; n < nbChannel; n++ )
+                {
+                    LOGGER.info( "  Channel {}", (n+1 ));
+//                    int channelNb = n * 1;
+                    int delta = ArgumentCheck.delta( line.get( 15 +  (3 * n)  ), n );
+                    int offset = ArgumentCheck.offset( line.get( 16 + (3 * n) ), n );
+                    String method = ArgumentCheck.method( line.get( 17 +(3 * n) ), n );
+                    ProjectionParameters parameters = new ProjectionParameters( delta, offset, method );
+                    projectionParameters.add( parameters );
+                }
+                LOGGER.debug( "All argument are checked." );
+
+                //Parameters
+                PretreatmentParameters pretreatmentParameters = new PretreatmentParameters( FILTER, RADIUS, bin );
+                ClassificationParameters classificationParameters = new ClassificationParameters( amplitude, otsu );
+                PostTreatmentParameters postTreatmentParameters = new PostTreatmentParameters( sigmaXY, sigmaZ, islandSize, CONNEXITY );
+                ConstructionParameters[] constructionParameters = new ConstructionParameters[2];
+                constructionParameters [0] = new ConstructionParameters( startingOsSize1, overlap1, connexityRate1, surfaceMinSizeFactor );
+                constructionParameters [1] = new ConstructionParameters( startingOsSize2, overlap2, connexityRate2, surfaceMinSizeFactor );
+
+                //set the input
+                Img<T> input ;
+                if ( nbChannel == 1 )
                 {
-                    rse.project( projectionParameters, displayParameters );
+                    try
+                    {
+                        input = ( create4dimImage( dataset ) );
+                    }
+                    catch ( Exception e )
+                    {
+                        throw new RuntimeException( e );
+                    }
                 }
-                catch ( Exception e )
+                else
                 {
-                    LOGGER.debug( e.getMessage() );
+                    input = ( ( Img< T > ) dataset.getImgPlus() );
                 }
+
+                // Set the target channel
+                RandomAccessibleInterval<T> inputChannel = Views.hyperSlice( input, 2, (channel -1) );
+
+                // Preprocessing and selection steps
+                ImageJFunctions.show(input, "input");
+                Img <FloatType > selectedPixels = Selection.run(inputChannel, pretreatmentParameters, classificationParameters, postTreatmentParameters);
+
+                // Construction step
+                ArrayList< ReferenceSurface< T > > referenceSurfaces = Construction.run(constructionParameters, input, input.factory(), selectedPixels, bin);
+
+                // Projection step
+                ArrayList<ImgPlus<T>> finalProjections = new ArrayList<>();
+
+
+                for ( int j = 0; j < referenceSurfaces.size(); j++ )
+                {
+                    ArrayList<Img<T>> channelProjections = new ArrayList<>();
+                    Img< UnsignedShortType > zMap = referenceSurfaces.get(j).getzMap();
+                    for ( int k = 0; k < nbChannel; k++ )
+                    {
+                        ProjectionParameters projectionParameter = projectionParameters.get( 0 );
+                        RandomAccessibleInterval<T> channelImg = Views.hyperSlice( input, 2, k );
+                        Img<T> subVolume = ReferenceSurfaceProjection.getSubStack( channelImg, input.factory(),zMap, projectionParameter.getDelta(), projectionParameter.getOffset());
+
+                        Img<T> p = ReferenceSurfaceProjection.run( subVolume, projectionParameter.getProjectionMethod() );
+                        channelProjections.add(k, p );
+                    }
+                    Img<T> temp = ReferenceSurfaceProjection.regroupChannels( channelProjections );
+                    String projectionName = String.format( "%s_proj_%d", inputName, (j+1) );
+                    ImgPlus< T > finalProjection = ReferenceSurfaceProjection.setColorsAndName( temp, colorTables, projectionName );
+                    finalProjections.add( finalProjection );
+                }
+                ImgSaver saver = new ImgSaver();
+                for ( int j = 0; j < referenceSurfaces.size(); j++ )
+                {
+                    ImgPlus<T> projection = finalProjections.get(j);
+                    String imgLocation = String.format( "%s\\%s%s",outputPath , projection.getName(), ".tif");
+                    saver.saveImg(imgLocation, projection ) ;
+                }
+                LOGGER.debug("End of process");
+                fileAppender.stop();
             }
         }
-        else
+    }
+
+    /**
+     * Creates a new LogAppender to display the program state in the GUI.
+     */
+    public static void setLogStatus()
+    {
+        LoggerContext context = ( LoggerContext ) LoggerFactory.getILoggerFactory();
+        ch.qos.logback.classic.Logger rootLogger =  context.getLogger(Logger.ROOT_LOGGER_NAME);
+
+        // Encoder
+        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
+        encoder.setContext( context );
+        encoder.setPattern( "%msg%n" );
+        encoder.start();
+
+        // Creates a new FileAppender
+        fileAppender = new LogFile();
+        fileAppender.setContext( context );
+        fileAppender.setFile( ".\\log.txt" );
+
+        fileAppender.setEncoder( encoder );
+        fileAppender.start();
+
+        // Attach the appender to the logger
+        rootLogger.addAppender( fileAppender );
+
+    }
+
+    public static void setLogFilePath(String path)
+    {
+        fileAppender.stop();
+        fileAppender.setFile( path );
+        fileAppender.start();
+    }
+
+    public static String uniqueID()
+    {
+        RandomStringGenerator generator = new RandomStringGenerator.Builder()
+                .withinRange('A', 'Z').get();
+        RandomStringGenerator generator2 = new RandomStringGenerator.Builder()
+                .withinRange('1', '9').get();
+        return String.format("_%s%s", generator.generate(2), generator2.generate(2));
+    }
+
+    public static class LogFile extends FileAppender< ILoggingEvent >
+    {
+        @Override
+        protected void append( ILoggingEvent iLoggingEvent )
         {
-            LOGGER.debug( " This image has to be a z-stack ! " );
+            String level = iLoggingEvent.getLevel().toString();
+            if ( level.equals( Level.INFO.toString() )  )
+            {
+               super.append(iLoggingEvent);
+            }
+
         }
     }
 }
diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/ArgumentCheck.java b/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/ArgumentCheck.java
index 4676bb2fa68532d97468517b72bb9e6d0cc0fa33..27fabe2c0a2434cfa37d7d2774156336db08c386 100644
--- a/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/ArgumentCheck.java
+++ b/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/ArgumentCheck.java
@@ -21,10 +21,7 @@ public class ArgumentCheck
         int nbChannels = ( int ) dataset.getChannels();
 
         // Set the file info label
-        String advice = "You go girl!";
-        LOGGER.debug( "NUmber of dimensions: {}", nbDim );
-        LOGGER.debug( "NUmber of channels: {}", nbChannels );
-        LOGGER.debug( "Number of frames: {}", nbFrames );
+
 
         if ( nbFrames > 1 )
         {
@@ -37,6 +34,11 @@ public class ArgumentCheck
             throw  new NoA3DStackException() ;
 
         }
+
+        LOGGER.info("Input: {}", dataset.getName());
+        LOGGER.info( "NUmber of dimensions: {}", nbDim );
+        LOGGER.info( "NUmber of channels: {}", nbChannels );
+        LOGGER.info( "Number of frames: {}", nbFrames );
         return dataset;
     }
 
@@ -55,12 +57,15 @@ public class ArgumentCheck
             {
                 throw new ParameterException( " The value of bin parameter is to high" );
             }
+            LOGGER.info( "Bin: {}", bin );
+
             return bin;
         }
         catch (NumberFormatException nfe)
         {
             throw new ParameterException( " The bin value must be an integer" );
         }
+
     }
 
     public static int channel( String CHANNEL, int channelNb) throws ParameterException
@@ -77,6 +82,8 @@ public class ArgumentCheck
             {
                 throw new ParameterException( String.format(" There is no channel %d in the input image " , channel));
             }
+
+            LOGGER.info( "Target channel:: {}", channel );
             return channel;
         }
         catch (NumberFormatException nfe)
@@ -99,6 +106,7 @@ public class ArgumentCheck
             {
                 throw new ParameterException( " The value of amplitude parameter must be inferior or equal to 255" );
             }
+            LOGGER.info( "Amplitude threshold: {}", amplitude );
             return amplitude;
         }
         catch (NumberFormatException nfe)
@@ -121,6 +129,7 @@ public class ArgumentCheck
             {
                 throw new ParameterException( " The value of otsu parameter must be inferior or equal to 255" );
             }
+            LOGGER.info( "Otsu threshold: {}", otsu );
             return otsu;
         }
         catch (NumberFormatException nfe)
@@ -143,6 +152,7 @@ public class ArgumentCheck
             {
                 throw new ParameterException( " The value of islandSize parameter must be inferior or equal to 50" );
             }
+            LOGGER.info( "Island size: {}", islandSize );
             return islandSize;
         }
         catch (NumberFormatException nfe)
@@ -165,6 +175,7 @@ public class ArgumentCheck
             {
                 throw new ParameterException( " The value of sigmaXY parameter must be inferior or equal to 10" );
             }
+            LOGGER.info( "XY smoothing: {}", sigmaXY );
             return sigmaXY;
         }
         catch (NumberFormatException nfe)
@@ -187,6 +198,7 @@ public class ArgumentCheck
             {
                 throw new ParameterException( " The value of sigmaZ parameter must be inferior or equal to 10" );
             }
+            LOGGER.info( "Z smoothing: {}", sigmaZ );
             return sigmaZ;
         }
         catch (NumberFormatException nfe)
@@ -210,12 +222,13 @@ public class ArgumentCheck
                         String.format( " The value of %s starting OS size (ST%d) parameter can not be negative",
                                 os, round ));
             }
-            if ( osSize > 10  )
+            if ( osSize > 1  )
             {
                 throw new ParameterException(
                         String.format(" The value of %s starting OS size (ST%d) parameter must be inferior or equal to 1",
                                 os, round ));
             }
+            LOGGER.info( "{} Starting OS size: {}", os, osSize );
             return osSize;
         }
         catch (NumberFormatException nfe)
@@ -225,37 +238,38 @@ public class ArgumentCheck
         }
     }
 
-    public static double connexity( String OS_SIZE, int round) throws ParameterException
+    public static double connexity( String CONNEXITY, int ROUND) throws ParameterException
     {
-        String os = (round == 2 ? "First round": "Second round");
+        String round = (ROUND == 2 ? "First round": "Second round");
         try
         {
-            double osSize = Double.parseDouble( OS_SIZE );
+            double connexity = Double.parseDouble( CONNEXITY );
 
-            if ( osSize < 0 )
+            if ( connexity < 0 )
             {
                 throw new ParameterException(
                         String.format( " The value of %s connexity rate (CR%d) parameter can not be negative",
-                                os, round ));
+                                round, ROUND ));
             }
-            if ( osSize > 10  )
+            if ( connexity > 1  )
             {
                 throw new ParameterException(
                         String.format(" The value of %s connexity rate (CR%d) parameter must be inferior or equal to 1",
-                                os, round ));
+                                round, ROUND ));
             }
-            return osSize;
+            LOGGER.info( "{} connexity: {}", round, connexity );
+            return connexity;
         }
         catch (NumberFormatException nfe)
         {
             throw new ParameterException(  String.format(" The %s connexity rate (CR%d) parameter must a number comprise between 0 and 1",
-                    os, round ));
+                    round, ROUND ));
         }
     }
 
-    public static int overlap( String OVERLAP, int round) throws ParameterException
+    public static int overlap( String OVERLAP, int ROUND) throws ParameterException
     {
-        String os = (round == 2 ? "First round": "Second round");
+        String round = (ROUND == 2 ? "First round": "Second round");
         try
         {
             int overlap = Integer.parseInt( OVERLAP );
@@ -263,14 +277,15 @@ public class ArgumentCheck
             if ( overlap < 0 )
             {
                 throw new ParameterException(
-                        String.format(" The value of the %s overlap parameter (R%d) can not be negative",os, round  ));
+                        String.format(" The value of the %s overlap parameter (R%d) can not be negative",round, ROUND  ));
             }
             if ( overlap > 50  )
             {
                 throw new ParameterException(
                         String.format( " The value of the %s overlap parameter (R%d) must be inferior or equal to 50",
-                                os, round  ));
+                                round, ROUND  ));
             }
+            LOGGER.info( "{} overlap: {}", round, overlap );
             return overlap;
         }
         catch (NumberFormatException nfe)
@@ -297,6 +312,7 @@ public class ArgumentCheck
             {
                 throw new ParameterException( " The value of delta parameter is to high" );
             }
+            LOGGER.info( "Delta: {}",delta );
             return delta;
         }
         catch (NumberFormatException nfe)
@@ -323,6 +339,7 @@ public class ArgumentCheck
             {
                 throw new ParameterException( " The value of offset parameter is to high" );
             }
+            LOGGER.info( "Offset: {}",offset );
             return offset;
         }
         catch (NumberFormatException nfe)
@@ -341,6 +358,7 @@ public class ArgumentCheck
             {
                 throw new ParameterException( " The method  %s ois not implemented in Zellige, try MIP or MEAN" );
             }
+        LOGGER.info( "Method: {}",METHOD );
             return METHOD;
     }