Commit in CDMS/src/CDMS/kscheck on MAIN
CreateRoadMapFile.java+265-161.4 -> 1.5
SortCoordsTest.java+6-61.5 -> 1.6
+271-22
2 modified files
Updates to interpolation routines. If the distance is moderate, i.e. a distance which likely corresponds to a long line instead of a real jump, then we can pretend the interpolated space is a QET with size defined by the number of images it takes to get complete overlap. Works rather well. 

CDMS/src/CDMS/kscheck
CreateRoadMapFile.java 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- CreateRoadMapFile.java	25 Jan 2011 23:43:29 -0000	1.4
+++ CreateRoadMapFile.java	31 Jan 2011 03:05:11 -0000	1.5
@@ -42,6 +42,7 @@
     //private static double TESwidth = 0.307907; //width in mm, originally .22 mm
     //private static double TESwidth = 0.27;
     private static double TESwidth = 0.31;
+    //private static double TESwidth = 0.23;
     private static double nPixX = 620; //number of pixels in horizontal direction = 640 add overlap explicitly here: 620/460
     private static double nPixY = 460; //number of pixels in vertical direction = 480
 
@@ -52,6 +53,9 @@
     
     private static boolean CHECK_OVERLAP = true; // flag for whether we check for overlap before interpolating
     
+    private static double BIG_CUTOFF = 2;
+    private static double HUGE_CUTOFF = 10; // cutoff for big jump, where we should interp forward to complete loop
+    
     public CreateRoadMapFile(String inputCoordsFile, String outputOGPscript, double pixelSize, int outputType) throws FileNotFoundException, IOException {
         // outputType = 0 should be default: normal commands file
     	// outputType = 1 is for csv output, for examining in excel/numbers/neooffice
@@ -139,14 +143,20 @@
 
                 Double[] coords2 = _coordinates.get(i+1);
                         
-                Double[] interp = getInterpolatedImagePosition(coords1,coords2);
-                if(interp!=null){ // null means we don't want an interpolated picture
-                	Formatter fmt1 = new Formatter();
-                	Formatter fmt2 = new Formatter();
-                	fmt1.format("%.6f", interp[0]);
-                	fmt2.format("%.6f", interp[1]);
-                	if(outputType==0) output.write("c:\\Partrtn\\IZipOriginTakePicture_x2_5.RTN,"+fmt1+","+fmt2+",0,0,0,0\n");
-                	else if(outputType==1) output.write(fmt1+","+fmt2+",%interp\n");
+                List<Double[]> interps = getInterpolatedImagePositions(coords1,coords2);
+                
+                
+                if(interps!=null){ // null means we don't want an interpolated picture
+                	for(int a = 0; a < interps.size(); a++){
+                		if(interps.get(a)!=null){
+                			Formatter fmt1 = new Formatter();
+                			Formatter fmt2 = new Formatter();
+                			fmt1.format("%.6f", interps.get(a)[0]);
+                			fmt2.format("%.6f", interps.get(a)[1]);
+                			if(outputType==0) output.write("c:\\Partrtn\\IZipOriginTakePicture_x2_5.RTN,"+fmt1+","+fmt2+",0,0,0,0\n");
+                			else if(outputType==1) output.write(fmt1+","+fmt2+",%interp\n");
+                		}
+                	}
                 }
             }
 
@@ -200,15 +210,212 @@
         return nums;
     }
     
