diff --git a/src/main/java/fr/pasteur/ida/zellige/Main.java b/src/main/java/fr/pasteur/ida/zellige/Main.java
index 787eac3bb89bbc3944f452f20b551a8af76ff571..d4370e98ce1502bd46d78854661bd4043b1568c4 100644
--- a/src/main/java/fr/pasteur/ida/zellige/Main.java
+++ b/src/main/java/fr/pasteur/ida/zellige/Main.java
@@ -80,364 +80,13 @@ import static fr.pasteur.ida.zellige.utils.Util.create4dimImage;
 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();
-//// 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 CSV_FILE = "doc/test.csv"; //args[ 0 ];
-        setLogStatus();
-        try ( Stream< String > lines = Files.lines( Paths.get( CSV_FILE ) ) )
-        {
-            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
-            {
-                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 )
-                {
-                    try
-                    {
-                        input = ( create4dimImage( dataset ) );
-                    }
-                    catch ( Exception e )
-                    {
-                        throw new RuntimeException( e );
-                    }
-                }
-                else
-                {
-                    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();
-            }
-        }
-    }
-
-    /**
-     * 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();
-    }
+    @SuppressWarnings( "unchecked" )
 
-    public static String uniqueID()
+    public static < T extends RealType< T > & NativeType< T > > void main( String [] args ) throws Exception
     {
-        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));
+        String CSV_FILE ="doc/test.csv";
+        ReferenceSurfaceExtraction.run( CSV_FILE );
     }
 
-    public static class LogFile extends FileAppender< ILoggingEvent >
-    {
-        @Override
-        protected void append( ILoggingEvent iLoggingEvent )
-        {
-            String level = iLoggingEvent.getLevel().toString();
-            if ( level.equals( Level.INFO.toString() )  )
-            {
-               super.append(iLoggingEvent);
-            }
-
-        }
-    }
 }
diff --git a/src/main/java/fr/pasteur/ida/zellige/ReferenceSurfaceExtraction.java b/src/main/java/fr/pasteur/ida/zellige/ReferenceSurfaceExtraction.java
index 7150890f25dff0d0cb4676dbc04bb6abecb2d152..b0d63bcb125c76ce735e5f0d5f6e8458bde82cb7 100644
--- a/src/main/java/fr/pasteur/ida/zellige/ReferenceSurfaceExtraction.java
+++ b/src/main/java/fr/pasteur/ida/zellige/ReferenceSurfaceExtraction.java
@@ -28,8 +28,16 @@
  */
 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.element.Surface;
+import fr.pasteur.ida.zellige.gui.exception.NoA3DStackException;
+import fr.pasteur.ida.zellige.gui.exception.TimeLapseException;
+import fr.pasteur.ida.zellige.steps.construction.Construction;
 import fr.pasteur.ida.zellige.steps.construction.ConstructionCompletion;
 import fr.pasteur.ida.zellige.steps.construction.exception.NoSurfaceFoundException;
 import fr.pasteur.ida.zellige.steps.construction.rounds.ConstructionParameters;
@@ -44,27 +52,53 @@ import fr.pasteur.ida.zellige.steps.selection.classification.ClassificationParam
 import fr.pasteur.ida.zellige.steps.selection.exception.DataValidationException;
 import fr.pasteur.ida.zellige.steps.selection.exception.ImageTooLargeException;
 import fr.pasteur.ida.zellige.steps.selection.exception.NoClassificationException;
+import fr.pasteur.ida.zellige.steps.selection.exception.ParameterException;
 import fr.pasteur.ida.zellige.steps.selection.postTreatment.PostTreatmentParameters;
 import fr.pasteur.ida.zellige.steps.selection.pretreatment.PretreatmentParameters;
