package gdsc.foci;
/*-----------------------------------------------------------------------------
* GDSC Plugins for ImageJ
*
* Copyright (C) 2011 Alex Herbert
* Genome Damage and Stability Centre
* University of Sussex, UK
*
* 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.
*---------------------------------------------------------------------------*/
import ij.gui.PointRoi;
import ij.gui.PolygonRoi;
import ij.gui.Roi;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import gdsc.core.match.Coordinate;
/**
* Manages I/O of the Point class
*/
public class PointManager
{
public static final String newline = System.getProperty("line.separator");
/**
* Save the predicted points to the given file
*
* @param points
* @param filename
* @throws IOException
*/
public static void savePoints(AssignedPoint[] points, String filename) throws IOException
{
if (points == null)
return;
OutputStreamWriter out = null;
try
{
File file = new File(filename);
if (!file.exists())
{
if (file.getParent() != null)
new File(file.getParent()).mkdirs();
}
// Save results to file
FileOutputStream fos = new FileOutputStream(filename);
out = new OutputStreamWriter(fos);
StringBuilder sb = new StringBuilder();
out.write("X,Y,Z" + newline);
// Output all results in ascending rank order
for (AssignedPoint point : points)
{
sb.append(point.getX()).append(',');
sb.append(point.getY()).append(',');
sb.append(point.getZ()).append(newline);
out.write(sb.toString());
sb.setLength(0);
}
}
finally
{
try
{
if (out != null)
out.close();
}
catch (IOException e)
{
}
}
}
/**
* Loads the points from the file
*
* @param filename
* @return
* @throws IOException
*/
public static AssignedPoint[] loadPoints(String filename) throws IOException
{
LinkedList<AssignedPoint> points = new LinkedList<AssignedPoint>();
BufferedReader input = null;
try
{
// Load results from file
input = new BufferedReader(new FileReader(filename));
String line = input.readLine();
if (line != null)
{
int lineCount = 1;
while ((line = input.readLine()) != null)
{
lineCount++;
String[] tokens = line.split(",");
if (tokens.length == 3)
{
try
{
int x = Integer.parseInt(tokens[0]);
int y = Integer.parseInt(tokens[1]);
int z = Integer.parseInt(tokens[2]);
points.add(new AssignedPoint(x, y, z, lineCount - 1));
}
catch (NumberFormatException e)
{
System.err.println("Invalid numbers on line: " + lineCount);
}
}
}
}
return points.toArray(new AssignedPoint[0]);
}
finally
{
try
{
if (input != null)
input.close();
}
catch (IOException e)
{
}
}
}
/**
* Extracts the points from the given Point ROI
*
* @param roi
* @return The list of points (can be zero length)
*/
public static AssignedPoint[] extractRoiPoints(Roi roi)
{
AssignedPoint[] roiPoints = null;
if (roi != null && roi.getType() == Roi.POINT)
{
Polygon p = ((PolygonRoi) roi).getNonSplineCoordinates();
int n = p.npoints;
Rectangle bounds = roi.getBounds();
// The ROI has either a hyperstack position or a stack position, but not both.
// Both will be zero if the ROI has no 3D information.
int z = roi.getZPosition();
if (z == 0)
z = roi.getPosition();
roiPoints = new AssignedPoint[n];
for (int i = 0; i < n; i++)
{
roiPoints[i] = new AssignedPoint(bounds.x + p.xpoints[i], bounds.y + p.ypoints[i], z, i);
}
}
else
{
roiPoints = new AssignedPoint[0];
}
return roiPoints;
}
/**
* Creates an ImageJ PointRoi from the list of points
*
* @param array
* List of points
* @return The PointRoi
*/
public static Roi createROI(List<? extends Coordinate> array)
{
int nMaxima = array.size();
float[] xpoints = new float[nMaxima];
float[] ypoints = new float[nMaxima];
int i = 0;
for (Coordinate point : array)
{
xpoints[i] = point.getX();
ypoints[i] = point.getY();
i++;
}
return new PointRoi(xpoints, ypoints, nMaxima);
}
/**
* Creates an ImageJ PointRoi from the list of points
*
* @param array
* List of points
* @return The PointRoi
*/
public static Roi createROI(AssignedPoint[] array)
{
int nMaxima = array.length;
float[] xpoints = new float[nMaxima];
float[] ypoints = new float[nMaxima];
for (int i = 0; i < nMaxima; i++)
{
xpoints[i] = array[i].getX();
ypoints[i] = array[i].getY();
}
return new PointRoi(xpoints, ypoints, nMaxima);
}
/**
* Eliminates duplicate coordinates. Destructively alters the IDs in the input array since the objects are recycled
*
* @param points
* @return new list of points with Ids from zero
*/
public static AssignedPoint[] eliminateDuplicates(AssignedPoint[] points)
{
HashSet<AssignedPoint> newPoints = new HashSet<AssignedPoint>();
int id = 0;
for (AssignedPoint p : points)
{
if (newPoints.add(p))
p.setId(id++);
}
return newPoints.toArray(new AssignedPoint[0]);
}
}