package edu.stanford.rsl.conrad.reconstruction.voi;
import java.awt.Polygon;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import edu.stanford.rsl.conrad.io.ConfigFileParser;
import edu.stanford.rsl.conrad.io.SafeSerializable;
/**
* VOI based on a polygon definition which is identical for each slice. The VOI is than formed as a stack of identical polygons. Note that this method is sub-optimal for clipping as either the VOI has to be pre-computed for the whole volume or clipped against a polygon in each call of contains().
* @author akmaier
*
*/
public class PolygonBasedVolumeOfInterest extends VolumeOfInterest implements ConfigFileParser, SafeSerializable {
/**
*
*/
private static final long serialVersionUID = -8511498569857161802L;
Polygon sliceRegionOfInterest;
double maxZ, minZ;
int numberOfPointsInPolygon;
private boolean success = false;
private HashMap<Double, Boolean> sliceVoi = new HashMap<Double, Boolean>();
public PolygonBasedVolumeOfInterest(){
}
public PolygonBasedVolumeOfInterest(String maxVOIFileName) throws IOException{
readConfigFile(maxVOIFileName);
}
public boolean contains (double x, double y, double z){
if (debug) System.out.println("Voxel " + x + " " + y + " " + z);
boolean revan = true;
if ((z < minZ)||(z > maxZ)){
revan = false;
if (debug) System.out.println("z out of Range: " + z);
if (debug) System.out.println("Z-Range " + minZ + " " + maxZ);
} else {
Double location = new Double (x *1000 +y);
if (! sliceVoi.containsKey(location)) {
if (!(sliceRegionOfInterest.contains(x, y))){
revan = false;
if (debug) System.out.println("Not in polygon");
}
sliceVoi.put(location, new Boolean(revan));
} else {
revan = sliceVoi.get(location);
}
}
return revan;
}
public void readConfigFile(String filename) throws IOException {
FileReader read = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(read);
String line = "";
//skip four lines
line = bufferedReader.readLine();
if (line.contains("version 2")){
line = bufferedReader.readLine();
line = bufferedReader.readLine();
line = bufferedReader.readLine();
if (debug) System.out.println(line);
String [] entries = line.split("\\s+");
minZ = Double.parseDouble(entries[1]);
maxZ = Double.parseDouble(entries[2]);
if (debug) System.out.println("Z-Range " + minZ + " " + maxZ);
line = bufferedReader.readLine();
if (debug) System.out.println(line);
entries = line.split("\\s+");
numberOfPointsInPolygon = Integer.parseInt(entries[1]);
int [] xvals = new int[numberOfPointsInPolygon];
int [] yvals = new int[numberOfPointsInPolygon];
for (int i=0; i < numberOfPointsInPolygon; i++){
line = bufferedReader.readLine();
entries = line.split("\\s+");
xvals[i] = (int) Math.round(Double.parseDouble(entries[1]));
yvals[i] = (int) Math.round(Double.parseDouble(entries[2]));
if (debug) System.out.println(line);
}
sliceRegionOfInterest = new Polygon(xvals, yvals, numberOfPointsInPolygon);
success = true;
} else {
throw new IOException("File is not in version 2 format.");
}
bufferedReader.close();
}
public boolean getSuccess() {
return success;
}
public void prepareForSerialization() {
sliceVoi = new HashMap<Double, Boolean>();
}
}
/*
* Copyright (C) 2010-2014 Andreas Maier
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/