Commit f8cffed4 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Added suggestions for manual screws (handling motors out of range)

parent 3fa095d3
Loading
Loading
Loading
Loading
+65 −2
Original line number Diff line number Diff line
@@ -4544,6 +4544,12 @@ if (MORE_BUTTONS) {
					return;
				}
			}
			// Just for old focal distance calculation
			MOTORS.focusingHistory.optimalMotorPosition( // recalculate calibration to estimate current distance from center PSF
					FOCUS_MEASUREMENT_PARAMETERS,
	    			MOTORS.getMicronsPerStep(), //double micronsPerStep,
	    			DEBUG_LEVEL);
			
			while (adjustFocusTiltLMA());
			return;
		}
@@ -8698,10 +8704,12 @@ if (MORE_BUTTONS) {
/* ===== Other methods ==================================================== */
	public boolean adjustFocusTiltLMA(){
		// just for reporting distance old way
/*		
		MOTORS.focusingHistory.optimalMotorPosition( // recalculate calibration to estimate current distance from center PSF
				FOCUS_MEASUREMENT_PARAMETERS,
    			MOTORS.getMicronsPerStep(), //double micronsPerStep,
    			DEBUG_LEVEL);
*/    			
		// No-move measure, add to history
		moveAndMaybeProbe(
				true, // just move, not probe
@@ -8724,7 +8732,7 @@ if (MORE_BUTTONS) {
		//get measurement
		FocusingField.FocusingFieldMeasurement fFMeasurement=MOTORS.getThisFFMeasurement(FOCUSING_FIELD);	
		// calculate z, tx, ty, m1,m2,m3
	    double [] zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA (fFMeasurement);
	    double [] zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA(fFMeasurement,false);
		// show dialog: Apply, re-calculate, exit
    	int [] currentMotors=fFMeasurement.motors;
    	int [] newMotors=currentMotors.clone();
@@ -8738,15 +8746,47 @@ if (MORE_BUTTONS) {
    		zTxTy[2]=zTxTyM1M2M3[2];
    	}
    	double [] targetTilts={0.0,0.0};
    	double [] manualScrewsCW=null;
    	if (zTxTyM1M2M3!=null){
    		manualScrewsCW=FOCUSING_FIELD.fieldFitting.mechanicalFocusingModel. getManualScrews(
    				zTxTy[0]-FOCUSING_FIELD.targetRelFocalShift, //double zErr, // positive - away from lens
    				zTxTy[1]-targetTilts[0],                     // double tXErr,// positive - 1,2 away from lens, 3 - to the lens
    				zTxTy[2]-targetTilts[1]);                    // double tYErr);
    	}
    	double scaleMovement=1.0; // calculate automatically - reduce when close
    	boolean parallelMove=false;
    	if (MASTER_DEBUG_LEVEL>0){
    		System.out.println("----- Focus/tilt measurement results -----");
    		System.out.println("Relative focal shift "+IJ.d2s(zTxTy[0],3)+" um ("+IJ.d2s(FOCUSING_FIELD.targetRelFocalShift,3)+"um)");
    		System.out.println("Horizontal tilt "+IJ.d2s(zTxTy[1],3)+" um/mm ("+IJ.d2s(targetTilts[0],3)+"um/mm)");
    		System.out.println("Vertical tilt "+IJ.d2s(zTxTy[2],3)+" um/mm ("+IJ.d2s(targetTilts[1],3)+"um/mm)");
    		for (int i=0;i<newMotors.length;i++){
        		System.out.println("Suggested for motor "+(i+1)+" "+newMotors[i]+" ("+currentMotors[i]+")");
    		}
    		if (manualScrewsCW!=null) for (int i=0;i<manualScrewsCW.length;i++){
    			if (manualScrewsCW[i]>=0) System.out.println("Suggested rotation for screw # "+(i+1)+" "+IJ.d2s(manualScrewsCW[i],3)+" (CW)");
    			else  System.out.println("Suggested rotation for screw # "+(i+1)+" "+IJ.d2s(manualScrewsCW[i],3)+" (CCW)");
    		}
    		System.out.println("----- end of Focus/tilt measurement results -----");
    	}
    	GenericDialog gd = new GenericDialog("Adjusting focus/tilt");
    	if (zTxTyM1M2M3==null){
    		gd.addMessage("**** Failed to determine focus/tilt, probably too far out of focus. ****");
    		gd.addMessage("**** You may cancel the command and try \"Auto pre-focus\" first. ****");
    	}
        gd.addNumericField("Target focus (relative to best composirte)",FOCUSING_FIELD.targetRelFocalShift,2,5,"um ("+IJ.d2s(zTxTy[0],3)+")");
        gd.addNumericField("Target horizontal tilt (normally 0)",targetTilts[0],2,5,"um/mm ("+IJ.d2s(zTxTy[1],3)+")");
        gd.addNumericField("Target vertical tilt (normally 0)",targetTilts[1],2,5,"um/mm ("+IJ.d2s(zTxTy[2],3)+")");
		gd.addNumericField("Motor 1",newMotors[0],0,5,"steps ("+currentMotors[0]+")");
		gd.addNumericField("Motor 2",newMotors[1],0,5,"steps ("+currentMotors[1]+")");
		gd.addNumericField("Motor 3",newMotors[2],0,5,"steps ("+currentMotors[2]+")");
		gd.addMessage("Suggested rotation of the top screws, use if motor positions are out of limits - outside of +/-25,000");
		if (manualScrewsCW!=null)  for (int i=0;i<manualScrewsCW.length;i++){
			if (manualScrewsCW[i]>=0) gd.addMessage("Screw # "+(i+1)+" "+IJ.d2s(manualScrewsCW[i],3)+" (CW)");
			else                      gd.addMessage("Screw # "+(i+1)+" "+IJ.d2s(manualScrewsCW[i],3)+" (CCW)");
		}
		gd.addNumericField("Scale movement",scaleMovement,3,5,"x");
        gd.addCheckbox("Recalculate and apply parallel move only",parallelMove); // should be false after manual movement
		
        gd.addCheckbox("Filter samples/channels by Z",FOCUSING_FIELD.filterZ); // should be false after manual movement
        gd.addCheckbox("Filter by value (leave lower than maximal fwhm used in focal scan mode)",FOCUSING_FIELD.filterByScanValue);
@@ -8773,7 +8813,7 @@ if (MORE_BUTTONS) {
		newMotors[1]=               (int)  gd.getNextNumber();
		newMotors[2]=               (int)  gd.getNextNumber();
		scaleMovement=                     gd.getNextNumber();
		
		parallelMove=                      gd.getNextBoolean();
        FOCUSING_FIELD.filterZ=            gd.getNextBoolean();
        FOCUSING_FIELD.filterByScanValue=  gd.getNextBoolean();
        FOCUSING_FIELD.filterByValueScale= gd.getNextNumber();
@@ -8789,6 +8829,18 @@ if (MORE_BUTTONS) {
		MASTER_DEBUG_LEVEL=(         int)  gd.getNextNumber();
		DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
		FOCUSING_FIELD.setDebugLevel(DEBUG_LEVEL);
		if (parallelMove){ // ignore/recalculate newMotors data 
		    zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA(fFMeasurement,true); // recalculate with parallel move only
	    	newMotors=currentMotors.clone();
	    	if (zTxTyM1M2M3!=null){
	    		newMotors[0]=(int) Math.round(zTxTyM1M2M3[3]);
	    		newMotors[1]=(int) Math.round(zTxTyM1M2M3[4]);
	    		newMotors[2]=(int) Math.round(zTxTyM1M2M3[5]);
	    	}			
    		System.out.println("Parallel move position for motor 1 "+newMotors[0]+" ("+currentMotors[0]+")");
    		System.out.println("Parallel move position for motor 2 "+newMotors[1]+" ("+currentMotors[1]+")");
    		System.out.println("Parallel move position for motor 3 "+newMotors[2]+" ("+currentMotors[2]+")");
		}
		
//	Scale motor movement	
		newMotors[0]=currentMotors[0]+((int) Math.round((newMotors[0]-currentMotors[0])*scaleMovement));
@@ -10042,6 +10094,7 @@ if (MORE_BUTTONS) {
			return null;
		}
		if (allOK) {
			if (focusMeasurementParameters.scanMeasureLast) {
			allOK &= moveAndMaybeProbe(
					true,
					centerMotorPos, // null OK
@@ -10060,6 +10113,16 @@ if (MORE_BUTTONS) {
					updateStatus,
					debugLevel,
					loopDebugLevel);
			} else { // just move, no measuring
				System.out.println("Returning motors to initial position at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
				focusingMotors.moveElphel10364Motors( // return to last direct scan position
						true, //boolean wait,
						centerMotorPos,
						0.0, //double sleep,
						true, //boolean showStatus,
						"",   //String message,
						false); //focusMeasurementParameters.compensateHysteresis); //boolean hysteresis)
			}
		}
		if (debugLevel>0) System.out.println("Scanning focus in the center, number of steps="+ focusMeasurementParameters.scanNumber+
+63 −3
Original line number Diff line number Diff line
@@ -4255,6 +4255,7 @@ public boolean LevenbergMarquardt(
    				}
    			}
    			double [] dmz= getAdjustedMotors(
    					null, // double [] zM0, //  current linearized motors (or null for full adjustment) 
    		            targetRelFocalShift+best_qb_corr[0],
    		            targetTiltX, // for testing, normally should be 0 um/mm
    		            targetTiltY,
@@ -4263,6 +4264,7 @@ public boolean LevenbergMarquardt(
    				System.out.println("Suggested motor linearized positions: "+IJ.d2s(dmz[0],2)+":"+IJ.d2s(dmz[1],2)+":"+IJ.d2s(dmz[2],2));
    			}
    			double [] dm= getAdjustedMotors(
    					null, // double [] zM0, //  current linearized motors (or null for full adjustment) 
    		            targetRelFocalShift+best_qb_corr[0],
    		            targetTiltX, // for testing, normally should be 0 um/mm
    		            targetTiltY,
@@ -4312,6 +4314,7 @@ public boolean LevenbergMarquardt(
        				}
        			}
        			double [] dmz= getAdjustedMotors(
        					null, // double [] zM0, //  current linearized motors (or null for full adjustment) 
        		            targetRelFocalShift+best_qb_corr[0],
        		            targetTiltX, // for testing, normally should be 0 um/mm
        		            targetTiltY,
@@ -4320,6 +4323,7 @@ public boolean LevenbergMarquardt(
        				System.out.println("Suggested motor linearized positions: "+IJ.d2s(dmz[0],2)+":"+IJ.d2s(dmz[1],2)+":"+IJ.d2s(dmz[2],2));
        			}
        			double [] dm= getAdjustedMotors(
        					null, // double [] zM0, //  current linearized motors (or null for full adjustment) 
        		            targetRelFocalShift+best_qb_corr[0],
        		            targetTiltX, // for testing, normally should be 0 um/mm
        		            targetTiltY,
@@ -4369,7 +4373,9 @@ public boolean LevenbergMarquardt(
    }
    
//,
    public double [] adjustLMA (FocusingFieldMeasurement measurement){
    public double [] adjustLMA (
    		FocusingFieldMeasurement measurement,
    		boolean parallelMove){
    	if (!testMeasurement(
    			measurement,    				
				zMin, //+best_qb_corr[0],
@@ -4390,7 +4396,13 @@ public boolean LevenbergMarquardt(
        result[0]=zTilts[0]-best_qb_corr[0];
        result[1]=zTilts[1];
        result[2]=zTilts[2];
        double [] zm=null;
        if (parallelMove){
        	zm=new double [3];
        	for (int i=0;i<zm.length;i++) zm[i]=fieldFitting.mechanicalFocusingModel.mToZm(measurement.motors[i], i);
        }
		double [] dm= getAdjustedMotors(
				zm,
	            targetRelFocalShift+best_qb_corr[0],
	            0.0, // targetTiltX, // for testing, normally should be 0 um/mm
	            0.0, // targetTiltY,
@@ -4426,11 +4438,13 @@ public boolean LevenbergMarquardt(
    }
    
    public double [] getAdjustedMotors(
    		double [] zM0, //  current linearized motors (or null for full adjustment) 
            double targetRelFocalShift,
            double targetTiltX, // for testing, normally should be 0 um/mm
            double targetTiltY,  // for testing, normally should be 0 um/mm
            boolean motorSteps){ 
    	double [] zM=fieldFitting.mechanicalFocusingModel.getZM(
    			zM0,
    			currentPX0, //fieldFitting.getCenterXY()[0],
    			currentPY0, //fieldFitting.getCenterXY()[1],
    			targetRelFocalShift,
@@ -4516,7 +4530,7 @@ public boolean LevenbergMarquardt(
    				break;
    			}
    			if (!changedEnable) {
    				if (debugLevel>0) System.out.println("No filter chnage, finished in "+(n+1)+" steps");
    				if (debugLevel>0) System.out.println("No filter cnange, finished in "+(n+1)+" step"+((n==0)?"":"s"));
    				return true;
    			} else {
    				if ((was2PrevEnable!=null) && (prevEnable!=null) && (was2PrevEnable.length==prevEnable.length)){
@@ -4541,7 +4555,7 @@ public boolean LevenbergMarquardt(
    	private double [] pXY=null;
    	private boolean [] centerSelect=null;
    	private boolean [] centerSelectDefault={true,true};
    	private MechanicalFocusingModel mechanicalFocusingModel;
    	public MechanicalFocusingModel mechanicalFocusingModel;
    	private CurvatureModel [] curvatureModel=new CurvatureModel[6]; // 3 colors, sagittal+tangential each
    	private boolean [] channelSelect=null;
    	private boolean [] mechanicalSelect=null;
@@ -6609,9 +6623,44 @@ public boolean LevenbergMarquardt(
    		}
    		return m;
    	}
    	/**
    	 * Calculate manual screw adjustments for focus/tilt to reduce amount of motor travel (when it is out of limits)
    	 * @param zErr  current focal distance error in microns, positive - away from lens
    	 * @param tXErr current horizontal tilt in microns/mm , positive - 1,2 away from lens, 3 - to the lens
    	 * @param tYErr current vertical tilt in microns/mm , positive - 2 away from lens, 1 - to the lens
    	 * @return array of optimal CW rotations of each screw (1.0 == 360 deg)
    	 * Screw locations:
    	 *       5    2
    	 *  3    +
    	 *       4    1
    	 * + - center      
    	 * 1,2 M2x0.4 set screws (push)
    	 * 3 - M2x0.4 socket screw (push)
    	 * 4 - M2x0.4 socket screw (pull)
    	 * 5 - M2.5x0.45 screw (pull)
    	 */
    	public double [] getManualScrews(
    			double zErr, // positive - away from lens
    			double tXErr,// positive - 1,2 away from lens, 3 - to the lens
    			double tYErr){// positive - 2 away from lens
    		double [][] screws={ // right, down, thread pitch (pull)
    				{ 20.5 ,17.5, -0.4},
    				{ 20.5,-17.5, -0.4},
    				{-20.5,  0.0, -0.4},
    				{  0.0, 17.5,  0.4},
    				{  0.0,-17.5,  0.45}};
    		double [] moveDownUm=new double [screws.length];
    		double [] turnCW=new double [screws.length];
    		for (int i=0;i<screws.length;i++){
    			moveDownUm[i]=zErr + screws[i][0]*tXErr+screws[i][1]*tYErr;
    			turnCW[i]=0.001*moveDownUm[i]/screws[i][2];
    		}
    		return turnCW;
    	}

    	/**
    	 * Calculate three linearized values of motor positions for current parameters, target center focal shift and tilt 
    	 * @param zM0 current linearized position (for parallel adjustment) or null for full adjustment
    	 * @param px lens center X (pixels)
    	 * @param py lens center Y (pixels)
    	 * @param targetZ target focal shift uin the center, microns, positive - away
@@ -6620,6 +6669,7 @@ public boolean LevenbergMarquardt(
    	 * @return array of 3 linearized motor positions (microns) 
    	 */
    	public double [] getZM(
        		double [] zMCurrent, //  current linearized motors (or null for full adjustment) 
    			double px,
    			double py,
    			double targetZ,
@@ -6627,6 +6677,16 @@ public boolean LevenbergMarquardt(
    			double targetTy){
    		double dx=PIXEL_SIZE*(px-getValue(MECH_PAR.mpX0));
    		double dy=PIXEL_SIZE*(py-getValue(MECH_PAR.mpY0));
    		if (zMCurrent!=null){
        		//    		0.25* zM1+ 0.25* zM2+ 0.5 * zM3 = targetZ-getValue(MECH_PAR.z0);
        		//    		0.25* (zM1+dzM)+ 0.25* (zM2+dzM)+ 0.5 * (zM3+dzM) = targetZ-getValue(MECH_PAR.z0);
        		//    		0.25* (dzM+ 0.25* dzM+ 0.5 * dzM = targetZ-getValue(MECH_PAR.z0) - (0.25* zM1+ 0.25* zM2+ 0.5 * zM3 );
        		//    		dzM = targetZ-getValue(MECH_PAR.z0) - (0.25* zM1+ 0.25* zM2+ 0.5 * zM3 );
    			double dZM=targetZ-getValue(MECH_PAR.z0)-(0.25* zMCurrent[0]+ 0.25* zMCurrent[1]+ 0.5 * zMCurrent[2]);
    			double [] zM=zMCurrent.clone();
    			for (int i=0;i<zM.length;i++) zM[i]+=dZM;
    			return zM;
    		}
    		//    		double zc= 0.25* zM1+ 0.25* zM2+ 0.5 * zM3+getValue(MECH_PAR.z0);
    		//    		double zx=dx*(getValue(MECH_PAR.tx)+(2*zM3-zM1-zM2)/(4*getValue(MECH_PAR.Lx))) ;
    		//    		double zy=dy*(getValue(MECH_PAR.ty)-(zM2-zM1)/(2*getValue(MECH_PAR.Ly)));//!
+14 −8
Original line number Diff line number Diff line
@@ -305,6 +305,7 @@ public class LensAdjustment {
        
        public boolean scanTiltEnable=true;  // enable scanning tilt
        public boolean scanTiltReverse=false;  // enable scanning tilt in both directions
        public boolean scanMeasureLast=false;  // Calculate PSF after last move (to original position)
        public int scanTiltRangeX=14336;    // 4 periods
        public int scanTiltRangeY=14336;    // 4 periods
        public int scanTiltStepsX=24;
@@ -520,6 +521,7 @@ public class LensAdjustment {
                
                boolean scanTiltEnable, //=true;  // enable scanning tilt
                boolean scanTiltReverse,
                boolean scanMeasureLast,
                int scanTiltRangeX, //=14336;    // 4 periods
                int scanTiltRangeY, //=14336;    // 4 periods
                int scanTiltStepsX, //=24;
@@ -663,6 +665,7 @@ public class LensAdjustment {
			
			this.scanTiltEnable=scanTiltEnable; //=true;  // enable scanning tilt
			this.scanTiltReverse=scanTiltReverse;
			this.scanMeasureLast=scanMeasureLast;
			this.scanTiltRangeX=scanTiltRangeX; //, //=14336;    // 4 periods
			this.scanTiltRangeY=scanTiltRangeY; //, //=14336;    // 4 periods
			this.scanTiltStepsX=scanTiltStepsX; //=24;
@@ -807,6 +810,7 @@ public class LensAdjustment {
    				
    				this.scanTiltEnable,  // enable scanning tilt
    				this.scanTiltReverse,
    				this.scanMeasureLast,
    	    		this.scanTiltRangeX,    // 4 periods
    	    		this.scanTiltRangeY,    // 4 periods
    	    		this.scanTiltStepsX,
@@ -952,24 +956,18 @@ public class LensAdjustment {
			properties.setProperty(prefix+"scanStep",this.scanStep+"");
			properties.setProperty(prefix+"scanNumber",this.scanNumber+"");
			properties.setProperty(prefix+"scanNumberNegative",this.scanNumberNegative+"");

			properties.setProperty(prefix+"scanHysteresis",this.scanHysteresis+"");
			properties.setProperty(prefix+"scanHysteresisNumber",this.scanHysteresisNumber+"");
			
			properties.setProperty(prefix+"scanTiltEnable",this.scanTiltEnable+"");  // enable scanning tilt
			properties.setProperty(prefix+"scanTiltReverse",this.scanTiltReverse+"");
			
			properties.setProperty(prefix+"scanMeasureLast",this.scanMeasureLast+"");
			properties.setProperty(prefix+"scanTiltRangeX",this.scanTiltRangeX+"");    // 4 periods
			properties.setProperty(prefix+"scanTiltRangeY",this.scanTiltRangeY+"");    // 4 periods
			properties.setProperty(prefix+"scanTiltStepsX",this.scanTiltStepsX+"");
			properties.setProperty(prefix+"scanTiltStepsY",this.scanTiltStepsY+"");
			
			
			properties.setProperty(prefix+"motorHysteresis",this.motorHysteresis+"");
			properties.setProperty(prefix+"measuredHysteresis",this.measuredHysteresis+"");

			properties.setProperty(prefix+"motorCalm",this.motorCalm+"");
			
			properties.setProperty(prefix+"linearReductionRatio",this.linearReductionRatio+"");
			properties.setProperty(prefix+"motorDebug",this.motorDebug+"");
			properties.setProperty(prefix+"lensDistanceNumPoints",this.lensDistanceNumPoints+"");
@@ -1217,6 +1215,9 @@ public class LensAdjustment {
				this.scanTiltReverse=Boolean.parseBoolean(properties.getProperty(prefix+"scanTiltReverse"));
			
			
			if (properties.getProperty(prefix+"scanMeasureLast")!=null)
				this.scanMeasureLast=Boolean.parseBoolean(properties.getProperty(prefix+"scanMeasureLast"));
						
			if (properties.getProperty(prefix+"scanTiltRangeX")!=null)
				this.scanTiltRangeX=Integer.parseInt(properties.getProperty(prefix+"scanTiltRangeX"));
			if (properties.getProperty(prefix+"scanTiltRangeY")!=null)
@@ -1364,7 +1365,7 @@ public class LensAdjustment {

    		gd.addCheckbox    ("Scan for tilt measurement (approximately preserving center)",                    this.scanTiltEnable);
    		gd.addCheckbox    ("Scan for tilt measurement in both directions",                                   this.scanTiltReverse);
    		
    		gd.addCheckbox    ("Calculate PSF after returning to the initial position",                          this.scanMeasureLast);
    		
    		gd.addNumericField("Full range of scanning motors tilting in X-direction",                           this.scanTiltRangeX, 0,7,"motors steps");
    		gd.addNumericField("Full range of scanning motors tilting in Y-direction",                           this.scanTiltRangeY, 0,7,"motors steps");
@@ -1386,6 +1387,8 @@ public class LensAdjustment {

    		this.scanTiltEnable=             gd.getNextBoolean();
    		this.scanTiltReverse=            gd.getNextBoolean();
            this.scanMeasureLast=            gd.getNextBoolean();
    		
    		this.scanTiltRangeX=       (int) gd.getNextNumber();
    		this.scanTiltRangeY=       (int) gd.getNextNumber();
    		this.scanTiltStepsX=       (int) gd.getNextNumber();
@@ -1518,6 +1521,8 @@ public class LensAdjustment {

    		gd.addCheckbox    ("Scan for tilt measurement (approximately preserving center)",                    this.scanTiltEnable);
    		gd.addCheckbox    ("Scan for tilt measurement in both directions",                                   this.scanTiltReverse);
    		gd.addCheckbox    ("Calculate PSF after returning to the initial position",                          this.scanMeasureLast);
    		
    		
    		gd.addNumericField("Full range of scanning motors tilting in X-direction",                           this.scanTiltRangeX, 0,7,"motors steps");
    		gd.addNumericField("Full range of scanning motors tilting in Y-direction",                           this.scanTiltRangeY, 0,7,"motors steps");
@@ -1684,6 +1689,7 @@ public class LensAdjustment {
			
    		this.scanTiltEnable=             gd.getNextBoolean();
    		this.scanTiltReverse=            gd.getNextBoolean();
    		this.scanMeasureLast=            gd.getNextBoolean();
    		this.scanTiltRangeX=       (int) gd.getNextNumber();
    		this.scanTiltRangeY=       (int) gd.getNextNumber();
    		this.scanTiltStepsX=       (int) gd.getNextNumber();