+    // the fractional number of pictures that we overlap by in x direction. negative overlap means no overlap,
+    // and that we're that far apart.
+    private double getOverlapX(Double[] coords1, Double[] coords2){
+
+    	Double x1 = 0.001*coords1[0]; //coords are given in um, OGP routine needs them in mm
+    	Double angle1 = coords1[2];
+    	Double x2 = 0.001*coords2[0];
+    	Double angle2 = coords2[2];
+
+
+    	// init overlap counters
+    	double xOverlap = 0;
+
+    	// first set up number of images, and lengths we're dealing with
+    	double lx1 = getILengthX(angle1);
+
+    	double lx2 = getILengthX(angle2);
+
+    	int xPics1 = getXPics(lx1);
+    	int xPics2 = getXPics(lx2);
+
+    	// calculate the x coordinates of the left and right ends of the pictures we're taking, for both
+    	// sensors (the current and the next)
+    	//double left1 = x1-(0.5*(xPics1-1))*xDim-0.5*xDim; // use the same calc as for center of images
+    	//double left2 = x2-(0.5*(xPics2-1))*xDim-0.5*xDim; // but then offset by half the width of the image
+    	//double right1 = x1+(0.5*(xPics1-1))*xDim+0.5*xDim; // this way we find the edge, not the center
+    	//double right2 = x2+(0.5*(xPics2-1))*xDim+0.5*xDim;
+    	// simplifying the above calculation a bit:
+    	double left1 = x1 - xDim*(0.5*xPics1);
+    	double left2 = x2 - xDim*(0.5*xPics2);
+    	double right1 = x1 + xDim*0.5*xPics1;
+    	double right2 = x2 + xDim*0.5*xPics2;
+
+
+    	if(x1-x2==0 && xPics1 == xPics2){// then they're exactly on top of each other, so #of pics = overlap
+    		xOverlap = xPics1;
+    	}
+    	else{ // if not simple, check for the real amount of overlap        		
+    		double rightmostLeft = Math.max(left1,left2);
+    		double leftmostRight = Math.min(right1,right2);
+
+    		xOverlap = (leftmostRight - rightmostLeft)/xDim;// calculate overlap, normalized by xDim
+    	}
+    	
+    	return xOverlap;
+
+    }
+    
+    // the fractional number of pictures that we overlap by in y direction. negative overlap means no overlap,
+    // and that we're that far apart.
+    private double getOverlapY(Double[] coords1, Double[] coords2){
+
+    	Double y1 = 0.001*coords1[1]; //coords are given in um, OGP routine needs them in mm
+    	Double angle1 = coords1[2];
+    	Double y2 = 0.001*coords2[1];
+    	Double angle2 = coords2[2];
+
+
+    	// init overlap counters
+    	double yOverlap = 0;
+
+    	// first set up number of images, and lengths we're dealing with
+    	double ly1 = getILengthY(angle1);
+
+    	double ly2 = getILengthY(angle2);
+
+    	int yPics1 = getYPics(ly1);
+    	int yPics2 = getYPics(ly2);
+
+    	// calculate the x coordinates of the left and right ends of the pictures we're taking, for both
+    	// sensors (the current and the next)
+    	//double left1 = x1-(0.5*(xPics1-1))*xDim-0.5*xDim; // use the same calc as for center of images
+    	//double left2 = x2-(0.5*(xPics2-1))*xDim-0.5*xDim; // but then offset by half the width of the image
+    	//double right1 = x1+(0.5*(xPics1-1))*xDim+0.5*xDim; // this way we find the edge, not the center
+    	//double right2 = x2+(0.5*(xPics2-1))*xDim+0.5*xDim;
+    	// simplifying the above calculation a bit:
+    	double bot1 = y1 - yDim*(0.5*yPics1);
+    	double bot2 = y2 - yDim*(0.5*yPics2);
+    	double top1 = y1 + yDim*0.5*yPics1;
+    	double top2 = y2 + yDim*0.5*yPics2;
+
+
+    	if(y1-y2==0 && yPics1 == yPics2){// then they're exactly on top of each other, so #of pics = overlap
+    		yOverlap = yPics1;
+    	}
+    	else{ // if not simple, check for the real amount of overlap        		    		
+    		double topmostBottom = Math.max(bot1,bot2);
+    		double bottommostTop = Math.min(top1, top2);
+    		
+    		yOverlap = (bottommostTop - topmostBottom)/yDim;
+    	}
+    	
+    	return yOverlap;
+    }
+    
+
+    private List<Double[]> getInterpolatedImagePositions(Double coords1[], Double coords2[]){
+
+    	List<Double[]> interps = new ArrayList<Double[]>();
+
+    	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];
+    	
+    	if(goodOverlap(coords1, coords2)) // if there's good overlap, return null interpolation position
+    		return null;
+
+    	Double overlapX = getOverlapX(coords1,coords2);
+    	Double overlapY = getOverlapY(coords1,coords2);
+    	
+    	
+    	if(overlapX > -1 && overlapY > -1){
+    		interps.add(getInterpolatedImagePosition(coords1, coords2)); // the case for not so bad failed overlap
+    																	 // use the old single overlap technique
+    	}
+    	else{ // we've got a big gap folks
+    		// if it's smaller than the big cutoff, it's our job to actually interpolate it
+    		// but we have one thing on our side: if it's a big gap, it's a simple type
+    		// just create a grid of images that covers all the points in the gaps
+    		double dist = Math.pow(Math.pow(x1-x2,2) + Math.pow(y1-y2, 2), 0.5);
+    		double xAv = (x1+x2)/2;
+    		double yAv = (y1+y2)/2;
+    		int m = (int) (Math.ceil(Math.abs(overlapX)));
+    		int n = (int) (Math.ceil(Math.abs(overlapY)));
+    		
+    		if(dist > BIG_CUTOFF){ // actually might want to put some extra interp here to "close the loops"    			
+    			
+    			if(dist > HUGE_CUTOFF){ // then we have a case of the really big jump, need to interp forward a bit
+    									// this is highly dependant on izip design, be careful
+    									// a better design would be to store the first coordinate after a big jump
+    									// (or at start), and then before a big jump, check the overlap to that
+    				System.out.println("In the Huge Cutoff block");
+    				
+    				Double[] line = getLineFromQET(x1, y1, angle1);
+    				
+    				double xtarget = x1 + TESlength*.6;
+    				double ytarget = line[0]*xtarget+line[1];
+    				
+    				Double[] hugeinterp = new Double[2];
+    				hugeinterp[0] = xtarget; hugeinterp[1] = ytarget;
+    				interps.add(hugeinterp);
+    				
+    				return interps;
+    			}
+    			
+    			System.out.println("too long! at " + x1 + ", " + y1);
+    			if(isStraight(coords1,coords2)!=1){
+    				if(isStraight(coords1, coords2)==0){
+    					System.out.println("not straight at " + x1 + ", " + y1);
+    				}
+    				if(isStraight(coords1,coords2)==-1) System.out.println("horizontal! at " + x1 + ", " + y1);
+    				return null; // if it's far apart and not vertical, null
+    			}
+    			else{ // so it's vertical... a few cases we still want to make nice with
+    				System.out.println("vertical!");
+    				// no distance cut off, and only one size for x: 1
+    				for(int j = 0; j < n; j++){
+
+    	    				double xi = xAv;
+    	    				double yi =  yAv-(0.5*(n-1))*yDim+j*yDim;
+    	    				Double[] interp = new Double[2];
+    	    				interp[0] = xi;
+    	    				interp[1] = yi;
+
+    	    				interps.add(interp);
+    	    		}// j loop	
+    	    		System.out.println("adding a " + m + " by " + n + " interp at " + xAv + ", " + yAv);
+    				return interps;
+    			}
+    		}
+
+    		n = Math.max(n,2);
+
+    		System.out.println("adding a " + m + " by " + n + " interp at " + xAv + ", " + yAv);
+
+    		
+    		for(int j = 0; j < m; j++){
+    			for(int k = 0; k < n; k++){
+    				double xi = xAv-(0.5*(m-1))*xDim+j*xDim;
+    				double yi =  yAv-(0.5*(n-1))*yDim+k*yDim;
+    				Double[] interp = new Double[2];
+    				interp[0] = xi;
+    				interp[1] = yi;
+
+    				interps.add(interp);
+    			}// k loop
+    		}// j loop	
+    		
+    	}// big gap if/else block
+    	
+    	
+    	return interps;
+    }
+
     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)
