mt.Tracking.java Source code

Java tutorial

Introduction

Here is the source code for mt.Tracking.java

Source

/*-
 * #%L
 * Microtubule tracker.
 * %%
 * Copyright (C) 2017 MTrack 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 3 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-3.0.html>.
 * #L%
 */
package mt;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Shape;
import java.io.BufferedReader;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

import net.imglib2.util.Pair;
import net.imglib2.util.ValuePair;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.util.ShapeUtils;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import fit.AbstractFunction2D;
import fit.PointFunctionMatch;
import fit.polynomial.LinearFunction;
import fit.polynomial.Polynomial;
import mpicbg.models.Point;

public class Tracking {

    public static ArrayList<FLSobject> loadMTStat(final File file) {
        final ArrayList<FLSobject> points = new ArrayList<FLSobject>();

        try {
            BufferedReader in = Util.openFileRead(file);

            while (in.ready()) {
                String line = in.readLine().trim();

                while (line.contains("\t\t"))
                    line = line.replaceAll("\t\t", "\t");

                if (line.length() >= 3 && line.matches("[0-9].*")) {
                    final String[] split = line.trim().split("\t");

                    final int frame = (int) Double.parseDouble(split[0]);
                    final double length = Double.parseDouble(split[2]);
                    final int seedID = (int) Double.parseDouble(split[3]);

                    FLSobject statobject = new FLSobject(frame, seedID, length);
                    points.add(statobject);
                }
            }
        } catch (Exception e) {

        }

        Collections.sort(points, new Comparator<FLSobject>() {
            @Override
            public int compare(final FLSobject o1, final FLSobject o2) {

                final int t1 = o1.Framenumber;
                final int t2 = o2.Framenumber;

                if (t1 < t2)
                    return -1;
                else if (t1 == t2)
                    return 0;
                else
                    return 1;
            }
        });

        if (points.size() > 0)
            return points;

        else
            return null;
    }

