Loading src/main/java/Aberration_Calibration.java +65 −2 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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 Loading @@ -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(); Loading @@ -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); Loading @@ -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(); Loading @@ -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)); Loading Loading @@ -10042,6 +10094,7 @@ if (MORE_BUTTONS) { return null; } if (allOK) { if (focusMeasurementParameters.scanMeasureLast) { allOK &= moveAndMaybeProbe( true, centerMotorPos, // null OK Loading @@ -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+ Loading src/main/java/FocusingField.java +63 −3 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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, Loading Loading @@ -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, Loading @@ -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, Loading Loading @@ -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], Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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)){ Loading @@ -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; Loading Loading @@ -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 Loading @@ -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, Loading @@ -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)));//! Loading src/main/java/LensAdjustment.java +14 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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+""); Loading Loading @@ -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) Loading Loading @@ -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"); Loading @@ -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(); Loading Loading @@ -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"); Loading Loading @@ -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(); Loading Loading
src/main/java/Aberration_Calibration.java +65 −2 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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 Loading @@ -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(); Loading @@ -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); Loading @@ -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(); Loading @@ -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)); Loading Loading @@ -10042,6 +10094,7 @@ if (MORE_BUTTONS) { return null; } if (allOK) { if (focusMeasurementParameters.scanMeasureLast) { allOK &= moveAndMaybeProbe( true, centerMotorPos, // null OK Loading @@ -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+ Loading
src/main/java/FocusingField.java +63 −3 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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, Loading Loading @@ -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, Loading @@ -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, Loading Loading @@ -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], Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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)){ Loading @@ -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; Loading Loading @@ -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 Loading @@ -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, Loading @@ -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)));//! Loading
src/main/java/LensAdjustment.java +14 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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+""); Loading Loading @@ -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) Loading Loading @@ -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"); Loading @@ -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(); Loading Loading @@ -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"); Loading Loading @@ -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(); Loading