/*- * #%L * Fiji distribution of ImageJ for the life sciences. * %% * Copyright (C) 2007 - 2017 Fiji developers. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-2.0.html>. * #L% */ package mpicbg.spim.io; /** * <p>Title: </p> * * <p>Description: </p> * * <p>Copyright: Copyright (c) 2006</p> * * <p>Company: Diplomarbeit - IZBI Leipzig/TU Dresden</p> * * @author Stephan Preibisch * @version 1.0 */ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Date; import spim.Threads; import mpicbg.imglib.container.array.ArrayContainerFactory; import mpicbg.imglib.container.cell.CellContainerFactory; import mpicbg.imglib.interpolation.linear.LinearInterpolatorFactory; import mpicbg.imglib.interpolation.nearestneighbor.NearestNeighborInterpolatorFactory; import mpicbg.imglib.outofbounds.OutOfBoundsStrategyFactory; import mpicbg.imglib.outofbounds.OutOfBoundsStrategyMirrorFactory; import mpicbg.imglib.outofbounds.OutOfBoundsStrategyValueFactory; import mpicbg.imglib.type.numeric.real.FloatType; import mpicbg.spim.registration.ViewStructure; public class ConfigurationParserSPIM { public static SPIMConfiguration parseFile( String confFileName ) throws ConfigurationParserException { SPIMConfiguration conf = new SPIMConfiguration(); String knownDatatypes[] = { "int", "double", "String", "boolean", "float", "float[]", "ContainerFactory", "InterpolatorFactory", "OutsideStrategyFactory" }; // convert to unix-style confFileName = confFileName.replace('\\', '/'); confFileName = confFileName.replaceAll( "//", "/" ); // get path String confFilePath; try { if (confFileName.indexOf("/") != -1) confFilePath = confFileName.substring(0, confFileName.lastIndexOf("/") + 1); else confFilePath = ""; } catch (Exception e) { throw new ConfigurationParserException("Error parsing confFileName-String: '" + e.getMessage() + "'"); } // open configfile BufferedReader assignFile = null; BufferedReader confFile; try { confFile = TextFileAccess.openFileReadEx(confFileName); } catch ( IOException e ) { throw new ConfigurationParserException("Configuration file not found: '" + confFileName + "'"); } // open assignment file try { while (confFile.ready() && assignFile == null) { String line = confFile.readLine().trim(); if (line.startsWith("<") && line.endsWith(">")) { assignFile = TextFileAccess.openFileRead(confFilePath + line.substring(1, line.length() - 1)); if (assignFile == null) throw new ConfigurationParserException("Variables Assignment file not found: '" + confFilePath + (line.substring(1, line.length() - 1)) + "'"); } } } catch (Exception e) { throw new ConfigurationParserException("Error finding assignment file entry: '" + e.getMessage() + "'"); } // load assignments final ArrayList<ConfigurationParserObject> assignments = new ArrayList<ConfigurationParserObject>(); Field[] fields = conf.getClass().getDeclaredFields(); int lineCount = 0; try { while (assignFile.ready()) { lineCount++; String line = assignFile.readLine().trim(); if (!line.startsWith("#") && line.length() > 0) { String words[] = line.split("="); if (words.length != 2) throw new ConfigurationParserException("Wrong format in assignment file, should be 'entry = datatype name'"); // entry name final ConfigurationParserObject cpo = new ConfigurationParserObject(); cpo.setEntry( words[0].trim() ); words = words[1].trim().split(" "); if (words.length != 2) throw new ConfigurationParserException("Wrong format in assignment file, datatype and name on right side MUST have no spaces"); words[0] = words[0].trim(); words[1] = words[1].trim(); // datatype boolean positiveMatch = false; for (int i = 0; i < knownDatatypes.length; i++) { if (words[0].compareTo(knownDatatypes[i]) == 0) positiveMatch = true; } if (!positiveMatch) { String datatypes = ""; for (int i = 0; i < knownDatatypes.length; i++) datatypes += knownDatatypes[i] + " "; throw new ConfigurationParserException("Unknown datatype '" + words[0] + "', available datatypes are: " + datatypes); } cpo.setDataType( words[0] ); // variable name int variablesPosition = -1; for (int i = 0; i < fields.length; i++) { if (words[1].compareTo(fields[i].getName()) == 0) variablesPosition = i; } if (variablesPosition == -1) { String variables = ""; for (int i = 0; i < fields.length; i++) variables += fields[i].getName() + "\n"; throw new ConfigurationParserException("Unknown variable '" + words[1] + "', available variables are:\n" + variables); } cpo.setVariableName( words[1] ); cpo.setVariableFieldPosition( variablesPosition ); assignments.add( cpo ); } } } catch (Exception e) { throw new ConfigurationParserException("Error reading/parsing assignment file at line " + lineCount + ":\n" + e.getMessage()); } // read configuration file and assign entry values to assigned variables lineCount = 0; try { while (confFile.ready()) { lineCount++; String line = confFile.readLine().trim(); if (!line.startsWith("#") && line.length() > 0) { String words[] = line.split("="); if (words.length != 2) throw new ConfigurationParserException("Wrong format in configuration file, should be 'entry = value'"); words[0] = words[0].trim(); words[1] = words[1].trim(); int entryPos = findEntry(assignments, words[0]); if (entryPos == -1) throw new ConfigurationParserException("Entry '" + words[0] + "' does not exist!\nFollowing entries are available:\n" + getAllEntries(assignments)); final ConfigurationParserObject cpo = assignments.get( entryPos ); final int varFieldPos = cpo.getVariableFieldPosition(); if ( cpo.getDataType().compareTo("byte") == 0 ) { fields[varFieldPos].setByte(conf, Byte.parseByte(words[1])); } else if ( cpo.getDataType().compareTo("short") == 0 ) { fields[varFieldPos].setShort(conf, Short.parseShort(words[1])); } else if ( cpo.getDataType().compareTo("int") == 0 ) { fields[varFieldPos].setInt(conf, Integer.parseInt(words[1])); } else if ( cpo.getDataType().compareTo("long") == 0) { fields[varFieldPos].setLong(conf, Long.parseLong(words[1])); } else if ( cpo.getDataType().compareTo("boolean") == 0) { fields[varFieldPos].setBoolean(conf, Boolean.parseBoolean(words[1])); } else if ( cpo.getDataType().compareTo("float[]") == 0) { final String[] entries = words[1].split( "," ); if ( entries.length < 1 ) throw new ConfigurationParserException("Cannot parse array, should be 3, 4.3, 2, ... - but is '" + words[1] + "'"); final float[] values = new float[ entries.length ]; for ( int i = 0; i < entries.length; ++i ) values[ i ] = Float.parseFloat( entries[ i ] ); fields[varFieldPos].set( conf, values ); } else if ( cpo.getDataType().compareTo("float") == 0) { if (words[1].toLowerCase().compareTo("nan") == 0) fields[varFieldPos].setFloat(conf, Float.NaN); else fields[varFieldPos].setFloat(conf, Float.parseFloat(words[1])); } else if ( cpo.getDataType().compareTo("double") == 0) { if (words[1].toLowerCase().compareTo("nan") == 0) fields[varFieldPos].setDouble(conf, Double.NaN); else fields[varFieldPos].setDouble(conf, Double.parseDouble(words[1])); } else if ( cpo.getDataType().compareTo("String") == 0) { if (words[1].equals("null")) fields[varFieldPos].set(conf, null); else { if (words[1].startsWith("\"") && words[1].endsWith("\"")) fields[varFieldPos].set(conf, words[1].substring(1, words[1].length() - 1)); else throw new ConfigurationParserException("Strings have to be surrounded by \"\" or be null"); } } else if ( cpo.getDataType().compareTo("ContainerFactory") == 0) { if (words[1].startsWith("ArrayContainerFactory")) { ArrayContainerFactory factory = new ArrayContainerFactory(); factory.setParameters(words[1].substring(words[1].indexOf("("), words[1].length())); fields[varFieldPos].set(conf, factory); } else if (words[1].startsWith("CellContainerFactory")) { CellContainerFactory factory = new CellContainerFactory(); factory.setParameters(words[1].substring(words[1].indexOf("("), words[1].length())); fields[varFieldPos].set(conf, factory); } else { throw new ConfigurationParserException("Unknown implementation of ContainerFactory '" + words[1] + "'"); } } else if ( cpo.getDataType().compareTo("InterpolatorFactory") == 0) { if (words[1].startsWith("LinearInterpolatorFactory")) { LinearInterpolatorFactory<FloatType> factory = new LinearInterpolatorFactory<FloatType>( null ); factory.setParameters(words[1].substring(words[1].indexOf("("), words[1].length())); fields[varFieldPos].set(conf, factory); } else if (words[1].startsWith("NearestNeighborInterpolatorFactory")) { NearestNeighborInterpolatorFactory<FloatType> factory = new NearestNeighborInterpolatorFactory<FloatType>( null ); factory.setParameters(words[1].substring(words[1].indexOf("("), words[1].length())); fields[varFieldPos].set(conf, factory); } else { throw new ConfigurationParserException("Unknown implementation of FloatInterpolatorFactory '" + words[1] + "'"); } } else if ( cpo.getDataType().compareTo("OutsideStrategyFactory") == 0) { if (words[1].startsWith("OutsideStrategyMirrorFactory")) { OutOfBoundsStrategyFactory<FloatType> factory = new OutOfBoundsStrategyMirrorFactory<FloatType>(); factory.setParameters(words[1].substring(words[1].indexOf("("), words[1].length())); fields[varFieldPos].set(conf, factory); } else if (words[1].startsWith("OutsideStrategyValueFactory")) { OutOfBoundsStrategyFactory<FloatType> factory = new OutOfBoundsStrategyValueFactory<FloatType>(); factory.setParameters(words[1].substring(words[1].indexOf("("), words[1].length())); fields[varFieldPos].set(conf, factory); } else { throw new ConfigurationParserException("Unknown implementation of OutsideStrategyFactory '" + words[1] + "'"); } } else { throw new ConfigurationParserException("Unknown datatype '" + cpo.getDataType() + "'"); } } } } catch (Exception e) { throw new ConfigurationParserException("Error reading/parsing configuration file at line " + lineCount + ":\n" + e.getMessage()); } // variable specific verification if (conf.numberOfThreads < 1) conf.numberOfThreads = Threads.numThreads(); if (conf.scaleSpaceNumberOfThreads < 1) conf.scaleSpaceNumberOfThreads = Threads.numThreads(); // check the directory string conf.inputdirectory = conf.inputdirectory.replace('\\', '/'); conf.inputdirectory = conf.inputdirectory.trim(); if (conf.inputdirectory.length() > 0 && !conf.inputdirectory.endsWith("/")) conf.inputdirectory = conf.inputdirectory + "/"; if (conf.outputdirectory == null || conf.outputdirectory.length() == 0) { conf.outputdirectory = conf.inputdirectory; } else { conf.outputdirectory = conf.outputdirectory.replace('\\', '/'); conf.outputdirectory = conf.outputdirectory.trim(); if (conf.outputdirectory.length() > 0 && !conf.outputdirectory.endsWith("/")) conf.outputdirectory = conf.outputdirectory + "/"; } if (conf.registrationFiledirectory == null || conf.registrationFiledirectory.length() == 0) { conf.registrationFiledirectory = conf.inputdirectory; } else { conf.registrationFiledirectory = conf.registrationFiledirectory.replace('\\', '/'); conf.registrationFiledirectory = conf.registrationFiledirectory.trim(); if (conf.registrationFiledirectory.length() > 0 && !conf.registrationFiledirectory.endsWith("/")) conf.registrationFiledirectory = conf.registrationFiledirectory + "/"; } // check if directories exist testDirectories( conf ); int countTrue = 0; if (conf.paralellFusion) countTrue++; if (conf.sequentialFusion) countTrue++; if (conf.multipleImageFusion) countTrue++; if (countTrue != 1) throw new ConfigurationParserException("Error reading/parsing configuration file: Only one fusion method must be true!"); if ( conf.debugLevel.toUpperCase().equals("DEBUG_ERRORONLY")) conf.debugLevelInt = ViewStructure.DEBUG_ERRORONLY; if ( conf.debugLevel.toUpperCase().equals("DEBUG_MAIN")) conf.debugLevelInt = ViewStructure.DEBUG_MAIN; if ( conf.debugLevel.toUpperCase().equals("DEBUG_ALL")) conf.debugLevelInt = ViewStructure.DEBUG_ALL; // here all angles, timepoints and channels are parsed from the input strings conf.getFileNames(); // set interpolator stuff conf.interpolatorFactorOutput.setOutOfBoundsStrategyFactory( conf.strategyFactoryOutput ); // close files try { assignFile.close(); confFile.close(); } catch (Exception e) {}; return conf; } public static void testDirectories( final SPIMConfiguration conf ) throws ConfigurationParserException { File dir = new File(conf.outputdirectory, ""); if (!dir.exists()) { IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Creating directory '" + conf.outputdirectory + "'."); boolean success = dir.mkdirs(); if (!success) { if (!dir.exists()) { throw new ConfigurationParserException("(" + new Date(System.currentTimeMillis()) + "): Cannot create directory '" + conf.outputdirectory + "', quitting."); } } } dir = new File(conf.registrationFiledirectory, ""); if (!dir.exists()) { IOFunctions.println("(" + new Date(System.currentTimeMillis()) + "): Creating directory '" + conf.registrationFiledirectory + "'."); boolean success = dir.mkdirs(); if (!success) { if (!dir.exists()) { throw new ConfigurationParserException("(" + new Date(System.currentTimeMillis()) + "): Cannot create directory '" + conf.registrationFiledirectory + "', quitting."); } } } } private static int findEntry( final ArrayList<ConfigurationParserObject> list, final String entry ) { int pos = -1; for (int i = 0; i < list.size() && pos == -1; i++) { final ConfigurationParserObject cpo = list.get( i ); if ( cpo.getEntry().toLowerCase().compareTo( entry.toLowerCase() ) == 0 ) pos = i; } return pos; } private static String getAllEntries( final ArrayList<ConfigurationParserObject> list ) { String entries = ""; for( final ConfigurationParserObject cpo : list ) entries += cpo.getEntry() + "\n"; return entries; } }