@@ -0,0 +1,2173 @@
+package nl.fifth.postulate.circuit.pipe;%0A%0Aimport nl.fifth.postulate.circuit.ChainingPipe;%0Aimport nl.fifth.postulate.circuit.TrappistData;%0A%0Apublic class MADFilter extends ChainingPipe %7B%0A    public static MADFilter madFilter(int window) %7B%0A        return new MADFilter(window);%0A    %7D%0A    public static final String COLUMN_NAME = %22MADFILTER%22;%0A    private final int window;%0A%0A    public MADFilter(int window) %7B%0A        super(COLUMN_NAME);%0A        this.window = window;%0A    %7D%0A%0A    @Override%0A    public Object calculate(TrappistData trappistData) %7B%0A        float%5B%5D data = (float%5B%5D) trappistData.dataFor(FFTFilter.COLUMN_NAME);%0A%0A        MADCollector collector = new MADCollector(window, data);%0A%0A        return collector.result();%0A    %7D%0A%7D%0A%0Aclass MADCollector %7B%0A    private final float%5B%5D data;%0A    private final int window;%0A    private final Median median;%0A%0A    public MADCollector(int window, float%5B%5D data) %7B%0A        this.window = window;%0A        this.data = data;%0A        this.median = new Median();%0A    %7D%0A%0A    public float%5B%5D result() %7B%0A        float%5B%5D result = new float%5Bdata.length%5D;%0A%0A        for (int row = 0, limit = data.length; row %3C limit; row++) %7B%0A            result%5Brow%5D = MADaround(row);%0A        %7D%0A%0A        return result;%0A    %7D%0A%0A    private float MADaround(int row) %7B%0A        float%5B%5D windowedData = windowedDataAroun(row);%0A        float globalMedian = median.of(windowedData);%0A        for (int index = 0, limit = windowedData.length; index %3C limit; index++) %7B%0A            windowedData%5Bindex%5D = java.lang.Math.abs(windowedData%5Bindex%5D - globalMedian);%0A        %7D%0A        return median.of(windowedData);%0A    %7D%0A%0A    private float%5B%5D windowedDataAroun(int row) %7B%0A        float%5B%5D data = new float%5Bwindow%5D;%0A%0A        for (int index = 0, offset = window/2; index %3C window; index++) %7B%0A            int rowIndex = rowIndex(index, offset);%0A            data%5Bindex%5D = data%5BrowIndex%5D;%0A        %7D%0A        return data;%0A    %7D%0A%0A    private int rowIndex(int index, int offset) %7B%0A        int rowIndex = index - offset;%0A        if (rowIndex %3C 0) %7B%0A            return 0;%0A        %7D%0A        if (rowIndex %3E= data.length) %7B%0A            return data.length - 1;%0A        %7D%0A        return rowIndex;%0A    %7D%0A%0A%7D

Create a MADFilter