+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.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.io.IOException;
+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.steps.selection.util.Derivative.FORWARD;
+import static fr.pasteur.ida.zellige.utils.Util.create4dimImage;
 
 
 public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T > >
 {
 
     private final static Logger LOGGER = LoggerFactory.getLogger( ReferenceSurfaceExtraction.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" )
     private final ArrayList< ReferenceSurface< T > > referenceSurfaces = new ArrayList<>();
 
     private Img< FloatType > maximums;
@@ -86,9 +120,234 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T
     private static final String derivativeMethod = FORWARD;
 
 
-    public ReferenceSurfaceExtraction(  )
+
+
+
+    public static < T extends RealType< T > & NativeType< T > > void run(String CSV_FILE)throws IOException, ParameterException
+    {
+        ImageJ ij = new ImageJ();
+//        ij.launch( args );
+        setLogStatus();
+        try ( Stream< String > lines = Files.lines( Paths.get( CSV_FILE ) ) )
+        {
+            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
+            {
+                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 )
+                {
+                    try
+                    {
+                        input = ( create4dimImage( dataset ) );
+                    }
+                    catch ( Exception e )
+                    {
+                        throw new RuntimeException( e );
+                    }
+                }
+                else
+                {
+                    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();
+            }
+        }
+        catch ( TimeLapseException e )
+        {
+            throw new RuntimeException( e );
+        }
+        catch ( DataValidationException e )
+        {
+            throw new RuntimeException( e );
+        }
+        catch ( NoSurfaceFoundException e )
+        {
+            throw new RuntimeException( e );
+        }
+        catch ( NoClassificationException e )
+        {
+            throw new RuntimeException( e );
+        }
+        catch ( ImageTooLargeException e )
+        {
+            throw new RuntimeException( e );
+        }
+        catch ( NoA3DStackException e )
+        {
+            throw new RuntimeException( e );
+        }
+
+    }
+    /**
+     * 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 )
+        {
+            String level = iLoggingEvent.getLevel().toString();
+            if ( level.equals( Level.INFO.toString() )  )
+            {
+                super.append(iLoggingEvent);
+            }
+
+        }
     }
     public static double getAdequacy()
     {
diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java b/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java
index cd357d31e397415d839be8e4c4d00861a34f7ec6..92f61ad013791a992d3b9c45f77842929d3f1adb 100644
--- a/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java
+++ b/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java
@@ -38,8 +38,11 @@ import fr.pasteur.ida.zellige.gui.parameter.ZelligeParameters;
 import javafx.application.Platform;
 import javafx.fxml.FXML;
 import javafx.fxml.Initializable;
+import javafx.scene.Scene;
 import javafx.scene.control.*;
 import javafx.stage.FileChooser;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
 import net.imglib2.type.NativeType;
 import net.imglib2.type.numeric.RealType;
 import org.slf4j.Logger;
@@ -199,6 +202,23 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme
         }
     }
 
+    @FXML
+    private void openFileDialog() {
+
+
+            BatchModeDialog dialog = new BatchModeDialog();
+
+            // Create a new Stage for the dialog
+            Stage dialogStage = new Stage();
+            dialogStage.setTitle("Batch Mode");
+            dialogStage.initModality( Modality.APPLICATION_MODAL);  // Blocks interaction with main window
+            dialogStage.setScene(new Scene(dialog));
+
+            // Show the dialog window
+            dialogStage.showAndWait();  // Use showAndWait() to wait until the dialog is closed
+
+    }
+
     private File chooseFile()
     {
         FileChooser fileChooser = chooseAFile( null, "Select a Zellige parameter file"
diff --git a/src/main/resources/fr.pasteur.ida.zellige.gui.view/Main.fxml b/src/main/resources/fr.pasteur.ida.zellige.gui.view/Main.fxml
index 06a92646a139078a2e0116ee159053dd6735783b..109d1650aaeca87c2814157b6b03e6f3aa9a5175 100644
--- a/src/main/resources/fr.pasteur.ida.zellige.gui.view/Main.fxml
+++ b/src/main/resources/fr.pasteur.ida.zellige.gui.view/Main.fxml
@@ -23,7 +23,7 @@
      <menus>
        <Menu mnemonicParsing="false" text="File">
          <items>
-           <MenuItem mnemonicParsing="false" text="Batch Mode" />
+           <MenuItem mnemonicParsing="false" onAction="#openFileDialog" text="Batch Mode" />
          </items>
        </Menu>
        <Menu mnemonicParsing="false" text="Edit">