+    	//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
@@ -241,7 +448,7 @@
         
         
         // 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){
+        if(Math.abs(angle1-angle2)< FLAT_ANGLE_CUT || Math.abs(x1-x2)<0.001*FLAT_XY_CUT || Math.abs(y1-y2)<0.001*FLAT_XY_CUT){
         	// 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];
@@ -388,11 +595,14 @@
         	}
         	else{
         		double topmostBottom = Math.max(bot1,bot2);
-        		double bottommostTop = Math.max(top1, top2);
+        		double bottommostTop = Math.min(top1, top2);
         		
         		yOverlap = (bottommostTop - topmostBottom)/yDim;
         	}
         	
+        	//if(x1==1.294) System.out.println("good overlap results for annoying at: " + x1 + ", " + y1 + ", with " + xOverlap + " " + yOverlap + 
+        	//		", overlapping with " + x2 + ", " + y2);
+        	
         	// if lots of overlap in one direction, and > 0 overlap in another direction, we can be pretty sure
         	// we don't need overlap. but otherwise, let's say bad overlap, take another picture.
         	if(Math.max(yOverlap, xOverlap) > OVERLAP_FRAC && Math.min(yOverlap,xOverlap) > 0)
@@ -439,4 +649,43 @@
     	
     	return xy;
     }
