CDMS/src/CDMS/kscheck
diff -u -r1.1 -r1.2
--- CreateRoadMapFile.java 13 Dec 2010 22:17:50 -0000 1.1
+++ CreateRoadMapFile.java 22 Jan 2011 19:08:28 -0000 1.2
@@ -1,229 +1,325 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
-package CDMS.kscheck;
-
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.StreamTokenizer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Formatter;
-//import hep.physics.matrix.Matrix;
-//import hep.physics.matrix.BasicMatrix;
-//import hep.physics.matrix.MatrixOp;
-
-/**
- *
- * @author kschneck
- * Creates auto-run file that takes high-res pictures of each TES
- *
- * @param file of TES coordinates (assumes the coordinates are sorted),
- * size of pixels (depends on magnification) in mm
- * @return file with OGP commands that drive along TES lines taking pictures
- *
- */
-public class CreateRoadMapFile {
-
- public List<Double[]> _coordinates;
-// public BasicMatrix XcoordsMatrix;
-// public BasicMatrix YcoordsVector;
-// public BasicMatrix functionVector;
-
- public CreateRoadMapFile(String inputCoordsFile, String outputOGPscript, double pixelSize) throws FileNotFoundException, IOException {
-
- FileReader fr = new FileReader(inputCoordsFile);
- StreamTokenizer tok = new StreamTokenizer(fr);
- tok.resetSyntax();
- tok.wordChars(33, 126);
- tok.parseNumbers();
- tok.whitespaceChars(0, 32);
- tok.eolIsSignificant(true);
-
- FileWriter fw = new FileWriter(outputOGPscript);
- BufferedWriter output = new BufferedWriter(fw);
-
- _coordinates = new ArrayList<Double[]>();
-
- double TESlength = 0.7; //length in mm
- double TESwidth = 0.22; //width in mm
- double xDim = (640)*pixelSize; //number of pixels in horizontal direction = 640
- double yDim = (480)*pixelSize; //number of pixels in vertical direction = 480
-
-
- // Loop over the input coordinate file entries
- while (true) {
- List<Double> args = getNumbersInLine(tok);
-
- //break out of loop if there are no more coords to add
- if (args.isEmpty()){
- break;
- }
-
- Double xcoord = args.get(0);
- Double ycoord = args.get(1);
- Double angle = args.get(2);
- Double TEStype = args.get(3);
-
- //add all coordinates to _coordinates ArrayList
- Double pos[] = {xcoord, ycoord, angle, TEStype};
- _coordinates.add(pos);
-
- }
-
- int ncoords = _coordinates.size();
-
- output.write("BEGIN_RUN\n");
- output.write("MM\n");
- output.write("SET_DATUM\n");
- output.write("c:\\Partrtn\\IZipDatum_PeaceSide1_x2.RTN\n");
-
- for(int i = 0; i<ncoords; i++){
- Double [] coords1 = _coordinates.get(i);
-
- Double x1 = 0.001*coords1[0]; //coords are given in um, OGP routine needs them in mm
- Double y1 = 0.001*coords1[1];
- Double angle1 = coords1[2];
-
- double length_x = Math.abs(TESlength*Math.cos(angle1))+Math.abs(TESwidth*Math.sin(angle1));
- double length_y = Math.abs(TESlength*Math.sin(angle1))+Math.abs(TESwidth*Math.cos(angle1));
-
- //take m by n array of pictures to cover entire TES
-
- //find m (horizontal number of pics) and n (vertical number of pics)
- int m = (int) Math.ceil(length_x/xDim);
- int n = (int) Math.ceil(length_y/yDim);
-
- //write proper commands to output autorun file
- for(int j = 0; j < m; j++){
- for(int k = 0; k < n; k++){
- Formatter fmt1 = new Formatter();
- Formatter fmt2 = new Formatter();
- fmt1.format("%.6f", x1-(0.5*(m-1))*xDim+j*xDim);
- fmt2.format("%.6f", y1-(0.5*(n-1))*yDim+k*yDim);
- output.write("c:\\Partrtn\\IZipOriginTakePicture_x2.RTN,"+fmt1+","+fmt2+",0,0,0,0\n");
-
- }
-
- }
-
- //find cubic function that fits the wiring between adjacent TESs
- //Do this by solving system of linear equations for (A,B,C,D):
- //row 1: A*x1^3 + B*x1^2 + C*x1 + D == y1
- //row 2: A*x2^3 + B*x2^2 + C*x2 + D == y2
- //row 3: derivative of LHS of row 1 wrt x1 == tan(angle1) (=slope at x1)
- //row 4: derivative of LHS of row 2 wrt x2 == tan(angle2) (=slope at x2)
- //It turns out that this method for taking pictures of the wiring between TESs
- // is redundant at the resolutions we're working with--everything is covered by
- // the m by n array of the above code. I'm commenting this section out but
- // leaving it here in case it ever becomes needed.
-
- //It should be noted that this method is not completely accurate for large angles
- // between the TESs--theta ~ pi/2 or so.
-
- //don't do this for the last coord in the file--there's nothing after it!
-// if(i != ncoords-1){
-//
-// Double [] coords2 = _coordinates.get(i+1);
-//
-// Double x2 = 0.001*coords2[0];
-// Double y2 = 0.001*coords2[1];
-// Double angle2 = coords2[2];
-//
-// XcoordsMatrix = new BasicMatrix(4,4);
-// YcoordsVector = new BasicMatrix(4,1);
-// functionVector = new BasicMatrix(4,1);
-//
-// //create XcoordsMatrix
-// XcoordsMatrix.setElement(0, 0, Math.pow(x1,3));
-// XcoordsMatrix.setElement(0, 1, Math.pow(x1,2));
-// XcoordsMatrix.setElement(0, 2, x1);
-// XcoordsMatrix.setElement(0, 3, 1);
-// XcoordsMatrix.setElement(1, 0, Math.pow(x2,3));
-// XcoordsMatrix.setElement(1, 1, Math.pow(x2,2));
-// XcoordsMatrix.setElement(1, 2, x2);
-// XcoordsMatrix.setElement(1, 3, 1);
-// XcoordsMatrix.setElement(2, 0, 3*Math.pow(x1,2));
-// XcoordsMatrix.setElement(2, 1, 2*x1);
-// XcoordsMatrix.setElement(2, 2, 1);
-// XcoordsMatrix.setElement(2, 3, 0);
-// XcoordsMatrix.setElement(3, 0, 3*Math.pow(x2,2));
-// XcoordsMatrix.setElement(3, 1, 2*x2);
-// XcoordsMatrix.setElement(3, 2, 1);
-// XcoordsMatrix.setElement(3, 3, 0);
-//
-// YcoordsVector.setElement(0,0, y1);
-// YcoordsVector.setElement(1,0, y2);
-// YcoordsVector.setElement(2,0, Math.tan(angle1));
-// YcoordsVector.setElement(3,0, Math.tan(angle2));
-//
-// Matrix inverse = MatrixOp.inverse(XcoordsMatrix);
-//
-// //find A,B,C,D by inverting XcoordsMatrix
-// Matrix paramVector = MatrixOp.mult(inverse,YcoordsVector);
-//
-// double A = paramVector.e(0,0);
-// double B = paramVector.e(1,0);
-// double C = paramVector.e(2,0);
-// double D = paramVector.e(3,0);
-//
-// //choose some x between x1 and x2, then calculate y using paramVector
-// if(x1 != x2){
-// Formatter fmt1 = new Formatter();
-// Formatter fmt2 = new Formatter();
-// double xavg = (x1+x2)/2;
-// double yvalue = A*Math.pow(xavg,3)+B*Math.pow(xavg,2)+C*xavg+D;
-// fmt1.format("%.6f", xavg);
-// fmt2.format("%.6f", yvalue);
-// output.write("c:\\Partrtn\\IZipOriginTakePicture_x2.RTN,"+fmt1+","+fmt2+",0,0,0,0\n");
-//
-// }
-// else{ //there might be a problem for x1 = x2, so try this
-// Formatter fmt = new Formatter();
-// double yavg = (y1+y2);
-// fmt.format("%.6f", yavg);
-// output.write("c:\\Partrtn\\IZipOriginTakePicture_x2.RTN,"+x1+","+fmt+",0,0,0,0\n");
-//
-// }
-//
-// }
-
- }
-
- output.write("END_RUN\n");
-
- output.close();
- }
-
-
- /**
- * Get a list of numbers in a line on the input stream
- *
- * @param tok StreamTokenizer with the next token being the first number
- * @return List of numbers in the current line
- * @throws IOException
- */
- private List<Double> getNumbersInLine(StreamTokenizer tok) throws IOException {
-
- // Create a list of numbers that the tokenizer finds
- List<Double> nums = new ArrayList<Double>();
-
- // Loop looking for either end of line or end of file
- while (tok.nextToken() != StreamTokenizer.TT_EOF) {
- if (tok.ttype == StreamTokenizer.TT_EOL) break;
-
- // Check to make sure that we have a numeric token
- if (tok.ttype != StreamTokenizer.TT_NUMBER) continue;
-
- // Found a number token - add it to the list
- nums.add(tok.nval);
-
- }
- return nums;
- }
-}
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package CDMS.kscheck;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.StreamTokenizer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Formatter;
+//import hep.physics.matrix.Matrix;
+//import hep.physics.matrix.BasicMatrix;
+//import hep.physics.matrix.MatrixOp;
+
+/**
+ *
+ * @author kschneck
+ * Creates auto-run file that takes high-res pictures of each TES
+ *
+ * @param file of TES coordinates (assumes the coordinates are sorted),
+ * size of pixels (depends on magnification) in mm
+ * @return file with OGP commands that drive along TES lines taking pictures
+ *
+ */
+public class CreateRoadMapFile {
+
+ public List<Double[]> _coordinates;
+// public BasicMatrix XcoordsMatrix;
+// public BasicMatrix YcoordsVector;
+// public BasicMatrix functionVector;
+
+ public CreateRoadMapFile(String inputCoordsFile, String outputOGPscript, double pixelSize) throws FileNotFoundException, IOException {
+
+ FileReader fr = new FileReader(inputCoordsFile);
+ StreamTokenizer tok = new StreamTokenizer(fr);
+ tok.resetSyntax();
+ tok.wordChars(33, 126);
+ tok.parseNumbers();
+ tok.whitespaceChars(0, 32);
+ tok.eolIsSignificant(true);
+
+ FileWriter fw = new FileWriter(outputOGPscript);
+ BufferedWriter output = new BufferedWriter(fw);
+
+ _coordinates = new ArrayList<Double[]>();
+
+ double TESlength = 0.7; //length in mm
+ double TESwidth = 0.22; //width in mm
+ double xDim = (620)*pixelSize; //number of pixels in horizontal direction = 640 add overlap explicitly here: 620/460
+ double yDim = (460)*pixelSize; //number of pixels in vertical direction = 480
+
+
+ // Loop over the input coordinate file entries
+ while (true) {
+ List<Double> args = getNumbersInLine(tok);
+
+ //break out of loop if there are no more coords to add
+ if (args.isEmpty()){
+ break;
+ }
+
+ Double xcoord = args.get(0);
+ Double ycoord = args.get(1);
+ Double angle = args.get(2);
+ Double TEStype = args.get(3);
+
+ //add all coordinates to _coordinates ArrayList
+ Double pos[] = {xcoord, ycoord, angle, TEStype};
+ _coordinates.add(pos);
+
+ }
+
+ int ncoords = _coordinates.size();
+
+ output.write("BEGIN_RUN\n");
+ output.write("MM\n");
+ output.write("SET_DATUM\n");
+ output.write("c:\\Partrtn\\IZipDatum_PeaceSide1_x2_5.RTN\n");
+
+ for(int i = 0; i<ncoords; i++){
+ Double [] coords1 = _coordinates.get(i);
+
+ Double x1 = 0.001*coords1[0]; //coords are given in um, OGP routine needs them in mm
+ Double y1 = 0.001*coords1[1];
+ Double angle1 = coords1[2];
+
+ //lengths in mm
+ double length_x = Math.abs(TESlength*Math.cos(angle1))+Math.abs(TESwidth*Math.sin(angle1));
+ double length_y = Math.abs(TESlength*Math.sin(angle1))+Math.abs(TESwidth*Math.cos(angle1));
+
+ //take m by n array of pictures to cover entire TES
+
+ //find m (horizontal number of pics) and n (vertical number of pics)
+ int m = (int) Math.ceil(length_x/xDim);
+ int n = (int) Math.ceil(length_y/yDim);
+
+ //write proper commands to output autorun file
+ for(int j = 0; j < m; j++){
+ for(int k = 0; k < n; k++){
+ Formatter fmt1 = new Formatter();
+ Formatter fmt2 = new Formatter();
+ fmt1.format("%.6f", x1-(0.5*(m-1))*xDim+j*xDim); // very clever: "extra" pixels go on either side of
+ fmt2.format("%.6f", y1-(0.5*(n-1))*yDim+k*yDim); // the QET by the 0.5*(m-1) offset here
+ // will we need to include explicit overlap?
+ output.write("c:\\Partrtn\\IZipOriginTakePicture_x2_5.RTN,"+fmt1+","+fmt2+",0,0,0,0\n");
+ //output.write(fmt1+","+fmt2+"\n");
+ }
+
+ }
+
+ //don't do this for the last coord in the file--there's nothing after it!
+ if(i != ncoords-1){
+
+ Double[] coords2 = _coordinates.get(i+1);
+
+
+ // also only do this if the distance is not too great
+
+ Double[] interp = getInterpolatedImagePosition(coords1,coords2);
+ if(interp!=null){ // null means we don't want an interpolated picture, prolly cause of jump
+ Formatter fmt1 = new Formatter();
+ Formatter fmt2 = new Formatter();
+ fmt1.format("%.6f", interp[0]);
+ fmt2.format("%.6f", interp[1]);
+ output.write("c:\\Partrtn\\IZipOriginTakePicture_x2_5.RTN,"+fmt1+","+fmt2+",0,0,0,0\n");
+ //output.write(fmt1+","+fmt2+",%interp\n");
+ }
+ }
+
+ }
+
+ output.write("END_RUN\n");
+
+ output.close();
+ }
+
+
+ /**
+ * Get a list of numbers in a line on the input stream
+ *
+ * @param tok StreamTokenizer with the next token being the first number
+ * @return List of numbers in the current line
+ * @throws IOException
+ */
+ private List<Double> getNumbersInLine(StreamTokenizer tok) throws IOException {
+
+ // Create a list of numbers that the tokenizer finds
+ List<Double> nums = new ArrayList<Double>();
+
+ // Loop looking for either end of line or end of file
+ while (tok.nextToken() != StreamTokenizer.TT_EOF) {
+ if (tok.ttype == StreamTokenizer.TT_EOL) break;
+
+ // Check to make sure that we have a numeric token
+ if (tok.ttype != StreamTokenizer.TT_NUMBER) continue;
+
+ // Found a number token - add it to the list
+ nums.add(tok.nval);
+
+ }
+ return nums;
+ }
+
+ private Double[] getInterpolatedImagePosition(Double coords1[], Double coords2[]){
+ //returns double that gives x,y image of where we should take an interpolated picture
+
+ //find cubic function that fits the wiring between adjacent TESs
+ //Do this by solving system of linear equations for (A,B,C,D):
+ //row 1: A*x1^3 + B*x1^2 + C*x1 + D == y1
+ //row 2: A*x2^3 + B*x2^2 + C*x2 + D == y2
+ //row 3: derivative of LHS of row 1 wrt x1 == tan(angle1) (=slope at x1)
+ //row 4: derivative of LHS of row 2 wrt x2 == tan(angle2) (=slope at x2)
+ //It turns out that this method for taking pictures of the wiring between TESs
+ // is redundant at the resolutions we're working with--everything is covered by
+ // the m by n array of the above code. I'm commenting this section out but
+ // leaving it here in case it ever becomes needed.
+
+ //It should be noted that this method is not completely accurate for large angles
+ // between the TESs--theta ~ pi/2 or so.
+
+ //set up input data
+
+
+ Double x1 = 0.001*coords1[0]; //coords are given in um, OGP routine needs them in mm
+ Double y1 = 0.001*coords1[1];
+ Double angle1 = coords1[2];
+ Double x2 = 0.001*coords2[0];
+ Double y2 = 0.001*coords2[1];
+ Double angle2 = coords2[2];
+
+
+ // checks: for large angle and large jumps
+ // first: large jump check. if the jump is too big, don't interpolate
+ Double dist = Math.pow(Math.pow(x1-x2,2)+Math.pow(y1-y2,2), 0.5);
+
+ if(dist > 2.0) return null; // if we're more than 3 times the length of a qet away
+ // then it's pretty safe to say that we're jumping
+ // then return null: no interpolation will be done
+
+
+ // need a backup method for straight line sections
+ if(Math.abs(angle1-angle2)<0.001 || Math.abs(x1-x2)<0.001 || Math.abs(y1-y2)<0.001){
+ // this is a more robust way to test for straight line sections, where other methods fail
+ // there the easiest thing is just to take the averages: very simple geometry for interpolation
+ Double[] pos = new Double[2];
+ pos[0] = (x1+x2)/2;
+ pos[1] = (y1+y2)/2;
+
+ return pos;
+
+ }
+ else{
+ // second: check for large angles. if the angle is near pi/2, use alternate interp.
+ //if(Math.abs(angle2-angle1) > Math.PI/4){ // pretty loose cut on the alternate interp...
+ // note that this method is vulnerable to having two qet's with same slope
+ // probably better to only use it on large angles
+ // get the extrapolated lines defined by the qet position and angle
+ Double[] line1 = getLineFromQET(x1, y1, angle1);
+ Double[] line2 = getLineFromQET(x2, y2, angle2);
+
+ // get the point of intersection between them
+ return getXYIntersect(line1,line2);
+ }
+
+ // we've passed the small jump, small angle check: go to main interpolate code
+//
+// //init matrices
+// BasicMatrix XcoordsMatrix = new BasicMatrix(4,4);
+// BasicMatrix YcoordsVector = new BasicMatrix(4,1);
+// //BasicMatrix functionVector = new BasicMatrix(4,1);
+//
+// //create XcoordsMatrix
+// XcoordsMatrix.setElement(0, 0, Math.pow(x1,3));
+// XcoordsMatrix.setElement(0, 1, Math.pow(x1,2));
+// XcoordsMatrix.setElement(0, 2, x1);
+// XcoordsMatrix.setElement(0, 3, 1);
+// XcoordsMatrix.setElement(1, 0, Math.pow(x2,3));
+// XcoordsMatrix.setElement(1, 1, Math.pow(x2,2));
+// XcoordsMatrix.setElement(1, 2, x2);
+// XcoordsMatrix.setElement(1, 3, 1);
+// XcoordsMatrix.setElement(2, 0, 3*Math.pow(x1,2));
+// XcoordsMatrix.setElement(2, 1, 2*x1);
+// XcoordsMatrix.setElement(2, 2, 1);
+// XcoordsMatrix.setElement(2, 3, 0);
+// XcoordsMatrix.setElement(3, 0, 3*Math.pow(x2,2));
+// XcoordsMatrix.setElement(3, 1, 2*x2);
+// XcoordsMatrix.setElement(3, 2, 1);
+// XcoordsMatrix.setElement(3, 3, 0);
+//
+// YcoordsVector.setElement(0,0, y1);
+// YcoordsVector.setElement(1,0, y2);
+// YcoordsVector.setElement(2,0, Math.tan(angle1));
+// YcoordsVector.setElement(3,0, Math.tan(angle2));
+//
+// Matrix inverse = MatrixOp.inverse(XcoordsMatrix);
+//
+// //find A,B,C,D by inverting XcoordsMatrix
+// Matrix paramVector = MatrixOp.mult(inverse,YcoordsVector);
+//
+// double A = paramVector.e(0,0);
+// double B = paramVector.e(1,0);
+// double C = paramVector.e(2,0);
+// double D = paramVector.e(3,0);
+//
+//
+// Double pos[] = new Double[2];
+// //choose some x between x1 and x2, then calculate y using paramVector
+// if(x1 != x2){
+// double xavg = (x1+x2)/2;
+// double yvalue = A*Math.pow(xavg,3)+B*Math.pow(xavg,2)+C*xavg+D;
+// pos[0] = xavg;
+// pos[1] = yvalue;
+// }
+// else{ //there might be a problem for x1 = x2, so try this
+// double yavg = (y1+y2)/2;
+// pos[0] = x1;
+// pos[1] = yavg;
+// }
+//
+//// Double pos[] = new Double[2];
+//// //explicit average, just take it: very good results compare to cubic
+//// // with 'good' overlap from 3 images in each axis, and very small offset from cubic, safe to use average
+//// pos[0] = (x1+x2)/2;
+//// pos[1] = (y1+y2)/2;
+//
+// return pos;
+ }
+
+ //get y = mx + b line from a qet. (extrapolate using x,y,angle coordinates)
+ //returns independent of units... be sure to use them right!
+ //returns line[], with line[0] = m, line[1] = b
+ private Double[] getLineFromQET(Double x, Double y, Double angle){
+
+ Double m = Math.tan(angle); // find the slope using the angle
+
+ Double b = y - m*x; // use the x-y data to find b
+
+ Double[] line = new Double[2];
+ line[0] = m;
+ line[1] = b;
+ return line;
+ }
+
+ private Double[] getXYIntersect(Double[] line1, Double[] line2){
+ Double m1 = line1[0];
+ Double b1 = line1[1];
+ Double m2 = line2[0];
+ Double b2 = line2[1];
+
+ Double x = - (b1-b2)/(m1-m2);
+ Double y = - (-b2*m1 + b1*m2)/(m1 - m2);
+
+ Double[] xy = new Double[2];
+ xy[0] = x;
+ xy[1] = y;
+
+ return xy;
+ }
+}
CDMS/src/CDMS/kscheck
diff -u -r1.1 -r1.2
--- SortCoordsFile.java 13 Dec 2010 22:17:50 -0000 1.1
+++ SortCoordsFile.java 22 Jan 2011 19:08:28 -0000 1.2
@@ -1,156 +1,178 @@
-/*
- * SortCoordsFile.java
- */
-
-package CDMS.kscheck;
-
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.StreamTokenizer;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author Kristi Schneck
- */
-public class SortCoordsFile {
-
- private List<Double[]> _coordinates;
- public List<Double[]> sortedCoords;
-
- public SortCoordsFile(String inputCoordsFile, String outputSortedFile) throws FileNotFoundException, IOException {
-
- // Open the autorun file and setup a StreamTokenizer for a space delimited list
- FileReader fr = new FileReader(inputCoordsFile);
- FileWriter fw = new FileWriter(outputSortedFile);
- BufferedWriter output = new BufferedWriter(fw);
- StreamTokenizer tok = new StreamTokenizer(fr);
- tok.resetSyntax();
- tok.wordChars(33, 126);
- tok.parseNumbers();
- tok.whitespaceChars(0, 32);
- tok.eolIsSignificant(true);
-
- _coordinates = new ArrayList<Double[]>();
-
- // Loop over the input coordinate file entries
- while (true) {
- List<Double> args = getNumbersInLine(tok);
-
- //break out of loop if there are no more coords to add
- if (args.isEmpty()){
- break;
- }
-
- Double xcoord = args.get(0);
- Double ycoord = args.get(1);
- Double angle = args.get(2);
- Double TEStype = args.get(3);
-
- //add all coordinates to _coordinates ArrayList
- Double pos[] = {xcoord, ycoord, angle, TEStype};
- _coordinates.add(pos);
-
- }
-
- int ncoords = _coordinates.size();
-
- sortedCoords = new ArrayList<Double[]>();
- //add first element of _coordinates to sortedCoords
- //this becomes the first element in the sorted list
- sortedCoords.add(_coordinates.get(0));
- //remove this element from _coordinates
- _coordinates.remove(0);
-
-
- //sort by looking for minimum distance between coords
- while(sortedCoords.size()<=ncoords){
- double minDist = 10000000000.0;//some really large number
- Double[] minCoords = {10000000000000.0,10000000000000.0,10000000000000.0,10000000000000.0};
- //look at last element (most recently added) of sortedCoords
- Double[] coords1 = sortedCoords.get(sortedCoords.size()-1);
- Double x1 = coords1[0];
- Double y1 = coords1[1];
- //loop over all elements in _coordinates
- for(int j = 0; j < ncoords-1; j++){
- //get next coords for comparison
- Double[] coords2 = _coordinates.get(j);
- Double x2 = coords2[0];
- Double y2 = coords2[1];
-
- //calculate distance squared between coords1 and coords2
- double dist = Math.pow((x1-x2),2)+Math.pow((y1-y2),2);
- //assign coords2 to minCoords if the distance is smaller than previous
- // distances and if coords2 is not already in sortedCoords
- if(dist <= minDist && dist != 0.0){
- if(sortedCoords.contains(coords2)==false){
- minCoords = coords2;
- minDist = dist;
- }
-
- }
-
- }
- //add resulting minCoords to sortedCoords
- sortedCoords.add(minCoords);
-
- }
-
- //write all elements in sortedCoords to the output file
- Double[] coordsToAdd;
- for(int k = 0; k < ncoords; k++){
- coordsToAdd = sortedCoords.get(k);
- Double x = coordsToAdd[0];
- Double y = coordsToAdd[1];
- Double angle = coordsToAdd[2];
- Double type = coordsToAdd[3];
- String xString = String.valueOf(x);
- String yString = String.valueOf(y);
- String angleString = String.valueOf(angle);
- String typeString = String.valueOf(type);
- output.write(xString+" "+yString+" "+angleString+" "+typeString+"\n");
- }
- output.close();
- }
-
- public List<Double[]> getImageCoordinates() {
- return _coordinates;
- }
-
- public Double[] getImageCoordinates(int i) {
- return _coordinates.get(i);
- }
-
- /**
- * Get a list of numbers in a line on the input stream
- *
- * @param tok StreamTokenizer with the next token being the first number
- * @return List of numbers in the current line
- * @throws IOException
- */
- private List<Double> getNumbersInLine(StreamTokenizer tok) throws IOException {
-
- // Create a list of numbers that the tokenizer finds
- List<Double> nums = new ArrayList<Double>();
-
- // Loop looking for either end of line or end of file
- while (tok.nextToken() != StreamTokenizer.TT_EOF) {
- if (tok.ttype == StreamTokenizer.TT_EOL) break;
-
- // Check to make sure that we have a numeric token
- if (tok.ttype != StreamTokenizer.TT_NUMBER) continue;
-
- // Found a number token - add it to the list
- nums.add(tok.nval);
-
- }
- return nums;
- }
-
-
-
+/*
+ * SortCoordsFile.java
+ */
+
+package CDMS.kscheck;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.StreamTokenizer;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Kristi Schneck, swiatlow
+ * Note: requires blank line as last line of input file
+ * Ignores everything on a line after %
+ * Blank lines are safe, ignored
+ */
+public class SortCoordsFile {
+
+ private List<Double[]> _coordinates;
+ public List<Double[]> sortedCoords;
+
+ public SortCoordsFile(String inputCoordsFile, String outputSortedFile) throws FileNotFoundException, IOException {
+
+ // Open the autorun file and setup a StreamTokenizer for a space delimited list
+ FileReader fr = new FileReader(inputCoordsFile);
+ FileWriter fw = new FileWriter(outputSortedFile);
+ BufferedWriter output = new BufferedWriter(fw);
+ StreamTokenizer tok = new StreamTokenizer(fr);
+ tok.resetSyntax();
+ tok.wordChars(33, 126);//normal text are words
+ tok.parseNumbers(); //set numbers to be marked as numeric so we can flag them
+ tok.whitespaceChars(0, 32);//commands and spaces are whitespace
+ tok.eolIsSignificant(true);
+ tok.commentChar('%');
+
+ _coordinates = new ArrayList<Double[]>();
+ List<Double> args = getNumbersInLine(tok);
+
+ // Loop over the input coordinate file entries
+ while (args!=null) {
+ System.out.println("in loop");
+ //no coordinates: means we have a blank line. (or a comment line or something similar)
+ //continue on till we reach end of file or a real line
+ if (!args.isEmpty()){
+
+ Double xcoord = args.get(0);
+ Double ycoord = args.get(1);
+ Double angle = args.get(2);
+ Double TEStype = args.get(3);
+
+ //add all coordinates to _coordinates ArrayList
+ Double pos[] = {xcoord, ycoord, angle, TEStype};
+ _coordinates.add(pos);
+ System.out.print(pos[0]);
+ }
+ else System.out.println("blank line!");
+ args = getNumbersInLine(tok); // get the next set of args: if it's null, we're going to break out
+ // if it's blank, we'll just continue on
+ }
+ System.out.println("out of loop?");
+ int ncoords = _coordinates.size();
+ if(ncoords==0){
+ //quick error check on reading data
+ output.close();
+ System.out.println("Is input setup correctly? 0 arguments.");
+ return;
+
+ }
+
+ sortedCoords = new ArrayList<Double[]>();
+ //add first element of _coordinates to sortedCoords
+ //this becomes the first element in the sorted list
+ sortedCoords.add(_coordinates.get(0));
+ //remove this element from _coordinates
+ _coordinates.remove(0);
+
+
+ //sort by looking for minimum distance between coords
+ while(sortedCoords.size()<=ncoords){
+ double minDist = 10000000000.0;//some really large number
+ Double[] minCoords = {10000000000000.0,10000000000000.0,10000000000000.0,10000000000000.0};
+ //look at last element (most recently added) of sortedCoords
+ Double[] coords1 = sortedCoords.get(sortedCoords.size()-1);
+ Double x1 = coords1[0];
+ Double y1 = coords1[1];
+ //loop over all elements in _coordinates
+ for(int j = 0; j < ncoords-1; j++){
+ //get next coords for comparison
+ Double[] coords2 = _coordinates.get(j);
+ Double x2 = coords2[0];
+ Double y2 = coords2[1];
+
+ //calculate distance squared between coords1 and coords2
+ double dist = Math.pow((x1-x2),2)+Math.pow((y1-y2),2);
+ //assign coords2 to minCoords if the distance is smaller than previous
+ // distances and if coords2 is not already in sortedCoords
+ if(dist <= minDist && dist != 0.0){
+ if(sortedCoords.contains(coords2)==false){
+ minCoords = coords2;
+ minDist = dist;
+ }
+
+ }
+
+ }
+ //add resulting minCoords to sortedCoords
+ sortedCoords.add(minCoords);
+
+ }
+
+ //write all elements in sortedCoords to the output file
+ Double[] coordsToAdd;
+ for(int k = 0; k < ncoords; k++){
+ coordsToAdd = sortedCoords.get(k);
+ Double x = coordsToAdd[0];
+ Double y = coordsToAdd[1];
+ Double angle = coordsToAdd[2];
+ Double type = coordsToAdd[3];
+ String xString = String.valueOf(x);
+ String yString = String.valueOf(y);
+ String angleString = String.valueOf(angle);
+ String typeString = String.valueOf(type);
+ output.write(xString+" "+yString+" "+angleString+" "+typeString+"\n");
+ }
+ output.close();
+ }
+
+ public List<Double[]> getImageCoordinates() {
+ return _coordinates;
+ }
+
+ public Double[] getImageCoordinates(int i) {
+ return _coordinates.get(i);
+ }
+
+ /**
+ * Get a list of numbers in a line on the input stream
+ *
+ * @param tok StreamTokenizer with the next token being the first number
+ * @return List of numbers in the current line
+ * @throws IOException
+ */
+ private List<Double> getNumbersInLine(StreamTokenizer tok){
+ try{
+ // Create a list of numbers that the tokenizer finds
+ List<Double> nums = new ArrayList<Double>();
+
+ // Loop looking for either end of line or end of file
+ while (tok.nextToken() != StreamTokenizer.TT_EOL) {
+ if(tok.ttype==StreamTokenizer.TT_EOF) return null; // reached EOF: get out of here!
+ // note we assume this is not on a line with data
+
+ //if (tok.ttype == StreamTokenizer.TT_EOL) break;
+
+ // Check to make sure that we have a numeric token
+ if (tok.ttype != StreamTokenizer.TT_NUMBER) continue;
+
+ // Found a number token - add it to the list
+ nums.add(tok.nval);
+
+ }
+ //if(nums.size()==0 && tok.ttype==StreamTokenizer.TT_EOF) return null;
+ return nums;
+ }
+ catch(IOException exception){
+ return null;
+ }
+ }
+
+
+
}
\ No newline at end of file