package etomica.normalmode;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;


/** 
 * Reads in lots of 2D arrays from a file.  Returns a 3D array with each n rows of
 * of the file corresponding to one (top-level) element (a 2D array).
 * @author Andrew Schultz
 */
public class ArrayReader2D {
    
    /**
     * Returns 2D arrays from the given file.  The arrays are assumed to be
     * square.
     */
    public static double[][][] getFromFile(String fn){
        return getFromFile(fn, 0);
    }

    /**
     * Returns 2D arrays from the given file.  The arrays are rows x columns,
     * where the rows are given and columns is taken as the actual number of
     * columns in the file.
     */
    public static double[][][] getFromFile(String fn, int rows){
        FileReader fileReaderS;
        try {
            fileReaderS = new FileReader(fn);
        }catch(IOException e) {
            throw new RuntimeException("Cannot open "+fn+", caught IOException: " + e.getMessage());
        }
        double[][][] S = null;
        try {
            BufferedReader bufReaderS = new BufferedReader(fileReaderS);
            String line = bufReaderS.readLine();
            ArrayList allS = new ArrayList();
            int dim = 0;
            while (line != null) {
                String[] valueStrings = line.split(" +");
                if (dim == 0) {
                    dim = valueStrings.length;
                    if (rows == 0) {
                        rows = dim;
                    }
                }
                else if (valueStrings.length != dim) {
                    throw new RuntimeException("Not enough data on line "+allS.size()*rows+" of "+fn);
                }
                double[][] thisS = new double[rows][dim];
                for (int i=0; i<rows; i++) {
                    if (i>0) line = bufReaderS.readLine();
                    valueStrings = line.split(" +");
                    for (int j=0; j<dim; j++) {
                        thisS[i][j] = Double.parseDouble(valueStrings[j]);
                    }
                }
                allS.add(thisS);
                line = bufReaderS.readLine();
            }
            S = new double[allS.size()][][];
            for (int i=0; i<S.length; i++) {
                S[i] = ((double[][])allS.get(i));
            }
        }
        catch (IOException e) {
            throw new RuntimeException("Couldn't read data from file "+fn);
        }
        return S;
    }
}

@@ -45,32 +45,64 @@
 BufferedReader;%0A
+import java.io.FileInputStream;%0A
 import java.io.F
@@ -140,16 +140,50 @@
 eption;%0A
+import java.io.ObjectInputStream;%0A
 import j
@@ -528,71 +528,291 @@
 are.
-%0A     */%0A    public static double%5B%5D%5B%5D%5B%5D getFromFile(String fn)%7B
+  If the given filename is of the form something.bin, it is%0A     * assume to be in binary format (serialized) and will be deserialized.%0A     */%0A    public static double%5B%5D%5B%5D%5B%5D getFromFile(String fn)%7B%0A        if (fn.matches(%22.*.bin%22)) %7B%0A            return getFromBinFile(fn);%0A        %7D
 %0A   
@@ -2824,11 +2824,606 @@
 S;%0A    %7D
+%0A%0A    /**%0A     * Deserializes a 3D array from the given file.%0A     */%0A    public static double%5B%5D%5B%5D%5B%5D getFromBinFile(String fn)%7B%0A        try %7B%0A            FileInputStream fis = new FileInputStream(fn);%0A            ObjectInputStream in = new ObjectInputStream(fis);%0A            double%5B%5D%5B%5D%5B%5D bar = (double%5B%5D%5B%5D%5B%5D)in.readObject();%0A            in.close();%0A            fis.close();%0A            return bar;%0A        %7D%0A        catch (IOException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A        catch (ClassNotFoundException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A    %7D
 %0A%7D%0A

add support for deserialization