    public static double[] loadCalibration(final File file) {

        double[] calibrations = new double[3];
        double calibrationX = 1, calibrationY = 1, calibrationT = 1;
        try {
            BufferedReader in = Util.openFileRead(file);

            while (in.ready()) {
                String line = in.readLine().trim();

                while (line.contains("\t\t"))
                    line = line.replaceAll("\t\t", "\t");

                if (line.length() >= 3 && line.matches("[0-9].*")) {
                    final String[] split = line.trim().split("\t");

                    calibrationX = Double.parseDouble(split[10]);
                    calibrationY = Double.parseDouble(split[11]);
                    calibrationT = Double.parseDouble(split[12]);

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        calibrations[0] = calibrationX;
        calibrations[1] = calibrationY;
        calibrations[2] = calibrationT;

        return calibrations;
    }

    public static ArrayList<Pair<Integer, Double>> loadMT(final File file) {
        final ArrayList<Pair<Integer, Double>> points = new ArrayList<Pair<Integer, Double>>();

        try {
            BufferedReader in = Util.openFileRead(file);

            while (in.ready()) {
                String line = in.readLine().trim();

                while (line.contains("\t\t"))
                    line = line.replaceAll("\t\t", "\t");

                if (line.length() >= 3 && line.matches("[0-9].*")) {
                    final String[] split = line.trim().split("\t");

                    final int frame = (int) Double.parseDouble(split[0]);
                    final double length = Double.parseDouble(split[1]);

                    points.add(new ValuePair<Integer, Double>(frame, length));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        Collections.sort(points, new Comparator<Pair<Integer, Double>>() {
            @Override
            public int compare(final Pair<Integer, Double> o1, final Pair<Integer, Double> o2) {
                return o1.getA().compareTo(o2.getA());
            }
        });

        if (points.size() > 0)
            return points;

        else
            return null;
    }

    public static ArrayList<Pair<Integer, Double>> loadsimple(final File file) {
        final ArrayList<Pair<Integer, Double>> points = new ArrayList<Pair<Integer, Double>>();
        final ArrayList<Pair<Integer, Double>> normalpoints = new ArrayList<Pair<Integer, Double>>();
        try {
            BufferedReader in = Util.openFileRead(file);

            while (in.ready()) {
                String line = in.readLine().trim();

                while (line.contains("\t\t"))
                    line = line.replaceAll("\t\t", "\t");

                if (line.length() >= 3 && line.matches("[0-9].*")) {
                    final String[] split = line.trim().split("\t");

                    final int frame = (int) Double.parseDouble(split[0]);
                    final double length = Double.parseDouble(split[1]);

                    points.add(new ValuePair<Integer, Double>(frame, length));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        double maxlength = Double.MIN_VALUE;
        for (Pair<Integer, Double> point : points) {

            double length = point.getB();
            if (length > maxlength)
                maxlength = length;
        }
        for (Pair<Integer, Double> point : points) {
            Pair<Integer, Double> newpoint = new ValuePair<Integer, Double>(point.getA() / 10,
                    point.getB() / maxlength);
            normalpoints.add(newpoint);
        }

        return normalpoints;
    }

    public static XYSeries drawPoints(final List<Pair<Integer, Double>> mts, double[] calibrations) {
        return drawPoints(mts, calibrations, "MT Length");
    }

    public static XYSeries drawPoints(final List<Pair<Integer, Double>> mts, double[] calibrations,
            final String name) {
        XYSeries series = new XYSeries(name);

        if (mts != null) {
            for (final Pair<Integer, Double> mt : mts)
                series.add(mt.getA(), mt.getB());
        }
        return series;
    }

    public static XYSeries drawFunction(final Polynomial<?, Point> polynomial, final double from, final double to,
            final double step, final String name) {
        XYSeries series = new XYSeries(name);

        for (double x = from; x <= to; x = x + step)
            series.add(x, polynomial.predict(x));

        return series;
    }

    public static XYSeries drawFunction(final interpolation.Polynomial polynomial, final double from,
            final double to, final double step, final String name) {
        XYSeries series = new XYSeries(name);

        for (double x = from; x <= to; x = x + step)
            series.add(x, polynomial.predict(x));

        return series;
    }

    public static XYSeries drawexpFunction(final interpolation.Polynomial polynomial, final double from,
            final double to, final double step, final String name) {
        XYSeries series = new XYSeries(name);

        for (double x = from; x <= to; x = x + step)
            series.add(x, Math.exp(polynomial.predict(x)));

        return series;
    }

    public static XYSeries drawFunction(final Polynomial<?, Point> polynomial, final double from, final double to,
            final double step, final double minY, final double maxY, final String name) {
        XYSeries series = new XYSeries(name);

        for (double x = from; x <= to; x = x + step) {
            final double v = polynomial.predict(x);

            if (v >= minY && v <= maxY)
                series.add(x, v);
        }

        return series;
    }

    public static JFreeChart makeChart(final XYSeriesCollection dataset) {
        return makeChart(dataset, "XY Chart", "x-axis", "y-axis");
    }

    public static JFreeChart makeChart(final XYSeriesCollection dataset, final String title, final String x,
            final String y) {
        final JFreeChart chart = ChartFactory.createXYLineChart(title, x, y, dataset, PlotOrientation.VERTICAL,
                true, true, false);

        return chart;
    }

    public static void setColor(final JFreeChart chart, final int seriesIndex, final Color col) {
        final XYPlot plot = chart.getXYPlot();
        final XYItemRenderer renderer = plot.getRenderer();
        renderer.setSeriesPaint(seriesIndex, col);
    }

    public static void setStroke(final JFreeChart chart, final int seriesIndex, final float stroke) {
        final XYPlot plot = chart.getXYPlot();
        final XYItemRenderer renderer = plot.getRenderer();
        renderer.setSeriesStroke(seriesIndex, new BasicStroke(stroke));
    }

    public static void setShape(final JFreeChart chart, final int seriesIndex, final Shape shape) {
        final XYPlot plot = chart.getXYPlot();
        final XYItemRenderer renderer = plot.getRenderer();
        renderer.setSeriesShape(seriesIndex, shape);
    }

    public static void setSmallUpTriangleShape(final JFreeChart chart, final int seriesIndex) {
        final XYPlot plot = chart.getXYPlot();
        final XYItemRenderer renderer = plot.getRenderer();
        renderer.setSeriesShape(seriesIndex, ShapeUtils.createUpTriangle(0.5f));
    }

    public static void setDisplayType(final JFreeChart chart, final int seriesIndex, final boolean line,
            final boolean shape) {
        final XYPlot plot = chart.getXYPlot();
        final XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
        renderer.setSeriesLinesVisible(seriesIndex, line);
        renderer.setSeriesShapesVisible(seriesIndex, shape);
    }

    public static JFrame display(final JFreeChart chart) {
        return display(chart, new Dimension(800, 500));
    }

    public static JFrame display(final JFreeChart chart, final Dimension d) {
        final JPanel panel = new JPanel();
        final ChartPanel chartPanel = new ChartPanel(chart, d.width - 10, d.height - 35,
                ChartPanel.DEFAULT_MINIMUM_DRAW_WIDTH, ChartPanel.DEFAULT_MINIMUM_DRAW_HEIGHT,
                ChartPanel.DEFAULT_MAXIMUM_DRAW_WIDTH, ChartPanel.DEFAULT_MAXIMUM_DRAW_HEIGHT,
                ChartPanel.DEFAULT_BUFFER_USED, true, // properties
                true, // save
                true, // print
                true, // zoom
                true // tooltips
        );
        panel.add(chartPanel);

        final JFrame frame = new JFrame();
        frame.setContentPane(panel);
        frame.validate();
        frame.setSize(d);

        frame.setVisible(true);
        return frame;
    }

    public static ArrayList<Point> toPoints(final ArrayList<Pair<Integer, Double>> mts) {
        final ArrayList<Point> points = new ArrayList<Point>();

        for (final Pair<Integer, Double> mt : mts)
            points.add(new Point(new double[] { mt.getA(), mt.getB() }));

        return points;
    }

    public static ArrayList<Pair<Integer, Double>> toPairList(final ArrayList<PointFunctionMatch> points) {
        final ArrayList<Pair<Integer, Double>> mts = new ArrayList<Pair<Integer, Double>>();

        for (final PointFunctionMatch p : points)
            mts.add(new ValuePair<Integer, Double>((int) Math.round(p.getP1().getW()[0]), p.getP1().getW()[1]));

        return mts;
    }

    public static <P extends AbstractFunction2D<P>> Pair<P, ArrayList<PointFunctionMatch>> findFunction(
            final ArrayList<Point> mts, final P function) {
        return findFunction(mts, function, 3.0, function.getMinNumPoints(), 6);
    }

    @SuppressWarnings("deprecation")
    public static <P extends AbstractFunction2D<P>> Pair<P, ArrayList<PointFunctionMatch>> findFunction(
            final ArrayList<Point> mts, final P function, final double maxError, final int minNumInliers,
            final int maxDist) {
        final ArrayList<PointFunctionMatch> candidates = new ArrayList<PointFunctionMatch>();
        final ArrayList<PointFunctionMatch> inliers = new ArrayList<PointFunctionMatch>();

        for (final Point p : mts)
            candidates.add(new PointFunctionMatch(p));

        try {
            function.ransac(candidates, inliers, 100, maxError, 0, minNumInliers, maxDist);

            if (inliers != null) {

                if (inliers.size() >= function.getMinNumPoints()) {
                    function.fit(inliers);

                    //System.out.println( inliers.size() + "/" + candidates.size() );
                    //System.out.println( function );
                }

                else {
                    //System.out.println( "0/" + candidates.size() );
                    return null;
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            return null;
        }

        return new ValuePair<P, ArrayList<PointFunctionMatch>>(function, inliers);
    }

    /*
     *          if ( LinearFunction.slopeFits( result.getB(), linear, minSlope, maxSlope ) )
     */
    public static <P extends AbstractFunction2D<P>> ArrayList<Pair<P, ArrayList<PointFunctionMatch>>> findAllFunctions(
            final ArrayList<Point> mts, final P function, final double maxError, final int minNumInliers,
            final int maxDist) {
        boolean fitted;

        final ArrayList<Point> remainingPoints = new ArrayList<Point>();
        if (mts != null) {
            remainingPoints.addAll(mts);

            final ArrayList<Pair<P, ArrayList<PointFunctionMatch>>> segments = new ArrayList<Pair<P, ArrayList<PointFunctionMatch>>>();

            do {
                fitted = false;

                final Pair<P, ArrayList<PointFunctionMatch>> f = findFunction(remainingPoints, function.copy(),
                        maxError, minNumInliers, maxDist);

                if (f != null && f.getB().size() > 0) {
                    fitted = true;
                    segments.add(f);

                    final ArrayList<Point> inlierPoints = new ArrayList<Point>();
                    for (final PointFunctionMatch p : f.getB())
                        inlierPoints.add(p.getP1());

                    remainingPoints.removeAll(inlierPoints);
                }
            }

            while (fitted);

            return segments;
        }

        else
            return null;
    }

    public static Pair<LinearFunction, ArrayList<PointFunctionMatch>> findLinearFunction(final ArrayList<Point> mts,
            final double maxError, final int minNumInliers, final int maxDist, final double minSlope,
            final double maxSlope) {
        final ArrayList<PointFunctionMatch> candidates = new ArrayList<PointFunctionMatch>();
        final ArrayList<PointFunctionMatch> inliers = new ArrayList<PointFunctionMatch>();

        for (final Point p : mts)
            candidates.add(new PointFunctionMatch(p));

        final LinearFunction function = new LinearFunction();

        try {
            function.ransac(candidates, inliers, 1000, maxError, 0, minNumInliers, maxDist, minSlope, maxSlope);

            if (inliers.size() >= function.getMinNumPoints()) {
                function.fit(inliers);

                System.out.println(inliers.size() + "/" + candidates.size());
                System.out.println(function);
            } else {
                System.out.println("0/" + candidates.size());
                return null;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }

        return new ValuePair<LinearFunction, ArrayList<PointFunctionMatch>>(function, inliers);
    }

    @SuppressWarnings("deprecation")
    public static <P extends AbstractFunction2D<P>> Pair<P, ArrayList<PointFunctionMatch>> findFunction(
            final ArrayList<Point> mts, final P function, final double maxError, final int minNumInliers,
            final double maxDist) {
        final ArrayList<PointFunctionMatch> candidates = new ArrayList<PointFunctionMatch>();
        final ArrayList<PointFunctionMatch> inliers = new ArrayList<PointFunctionMatch>();

        for (final Point p : mts)
            candidates.add(new PointFunctionMatch(p));

        try {
            function.ransac(candidates, inliers, 100, maxError, 0.01, minNumInliers, maxDist);

            if (inliers.size() >= function.getMinNumPoints()) {
                function.fit(inliers);

                //System.out.println( inliers.size() + "/" + candidates.size() );
                //System.out.println( function );
            } else {

                //System.out.println( "0/" + candidates.size() );
                return null;
            }
        } catch (Exception e) {
            System.out.println("Couldn't fit function: " + e);
            // TODO Auto-generated catch block
            //e.printStackTrace();
            return null;
        }

        return new ValuePair<P, ArrayList<PointFunctionMatch>>(function, inliers);
    }

    public static Pair<Double, Double> fromTo(final ArrayList<PointFunctionMatch> points) {
        double min = points.get(0).getP1().getW()[0];
        double max = min;

        for (final PointFunctionMatch p : points) {
            final double value = p.getP1().getW()[0];
            min = Math.min(min, value);
            max = Math.max(max, value);
        }

        return new ValuePair<Double, Double>(min, max);
    }

    public static Pair<Double, Double> fromToY(final ArrayList<PointFunctionMatch> points) {
        double min = points.get(1).getP1().getW()[1];
        double max = min;

        for (final PointFunctionMatch p : points) {
            final double value = p.getP1().getW()[1];
            min = Math.min(min, value);
            max = Math.max(max, value);
        }

        return new ValuePair<Double, Double>(min, max);
    }

}