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">