+    
+    private static double FLAT_ANGLE_CUT = 0.1;
+    private static double FLAT_XY_CUT = 100;
+    
+ // returns 0 if not straight
+    // returns -1 if horizontal
+    // returns 1 if vertical
+    private int isStraight(Double[] coords1, Double[] coords2){
+    	Double x1 = coords1[0];
+    	Double x2 = coords2[0];
+    	Double y1 = coords1[1];
+    	Double y2 = coords2[1];
+    	Double angle1 = coords1[2];
+    	Double angle2 = coords2[2];
+    	
+    	//double piremain1 = Math.abs(angle1)%Math.PI;
+    	//double piremain2 = Math.abs(angle2)%Math.PI;
+    	
+    	//if((piremain1 < FLAT_ANGLE_CUT || piremain1 > Math.PI-FLAT_ANGLE_CUT)
+    	//		&& (piremain2 < FLAT_ANGLE_CUT || piremain2 > Math.PI-FLAT_ANGLE_CUT) ){
+    	if(Math.abs(Math.abs(angle1)-Math.PI) < FLAT_ANGLE_CUT && Math.abs(Math.abs(angle2)-Math.PI) < FLAT_ANGLE_CUT ){
+    	//both are horizontal in this case: check that they're in the same line now
+    		if(Math.abs(y1-y2) < FLAT_XY_CUT){
+    			// they're in the same line, and they're horizontal
+    			return -1;
+    		}
+    	}
+    	//else if(((Math.abs(angle1)%(Math.PI/2)) < FLAT_ANGLE_CUT ) && (Math.abs(angle1)%(Math.PI) > FLAT_ANGLE_CUT )
+    	//		&& ((Math.abs(angle2)%(Math.PI/2)) < FLAT_ANGLE_CUT) && (Math.abs(angle2)%(Math.PI) > FLAT_ANGLE_CUT )){
+    	else if(Math.abs(Math.abs(angle1)-Math.PI/2) < FLAT_ANGLE_CUT && Math.abs(Math.abs(angle2)-Math.PI/2) < FLAT_ANGLE_CUT){
+    	// both are vertical.
+    		if(Math.abs(x1-x2) < FLAT_XY_CUT){
+    			return 1;
+    		}
+    	}
+    	
+    	return 0;
+    }
+    
 }

CDMS/src/CDMS/kscheck
SortCoordsTest.java 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- SortCoordsTest.java	28 Jan 2011 23:41:04 -0000	1.5
+++ SortCoordsTest.java	31 Jan 2011 03:05:11 -0000	1.6
@@ -18,14 +18,14 @@
     public static void main(String[] args) throws FileNotFoundException, IOException {
     	System.out.println("testing!");
         //SortCoordsFile pcfile = new SortCoordsFile("side1_copy.txt","sortedCoords.txt");
-        //CreateRoadMapFile roadmap1 = new CreateRoadMapFile("/Users/maxinion/Documents/Work/CDMS/code/imaging/sortedCoords_long.txt","/Users/maxinion/Documents/Work/CDMS/code/imaging/testfiles1-25/autorun_long.csv",0.00059,1);
+        CreateRoadMapFile roadmap1 = new CreateRoadMapFile("/Users/maxinion/Documents/Work/CDMS/code/imaging/testfiles1-28/sortedCoords_test_beta_short.txt","/Users/maxinion/Documents/Work/CDMS/code/imaging/testfiles1-28/test_short.txt",0.00059,0);
         //CreateRoadMapFile roadmap2 = new CreateRoadMapFile("shortTest2.txt","testautorun2.txt",0.00067);
         //CreateRoadMapFile roadmap3 = new CreateRoadMapFile("longTest.txt","testautorun3.txt",0.00067);
         //SplitSortedFile splitfile = new SplitSortedFile("sortedCoords.txt","splittest.txt");
-    	SortCoordsFile pcfile = new SortCoordsFile("/Users/maxinion/Documents/Work/CDMS/code/imaging/side1_copy.txt","/Users/maxinion/Documents/Work/CDMS/code/imaging/testfiles1-28/sortedCoords_test_beta.csv");
-    	if(pcfile.getInputStatus()==true){
-    		pcfile.sortBeta();
-    		pcfile.printOut(1);
-    	}
+//    	SortCoordsFile pcfile = new SortCoordsFile("/Users/maxinion/Documents/Work/CDMS/code/imaging/side1_copy.txt","/Users/maxinion/Documents/Work/CDMS/code/imaging/testfiles1-28/sortedCoords_test_beta.txt");
+//    	if(pcfile.getInputStatus()==true){
+//    		pcfile.sortBeta();
+//    		pcfile.printOut();
+//    	}
     }
 }
CVSspam 0.2.8