package nl.fifth.postulate.bin;

import nom.tam.fits.BinaryTableHDU;
import nom.tam.fits.Fits;
import nom.tam.fits.FitsException;

import java.io.*;

public class AverageWithSmoothing {
    public static void main(String[] args) throws FitsException, IOException {
        String filename = args[0];
        String pathName = args[1];
        float alpha = Float.valueOf(args[2]);

        AverageDataPoint[] average = calculateAverage(filename, alpha);

        PrintStream output = new PrintStream(new FileOutputStream(pathName));
        for (int index = 0, limit = average.length; index < limit; index++) {
            output.printf("%4d, %s\n", index, average[index]);
        }

    }

    private static AverageDataPoint[] calculateAverage(String filename, float alpha) throws FitsException, IOException {
        Fits f = new Fits(filename);
        BinaryTableHDU hdu = (BinaryTableHDU) f.getHDU(1);
        double[] timeRows = (double[]) hdu.getColumn("TIME");
        float[][][] fluxRows = (float[][][]) hdu.getColumn("FLUX");

        AverageDataPoint[] averageDataPoint = new AverageDataPoint[fluxRows.length];
        float smoothed = 0.0f;
        for (int row = 0, rowLimit = fluxRows.length; row < rowLimit; row++ ) {
            float sum = 0.0f;
            int count = 0;
            float[][] inputImage = fluxRows[row];
            for (int y = 0, ylimit = inputImage.length; y < ylimit; y++) {
                for (int x = 0, xlimit = inputImage[0].length; x < xlimit; x++) {
                    sum += inputImage[y][x];
                    count += 1;
                }
            }
            float average = sum / count;

            if (row != 0) {
                smoothed = alpha * average + (1 - alpha) * smoothed;
            } else {
                smoothed = average;
            }

            averageDataPoint[row] = new AverageDataPoint(timeRows[row], average, smoothed, average - smoothed);
        }

        return averageDataPoint;
    }
}

class AverageDataPoint {
    private final double time;
    private final float average;
    private final float smoothed;
    private final float detrended;

    public AverageDataPoint(double time, float average, float smoothed, float detrended) {
        this.time = time;
        this.average = average;
        this.smoothed = smoothed;
        this.detrended = detrended;
    }

    public String toString() {
        return String.format("%10.6f, %10.6f, %10.6f, %10.6f", time, average, smoothed, detrended);
    }
}
@@ -141,16 +141,94 @@
 va.io.*;
+%0Aimport java.util.ArrayList;%0Aimport java.util.Iterator;%0Aimport java.util.List;
 %0A%0Apublic
@@ -453,39 +453,32 @@
 s%5B2%5D);%0A%0A        
-Average
 DataPoint%5B%5D aver
@@ -462,34 +462,42 @@
        DataPoint
-%5B%5D
+Collection
  average = calcu
@@ -609,29 +609,24 @@
 ));%0A        
-for (
 int index = 
@@ -630,56 +630,59 @@
  = 0
-, limit = average.length; index %3C limit; index++
+;%0A        for (AverageDataPoint dataPoint : average
 ) %7B%0A
@@ -729,24 +729,21 @@
 ndex
-, average%5Bindex%5D
+++, dataPoint
 );%0A 
@@ -778,23 +778,16 @@
  static 
-Average
 DataPoin
@@ -787,18 +787,26 @@
 ataPoint
-%5B%5D
+Collection
  calcula
@@ -1116,23 +1116,16 @@
         
-Average
 DataPoin
@@ -1129,67 +1129,66 @@
 oint
-%5B%5D averageDataPoint = new AverageDataPoint%5BfluxRows.length%5D
+Collection dataPointCollection = new DataPointCollection()
 ;%0A  
@@ -1896,32 +1896,32 @@
     
-averageDataPoint%5Brow%5D = 
+dataPointCollection.add(
 new 
@@ -1990,16 +1990,17 @@
 moothed)
+)
 ;%0A      
@@ -2023,24 +2023,27 @@
 urn 
-averageDataPoint
+dataPointCollection
 ;%0A  
@@ -2564,16 +2564,376 @@
 rended);%0A    %7D%0A%7D
+%0A%0Aclass DataPointCollection implements Iterable%3CAverageDataPoint%3E %7B%0A    private final List%3CAverageDataPoint%3E dataPoints = new ArrayList%3CAverageDataPoint%3E();%0A%0A    public void add(AverageDataPoint dataPoint)%7B%0A        dataPoints.add(dataPoint);%0A    %7D%0A%0A%0A    @Override%0A    public Iterator%3CAverageDataPoint%3E iterator() %7B%0A        return dataPoints.iterator();%0A    %7D%0A%7D

Create a collection of AverageDataPoints