Loading src/main/java/Aberration_Calibration.java +116 −22 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; //import FocusingField.FocusingFieldMeasurement; //import FocusingField.MeasuredSample; import Jama.Matrix; // Download here: http://math.nist.gov/javanumerics/jama/ Loading Loading @@ -4388,6 +4389,7 @@ if (MORE_BUTTONS) { String path=dFile+Prefs.getFileSeparator()+lensPrefix+CAMERAS.getLastTimestampUnderscored()+"-focus.csv"; if (MASTER_DEBUG_LEVEL>0) System.out.println ("Saving focusing log data to "+path); MOTORS.listHistory( FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD!=null), path, // on screen, path - to csv FOCUS_MEASUREMENT_PARAMETERS.lensSerial, FOCUS_MEASUREMENT_PARAMETERS.comment, Loading Loading @@ -4473,6 +4475,7 @@ if (MORE_BUTTONS) { if (label.equals("List History")) { DEBUG_LEVEL=MASTER_DEBUG_LEVEL; MOTORS.listHistory( FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD!=null), null, // on screen, path - to csv FOCUS_MEASUREMENT_PARAMETERS.lensSerial, FOCUS_MEASUREMENT_PARAMETERS.comment, Loading Loading @@ -5268,7 +5271,7 @@ if (MORE_BUTTONS) { checkSerialAndRestore(); // returns true if did not change or was restored boolean modeAverage=label.equals("Focus Average"); boolean noTiltScan=true; boolean useLMA=true; // boolean useLMA=true; DEBUG_LEVEL=MASTER_DEBUG_LEVEL; MOTORS.focusingHistory.optimalMotorPosition( // recalculate calibration to estimate current distance from center PSF FOCUS_MEASUREMENT_PARAMETERS, Loading @@ -5285,7 +5288,8 @@ if (MORE_BUTTONS) { } gd.addCheckbox("Erase previous measurement history",modeAverage); gd.addCheckbox("Allow tilt scan when looking for the best fit",!noTiltScan); gd.addCheckbox("Use LMA calculations for focus/tilt",useLMA); gd.addCheckbox ("Use lens aberration model (if available) for focal distance and tilts", FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics); // gd.addCheckbox("Use LMA calculations for focus/tilt",useLMA); double scanMinutes=modeAverage?2.0:30.0; gd.addNumericField("Measure for ", scanMinutes , 1,5," minutes"); gd.showDialog(); Loading @@ -5297,7 +5301,17 @@ if (MORE_BUTTONS) { } if (gd.getNextBoolean()) MOTORS.clearHistory(); noTiltScan=!gd.getNextBoolean(); useLMA=gd.getNextBoolean(); FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics=gd.getNextBoolean(); // Only try to read history if useLMAMetrics is set if (FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD==null)) { if (DEBUG_LEVEL>0) System.out.println("FOCUSING_FIELD==null, trying to restore from the previously saved file"); if (!restoreFocusingHistory(false)) { // try to restore from the saved history file System.out.println("Failed to restore history, disabling use of lens aberration model"); } FOCUSING_FIELD.setDebugLevel(DEBUG_LEVEL); } boolean useLMA=FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD!=null); // int startHistPos=MOTORS.historySize(); scanMinutes=gd.getNextNumber(); long startTime=System.nanoTime(); Loading @@ -5319,6 +5333,14 @@ if (MORE_BUTTONS) { pX0, pY0); } if (useLMA){ FOCUSING_FIELD.testQualB(false); // optimize qualB, store results in this.qualBOptimizationResults if (MASTER_DEBUG_LEVEL>0) { System.out.println("Optimal absolute Zc="+FOCUSING_FIELD.qualBOptimizationResults[0]); System.out.println("Optimal Tx="+FOCUSING_FIELD.qualBOptimizationResults[1]); System.out.println("Optimal Ty="+FOCUSING_FIELD.qualBOptimizationResults[2]); } } while (System.nanoTime()<endTime){ moveAndMaybeProbe( true, // just move, not probe Loading Loading @@ -5350,7 +5372,6 @@ if (MORE_BUTTONS) { } // LMA version FocusingField ff= null; if (useLMA){ ff= new FocusingField( Loading @@ -5371,22 +5392,34 @@ if (MORE_BUTTONS) { ff, (runs==0)?0:(MOTORS.historySize()-runs), MOTORS.historySize()); // all newly acquired // TODO: Remove after checking average /* if (modeAverage && (FOCUSING_FIELD!=null)){ // calculate/show average over the last run - only in "average" mode double [] ZTM=FOCUSING_FIELD.averageZTM(noTiltScan,ff); // no tilt scan - faster double [] ZTM=FOCUSING_FIELD.averageZTM( noTiltScan, ff, // no tilt scan - faster true); // noMotors if (MASTER_DEBUG_LEVEL>0) { String msg="Failed to calulate average focus/tilt"; if (ZTM!=null) msg="Average:\n"+ if (ZTM!=null) { msg="Average:\n"+ "Relative focal shift "+IJ.d2s(ZTM[0],3)+"um (absolute - "+IJ.d2s(ZTM[0]+FOCUSING_FIELD.qualBOptimizationResults[0],3)+"um)\n"+ "Relative horizontal tilt "+IJ.d2s(ZTM[1],3)+"um/mm (absolute - "+IJ.d2s(ZTM[1]+FOCUSING_FIELD.qualBOptimizationResults[1],3)+"um.mm)\n"+ "Relative vertical tilt "+IJ.d2s(ZTM[2],3)+"um/mm (absolute - "+IJ.d2s(ZTM[2]+FOCUSING_FIELD.qualBOptimizationResults[2],3)+"um.mm)\n"+ "Suggested M1 "+IJ.d2s(ZTM[3],0)+"steps\n"+ "Relative vertical tilt "+IJ.d2s(ZTM[2],3)+"um/mm (absolute - "+IJ.d2s(ZTM[2]+FOCUSING_FIELD.qualBOptimizationResults[2],3)+"um.mm)\n"; if (ZTM.length>3) { msg+="Suggested M1 "+IJ.d2s(ZTM[3],0)+"steps\n"+ "Suggested M2 "+IJ.d2s(ZTM[4],0)+"steps\n"+ "Suggested M3 "+IJ.d2s(ZTM[5],0)+"steps"; } } System.out.println(msg); IJ.showMessage(msg); } } */ // } if (FOCUS_MEASUREMENT_PARAMETERS.saveResults) { String dir=getResultsPath(FOCUS_MEASUREMENT_PARAMETERS); File dFile=new File(dir); Loading Loading @@ -5415,6 +5448,7 @@ if (MORE_BUTTONS) { sensorHeight=FOCUSING_FIELD.sensorHeight; } MOTORS.listHistory( useLMA, path, // on screen, path - to csv FOCUS_MEASUREMENT_PARAMETERS.serialNumber, FOCUS_MEASUREMENT_PARAMETERS.lensSerial, Loading Loading @@ -5442,11 +5476,13 @@ if (MORE_BUTTONS) { if (!modeAverage) { double [] lastKT=MOTORS.focusingHistory.temperatureLinearApproximation( useLMA, runs, // number of last samples from history to use, 0 - use all FOCUS_MEASUREMENT_PARAMETERS.lensDistanceWeightK, FOCUS_MEASUREMENT_PARAMETERS.lensDistanceWeightY ); double [] allKT=MOTORS.focusingHistory.temperatureLinearApproximation( useLMA, 0, // number of last samples from history to use, 0 - use all FOCUS_MEASUREMENT_PARAMETERS.lensDistanceWeightK, FOCUS_MEASUREMENT_PARAMETERS.lensDistanceWeightY Loading @@ -5467,6 +5503,7 @@ if (MORE_BUTTONS) { IJ.showMessage("Info",msg); } // Now in LMA mode - recalculate and overwrite /* if (useLMA){ ff= new FocusingField( EYESIS_CAMERA_PARAMETERS.getSensorWidth(), Loading @@ -5486,7 +5523,12 @@ if (MORE_BUTTONS) { if (MASTER_DEBUG_LEVEL>0){ System.out.println ("*** Calculating focal distance shift for each of "+MOTORS.historySize()+" recorded measurments ***"); } double [][] allZTM=FOCUSING_FIELD.getAllZTM(noTiltScan,ff); // no tilt scan (supposed to be adjusted boolean noMotors=true; double [][] allZTM=FOCUSING_FIELD.getAllZTM( noTiltScan, ff, // no tilt scan (supposed to be adjusted noMotors); // boolean noMotors) // do not calculate correction lastKT=MOTORS.focusingHistory.temperatureLinearApproximation( allZTM, runs Loading @@ -5511,6 +5553,7 @@ if (MORE_BUTTONS) { IJ.showMessage("Info",msg); } } */ } saveCurrentConfig(); return; Loading Loading @@ -9125,6 +9168,12 @@ if (MORE_BUTTONS) { double [][][] sampleCoord=null; if (FOCUSING_FIELD!=null){ sampleCoord=FOCUSING_FIELD.getSampleCoord(); FOCUSING_FIELD.testQualB(false); // optimize qualB, store results in this.qualBOptimizationResults if (MASTER_DEBUG_LEVEL>0) { System.out.println("Optimal absolute Zc="+FOCUSING_FIELD.qualBOptimizationResults[0]); System.out.println("Optimal Tx="+FOCUSING_FIELD.qualBOptimizationResults[1]); System.out.println("Optimal Ty="+FOCUSING_FIELD.qualBOptimizationResults[2]); } } else { sampleCoord=FOCUS_MEASUREMENT_PARAMETERS.sampleCoordinates( FOCUS_MEASUREMENT_PARAMETERS.result_PX0, Loading Loading @@ -9154,7 +9203,12 @@ if (MORE_BUTTONS) { //get measurement FocusingField.FocusingFieldMeasurement fFMeasurement=MOTORS.getThisFFMeasurement(FOCUSING_FIELD); // calculate z, tx, ty, m1,m2,m3 double [] zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA(false,fFMeasurement,false); // allow tilt scan double [] zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA( false, // allow tilt scan fFMeasurement, false, // parallel move true, // boolean noQualB, // do not re-claculate testQualB false); // boolean noAdjust); // do not calculate correction // show dialog: Apply, re-calculate, exit int [] currentMotors=fFMeasurement.motors; int [] newMotors=currentMotors.clone(); Loading Loading @@ -9279,7 +9333,13 @@ if (MORE_BUTTONS) { DEBUG_LEVEL=MASTER_DEBUG_LEVEL; FOCUSING_FIELD.setDebugLevel(DEBUG_LEVEL); if (parallelMove){ // ignore/recalculate newMotors data zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA(false,fFMeasurement,true); // recalculate with parallel move only, allow tilt scan zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA( false,// disable tilt scan fFMeasurement, true, // recalculate with parallel move only false, // boolean noQualB, // do not re-claculate testQualB - OPTIMIZE to do once false); // boolean noAdjust); // do not calculate correction newMotors=currentMotors.clone(); if (zTxTyM1M2M3!=null){ newMotors[0]=(int) Math.round(zTxTyM1M2M3[3]); Loading Loading @@ -11114,6 +11174,34 @@ if (MORE_BUTTONS) { debugLevel, loopDebugLevel); // System.out.println(">>"+focusingMotors.historySize()+": "+focusingMotors.curpos[0]+", "+focusingMotors.curpos[1]+", "+focusingMotors.curpos[2]); int ca=6; double [] zTxTy=null; // {Double.NaN,Double.NaN,Double.NaN}; double oldTx=Double.NaN,oldTy=Double.NaN,oldFarNear=Double.NaN; if (metrics!=null ){ oldFarNear=metrics[ca][0]; oldTx= metrics[ca][1]; oldTy= metrics[ca][2]; } if (FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD!=null)){ FocusingField.FocusingFieldMeasurement fFMeasurement= FOCUSING_FIELD.getFocusingFieldMeasurement( ts, //focusingState.getTimestamp(), focusMeasurementParameters.sensorTemperature, focusingMotors.readElphel10364Motors(), //focusingHistory.getPosition(), //null? rFullResults[0]); //focusingState.getSamples()); zTxTy=FOCUSING_FIELD.adjustLMA( true, // false, // noTiltScan fFMeasurement, false, // parallel move true, // boolean noQualB, // do not re-claculate testQualB true); // boolean noAdjust); // do not calculate correction if (zTxTy!=null){ metrics[ca][0]=zTxTy[0]; // was far/near metrics[ca][1]=zTxTy[1]; metrics[ca][2]=zTxTy[2]; } } focusingMotors.addToHistory(ts,focusMeasurementParameters.sensorTemperature,metrics,rFullResults[0]); // System.out.println("focusMeasurementParameters.lensDistanceWeightK="+focusMeasurementParameters.lensDistanceWeightK); Loading @@ -11121,7 +11209,7 @@ if (MORE_BUTTONS) { if ((debugLevel>0) && (metrics!=null)){ // see if lens is calibrated double [] resolutions={1.0/metrics[1][6],1.0/metrics[5][6],1.0/metrics[2][6]}; // R,G,B double fDistance=focusingMotors.focusingHistory.getLensDistance( double fDistanceOld=focusingMotors.focusingHistory.getLensDistance( resolutions, // {R-sharpness,G-sharpness,B-sharpness} true, // boolean absolute, // return absolutely calibrated data focusMeasurementParameters.lensDistanceWeightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives Loading @@ -11129,18 +11217,25 @@ if (MORE_BUTTONS) { debugLevel ); int ca=6; // int ca=6; String sZTxTy=""; if (zTxTy!=null){ sZTxTy="z="+IJ.d2s(zTxTy[0],3)+"um"+" tX="+IJ.d2s(zTxTy[1],3)+"um/mm"+" tY="+IJ.d2s(zTxTy[2],3)+"um/mm"; } int [] actualPosition=focusingMotors.focusingHistory.getPosition(); System.out.println("##"+focusingMotors.historySize()+": "+actualPosition[0]+", "+actualPosition[1]+", "+actualPosition[2]+ ": fDistance="+IJ.d2s(fDistance,3)+"um"+ " Far/Near="+IJ.d2s(metrics[ca][0],3)+ " Tilt X="+IJ.d2s(metrics[ca][1],3)+ " Tilt Y="+IJ.d2s(metrics[ca][2],3)+ ": "+ sZTxTy+ " fDistanceOld="+IJ.d2s(fDistanceOld,3)+"um"+ " Far/Near="+IJ.d2s(oldFarNear,3)+ " Tilt X="+IJ.d2s(oldTx,3)+ " Tilt Y="+IJ.d2s(oldTy,3)+ " R50% average="+IJ.d2s(metrics[ca][3],3)+" sensor pixels,"+ " A50% average="+IJ.d2s(metrics[ca][4],3)+" sensor pixels,"+ " B50% average="+IJ.d2s(metrics[ca][5],3)+" sensor pixels,"+ " R50%Center="+IJ.d2s(metrics[ca][6],3)+" sensor pixels"+ " temp="+focusMeasurementParameters.sensorTemperature); double fDistance=(zTxTy==null)?fDistanceOld:zTxTy[0]; if (debugLevel>1){ String [] compColors={"green","red","blue","green","green","green","AVERAGE"}; for (int c=0;c<metrics.length-1;c++) if (metrics[c]!=null){ Loading @@ -11162,7 +11257,6 @@ if (MORE_BUTTONS) { focusMeasurementParameters.result_B50=metrics[ca][5]; // last measured B50 (simailar, but R^4 are averaged) focusMeasurementParameters.result_RC50=metrics[ca][6]; // last measured RC50(R50 calculated only for the 2 center samples) } } src/main/java/CalibrationHardwareInterface.java +86 −20 Original line number Diff line number Diff line Loading @@ -2977,7 +2977,25 @@ public class CalibrationHardwareInterface { fullResults ); } public FocusingField.FocusingFieldMeasurement getThisFFMeasurement( FocusingField focusingField, String sTimestamp, double temperature, double[][] psfMetrics, double [][][][] fullResults){ return focusingField.getFocusingFieldMeasurement( sTimestamp, //focusingState.getTimestamp(), temperature, //focusingState.getTemperature(), this.curpos, //focusingState.motorsPos, fullResults); //focusingState.getSamples()); } /* * FocusingHistory.FocusingState focusingState public void addToHistory( String sTimestamp,double temperature, double[][] psfMetrics){ // null OK this.focusingHistory.add( sTimestamp, Loading @@ -3004,6 +3022,7 @@ public class CalibrationHardwareInterface { } public void listHistory( boolean useLMA, String path, String lensSerial, String comment, Loading @@ -3015,6 +3034,7 @@ public class CalibrationHardwareInterface { double weightY // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution ){ listHistory( useLMA, path, "", lensSerial, Loading @@ -3033,6 +3053,7 @@ public class CalibrationHardwareInterface { } public void listHistory( boolean useLMA, String path, String serialNumber, String lensSerial, Loading @@ -3051,6 +3072,7 @@ public class CalibrationHardwareInterface { ){ this.focusingHistory.list( useLMA, path, serialNumber, lensSerial, Loading Loading @@ -3084,6 +3106,7 @@ public class CalibrationHardwareInterface { pY0, sampleCoord); } public FocusingField.FocusingFieldMeasurement getThisFFMeasurement(FocusingField focusingField){ return getThisFFMeasurement(focusingField, -1); } Loading Loading @@ -3899,6 +3922,14 @@ public class CalibrationHardwareInterface { if ((index<0) || (index>=this.history.size())) return null; return this.history.get(index).getCenterResolutions(); } public double [] getzTxTy(int index){ if ((index<0) || (index>=this.history.size())) return null; return this.history.get(index).getzTxTy(); } public double [] getzTxTy(){ if (this.history.size()<1) return null; return getzTxTy(this.history.size()-1); } public int size(){ return this.history.size(); } Loading Loading @@ -5067,6 +5098,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " * @return array of 2 elements - {length at 0C, microns/degree} */ public double [] temperatureLinearApproximation( boolean useLMA, int numSamples, // number of last samples from history to use, 0 - use all double lensDistanceWeightK, // used in distance calculation double lensDistanceWeightY // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution Loading @@ -5079,8 +5111,11 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " int firstSample=this.history.size()-numSamples; for (int nSample=0;nSample<numSamples;nSample++){ resolutions= this.history.get(firstSample+nSample).getCenterResolutions(); data[nSample][0]=this.history.get(firstSample+nSample).getTemperature(); if (useLMA){ data[nSample][1]=this.history.get(firstSample+nSample).getzTxTy()[0]; } else { resolutions= this.history.get(firstSample+nSample).getCenterResolutions(); data[nSample][1]=getLensDistance( resolutions, // {R-sharpness,G-sharpness,B-sharpness} true, // boolean absolute, // return absolutely calibrated data Loading @@ -5089,6 +5124,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " 1 //debugLevel ); } } PolynomialApproximation pa= new PolynomialApproximation(debugLevel); double [] polyCoeff=pa.polynomialApproximation1d(data, 1); // just linear return polyCoeff; Loading Loading @@ -5524,6 +5560,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " // todo - add "probe around" - 6/3 points, +/- for each direction (fraction of sigma?) public void list( boolean useLMA, String path, String lensSerial, // if null - do not add average String comment, Loading @@ -5533,8 +5570,10 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " double weightRatioBlueToGreen, double weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives double weightY){ // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution list (path, "", list ( useLMA, path, "", // serial; number lensSerial, // if null - do not add average comment, showIndividualComponents, Loading Loading @@ -5641,6 +5680,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " } public void list( boolean useLMA, String path, String serialNumber, String lensSerial, // if null - do not add average Loading Loading @@ -5701,15 +5741,22 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " if (showIndividualComponents) { for (int i=0;i<this.history.size();i++){ FocusingState focusingState=this.history.get(i); double [] zTxTy=useLMA?focusingState.getzTxTy():null; double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen); double [][] resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen); double dist= getLensDistance( double dist= (zTxTy==null)?getLensDistance( focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness} true, //boolean absolute, // return absolutely calibrated data weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives weightY, // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution 1); //int debugLevel 1): //int debugLevel zTxTy[0]; double [] averageMetrics=metrics[3]; if (zTxTy!=null){ averageMetrics=metrics[3].clone(); // to modify w/o changing original averageMetrics[1]=zTxTy[1]; // tiltX averageMetrics[2]=zTxTy[2]; // tiltY } double [] averageResolution=resolution[3]; sb.append((i+1)+"\t"); String timestamp=focusingState.getTimestamp(); Loading Loading @@ -5779,9 +5826,15 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " for (int i=0;i<this.history.size();i++){ // int parIndex=0; FocusingState focusingState=this.history.get(i); double [] zTxTy=useLMA?focusingState.getzTxTy():null; double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen); double [][] resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen); double [] averageMetrics=metrics[3]; if (zTxTy!=null){ averageMetrics=metrics[3].clone(); // to modify w/o changing original averageMetrics[1]=zTxTy[1]; // tiltX averageMetrics[2]=zTxTy[2]; // tiltY } double [] averageResolution=resolution[3]; if (!justSummary) sb.append((i+1)+"\t"); String timestamp=focusingState.getTimestamp(); Loading @@ -5806,12 +5859,13 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " sums[4]+=focusingState.motorsPos[0]; sums[5]+=focusingState.motorsPos[1]; sums[6]+=focusingState.motorsPos[2]; double dist= getLensDistance( double dist= (zTxTy==null)?getLensDistance( focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness} true, //boolean absolute, // return absolutely calibrated data weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives weightY, // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution 1); //int debugLevel 1): //int debugLevel zTxTy[0]; if (Double.isNaN(dist)){ if (!justSummary) sb.append("\t---"); } else { Loading Loading @@ -6199,7 +6253,19 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " 1.0, weightRatioBlueToGreen); } // alternative mode (from aberration model) ising metrics[6][] public double [] getzTxTy(){ if (this.psfMetricses==null){ return null; } if ((this.psfMetricses.length<7) || (this.psfMetricses[6]==null)) { System.out.println("BUG? psfMetrics does not have line 6 with lens berration model z, tx, ty"); return null; } double [] zTxTy={this.psfMetricses[6][0],this.psfMetricses[6][1],this.psfMetricses[6][2]}; return zTxTy; } public double [][] getMetrics( double weightRed, double weightGreen, Loading src/main/java/FocusingField.java +73 −56 File changed.Preview size limit exceeded, changes collapsed. Show changes src/main/java/LensAdjustment.java +12 −1 Original line number Diff line number Diff line Loading @@ -195,6 +195,7 @@ public class LensAdjustment { public String gridGeometryFile=""; public String initialCalibrationFile=""; public String focusingHistoryFile=""; public boolean useLMAMetrics=true; // measure/report focal distance and tilts using lens model/LMA (when available) public String strategyFile=""; public String resultsSuperDirectory=""; // directory with subdirectories named as serial numbers to stro results public int EEPROM_channel=1; // EEPROM channel to read serial number from Loading Loading @@ -430,6 +431,7 @@ public class LensAdjustment { String strategyFile, String resultsSuperDirectory, // directory with subdirectories named as serial numbers to stro results String focusingHistoryFile, boolean useLMAMetrics, // measure/report focal distance and tilts using lens model/LMA (when available) int EEPROM_channel, // EEPROM channel to read serial number from boolean saveResults, // save focusing results boolean showResults, // show focusing (includingh intermediate) results Loading Loading @@ -577,6 +579,7 @@ public class LensAdjustment { this.strategyFile=strategyFile; this.resultsSuperDirectory=resultsSuperDirectory; // directory with subdirectories named as serial numbers to stro results this.focusingHistoryFile=focusingHistoryFile; this.useLMAMetrics=useLMAMetrics; // measure/report focal distance and tilts using lens model/LMA (when available) this.EEPROM_channel=EEPROM_channel; // EEPROM channel to read serial number from this.saveResults=saveResults; // save focusing results this.showResults=showResults; // show focusing (includingh intermediate) results Loading Loading @@ -725,6 +728,7 @@ public class LensAdjustment { this.strategyFile, this.resultsSuperDirectory, // directory with subdirectories named as serial numbers to stro results this.focusingHistoryFile, this.useLMAMetrics, // measure/report focal distance and tilts using lens model/LMA (when available) this.EEPROM_channel,// EEPROM channel to read serial number from this.saveResults, // save focusing results this.showResults, // show focusing (includingh intermediate) results Loading Loading @@ -871,6 +875,7 @@ public class LensAdjustment { properties.setProperty(prefix+"strategyFile",this.strategyFile+""); properties.setProperty(prefix+"resultsSuperDirectory",this.resultsSuperDirectory+""); properties.setProperty(prefix+"focusingHistoryFile",this.focusingHistoryFile+""); properties.setProperty(prefix+"useLMAMetrics",this.useLMAMetrics+""); properties.setProperty(prefix+"serialNumber",this.serialNumber+""); if (!Double.isNaN(this.sensorTemperature))properties.setProperty(prefix+"sensorTemperature",this.sensorTemperature+""); if (!Double.isNaN(this.result_lastKT))properties.setProperty(prefix+"result_lastKT",this.result_lastKT+""); Loading Loading @@ -1030,6 +1035,9 @@ public class LensAdjustment { if (properties.getProperty(prefix+"focusingHistoryFile")!=null) this.focusingHistoryFile=properties.getProperty(prefix+"focusingHistoryFile"); if (properties.getProperty(prefix+"useLMAMetrics")!=null) this.useLMAMetrics=Boolean.parseBoolean(properties.getProperty(prefix+"useLMAMetrics")); if (properties.getProperty(prefix+"serialNumber")!=null) this.serialNumber=properties.getProperty(prefix+"serialNumber"); // this.serialNumber is only written, but never read from the configuration file (only from devivce) Loading Loading @@ -1441,7 +1449,8 @@ public class LensAdjustment { gd.addStringField ("Initial camera intrinsic/extrinsic parametres file", this.initialCalibrationFile,40); gd.addStringField ("Levenberg-Marquardt algorithm strategy file", this.strategyFile,40); gd.addStringField ("Focusing results superdirectory (individual will be named by serial numbers)", this.resultsSuperDirectory,40); gd.addStringField ("Measurement history (acquired during \"Scan Calib LMA\" file", this.focusingHistoryFile,80); gd.addStringField ("Measurement history (acquired during \"Scan Calib LMA\") file", this.focusingHistoryFile,80); gd.addCheckbox ("Use lens aberration model (if available) for focal distance and tilts", this.useLMAMetrics); gd.addNumericField("EEPROM channel to read sensor serial number from", this.EEPROM_channel, 0,4,""); gd.addCheckbox ("Save SFE focusing results (including intermediate) ", this.saveResults); gd.addCheckbox ("Show SFE focusing results (including intermediate) ", this.showResults); Loading Loading @@ -1618,6 +1627,8 @@ public class LensAdjustment { this.strategyFile= gd.getNextString(); this.resultsSuperDirectory= gd.getNextString(); this.focusingHistoryFile= gd.getNextString(); this.useLMAMetrics = gd.getNextBoolean(); this.EEPROM_channel= (int) gd.getNextNumber(); this.saveResults= gd.getNextBoolean(); this.showResults= gd.getNextBoolean(); Loading Loading
src/main/java/Aberration_Calibration.java +116 −22 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; //import FocusingField.FocusingFieldMeasurement; //import FocusingField.MeasuredSample; import Jama.Matrix; // Download here: http://math.nist.gov/javanumerics/jama/ Loading Loading @@ -4388,6 +4389,7 @@ if (MORE_BUTTONS) { String path=dFile+Prefs.getFileSeparator()+lensPrefix+CAMERAS.getLastTimestampUnderscored()+"-focus.csv"; if (MASTER_DEBUG_LEVEL>0) System.out.println ("Saving focusing log data to "+path); MOTORS.listHistory( FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD!=null), path, // on screen, path - to csv FOCUS_MEASUREMENT_PARAMETERS.lensSerial, FOCUS_MEASUREMENT_PARAMETERS.comment, Loading Loading @@ -4473,6 +4475,7 @@ if (MORE_BUTTONS) { if (label.equals("List History")) { DEBUG_LEVEL=MASTER_DEBUG_LEVEL; MOTORS.listHistory( FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD!=null), null, // on screen, path - to csv FOCUS_MEASUREMENT_PARAMETERS.lensSerial, FOCUS_MEASUREMENT_PARAMETERS.comment, Loading Loading @@ -5268,7 +5271,7 @@ if (MORE_BUTTONS) { checkSerialAndRestore(); // returns true if did not change or was restored boolean modeAverage=label.equals("Focus Average"); boolean noTiltScan=true; boolean useLMA=true; // boolean useLMA=true; DEBUG_LEVEL=MASTER_DEBUG_LEVEL; MOTORS.focusingHistory.optimalMotorPosition( // recalculate calibration to estimate current distance from center PSF FOCUS_MEASUREMENT_PARAMETERS, Loading @@ -5285,7 +5288,8 @@ if (MORE_BUTTONS) { } gd.addCheckbox("Erase previous measurement history",modeAverage); gd.addCheckbox("Allow tilt scan when looking for the best fit",!noTiltScan); gd.addCheckbox("Use LMA calculations for focus/tilt",useLMA); gd.addCheckbox ("Use lens aberration model (if available) for focal distance and tilts", FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics); // gd.addCheckbox("Use LMA calculations for focus/tilt",useLMA); double scanMinutes=modeAverage?2.0:30.0; gd.addNumericField("Measure for ", scanMinutes , 1,5," minutes"); gd.showDialog(); Loading @@ -5297,7 +5301,17 @@ if (MORE_BUTTONS) { } if (gd.getNextBoolean()) MOTORS.clearHistory(); noTiltScan=!gd.getNextBoolean(); useLMA=gd.getNextBoolean(); FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics=gd.getNextBoolean(); // Only try to read history if useLMAMetrics is set if (FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD==null)) { if (DEBUG_LEVEL>0) System.out.println("FOCUSING_FIELD==null, trying to restore from the previously saved file"); if (!restoreFocusingHistory(false)) { // try to restore from the saved history file System.out.println("Failed to restore history, disabling use of lens aberration model"); } FOCUSING_FIELD.setDebugLevel(DEBUG_LEVEL); } boolean useLMA=FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD!=null); // int startHistPos=MOTORS.historySize(); scanMinutes=gd.getNextNumber(); long startTime=System.nanoTime(); Loading @@ -5319,6 +5333,14 @@ if (MORE_BUTTONS) { pX0, pY0); } if (useLMA){ FOCUSING_FIELD.testQualB(false); // optimize qualB, store results in this.qualBOptimizationResults if (MASTER_DEBUG_LEVEL>0) { System.out.println("Optimal absolute Zc="+FOCUSING_FIELD.qualBOptimizationResults[0]); System.out.println("Optimal Tx="+FOCUSING_FIELD.qualBOptimizationResults[1]); System.out.println("Optimal Ty="+FOCUSING_FIELD.qualBOptimizationResults[2]); } } while (System.nanoTime()<endTime){ moveAndMaybeProbe( true, // just move, not probe Loading Loading @@ -5350,7 +5372,6 @@ if (MORE_BUTTONS) { } // LMA version FocusingField ff= null; if (useLMA){ ff= new FocusingField( Loading @@ -5371,22 +5392,34 @@ if (MORE_BUTTONS) { ff, (runs==0)?0:(MOTORS.historySize()-runs), MOTORS.historySize()); // all newly acquired // TODO: Remove after checking average /* if (modeAverage && (FOCUSING_FIELD!=null)){ // calculate/show average over the last run - only in "average" mode double [] ZTM=FOCUSING_FIELD.averageZTM(noTiltScan,ff); // no tilt scan - faster double [] ZTM=FOCUSING_FIELD.averageZTM( noTiltScan, ff, // no tilt scan - faster true); // noMotors if (MASTER_DEBUG_LEVEL>0) { String msg="Failed to calulate average focus/tilt"; if (ZTM!=null) msg="Average:\n"+ if (ZTM!=null) { msg="Average:\n"+ "Relative focal shift "+IJ.d2s(ZTM[0],3)+"um (absolute - "+IJ.d2s(ZTM[0]+FOCUSING_FIELD.qualBOptimizationResults[0],3)+"um)\n"+ "Relative horizontal tilt "+IJ.d2s(ZTM[1],3)+"um/mm (absolute - "+IJ.d2s(ZTM[1]+FOCUSING_FIELD.qualBOptimizationResults[1],3)+"um.mm)\n"+ "Relative vertical tilt "+IJ.d2s(ZTM[2],3)+"um/mm (absolute - "+IJ.d2s(ZTM[2]+FOCUSING_FIELD.qualBOptimizationResults[2],3)+"um.mm)\n"+ "Suggested M1 "+IJ.d2s(ZTM[3],0)+"steps\n"+ "Relative vertical tilt "+IJ.d2s(ZTM[2],3)+"um/mm (absolute - "+IJ.d2s(ZTM[2]+FOCUSING_FIELD.qualBOptimizationResults[2],3)+"um.mm)\n"; if (ZTM.length>3) { msg+="Suggested M1 "+IJ.d2s(ZTM[3],0)+"steps\n"+ "Suggested M2 "+IJ.d2s(ZTM[4],0)+"steps\n"+ "Suggested M3 "+IJ.d2s(ZTM[5],0)+"steps"; } } System.out.println(msg); IJ.showMessage(msg); } } */ // } if (FOCUS_MEASUREMENT_PARAMETERS.saveResults) { String dir=getResultsPath(FOCUS_MEASUREMENT_PARAMETERS); File dFile=new File(dir); Loading Loading @@ -5415,6 +5448,7 @@ if (MORE_BUTTONS) { sensorHeight=FOCUSING_FIELD.sensorHeight; } MOTORS.listHistory( useLMA, path, // on screen, path - to csv FOCUS_MEASUREMENT_PARAMETERS.serialNumber, FOCUS_MEASUREMENT_PARAMETERS.lensSerial, Loading Loading @@ -5442,11 +5476,13 @@ if (MORE_BUTTONS) { if (!modeAverage) { double [] lastKT=MOTORS.focusingHistory.temperatureLinearApproximation( useLMA, runs, // number of last samples from history to use, 0 - use all FOCUS_MEASUREMENT_PARAMETERS.lensDistanceWeightK, FOCUS_MEASUREMENT_PARAMETERS.lensDistanceWeightY ); double [] allKT=MOTORS.focusingHistory.temperatureLinearApproximation( useLMA, 0, // number of last samples from history to use, 0 - use all FOCUS_MEASUREMENT_PARAMETERS.lensDistanceWeightK, FOCUS_MEASUREMENT_PARAMETERS.lensDistanceWeightY Loading @@ -5467,6 +5503,7 @@ if (MORE_BUTTONS) { IJ.showMessage("Info",msg); } // Now in LMA mode - recalculate and overwrite /* if (useLMA){ ff= new FocusingField( EYESIS_CAMERA_PARAMETERS.getSensorWidth(), Loading @@ -5486,7 +5523,12 @@ if (MORE_BUTTONS) { if (MASTER_DEBUG_LEVEL>0){ System.out.println ("*** Calculating focal distance shift for each of "+MOTORS.historySize()+" recorded measurments ***"); } double [][] allZTM=FOCUSING_FIELD.getAllZTM(noTiltScan,ff); // no tilt scan (supposed to be adjusted boolean noMotors=true; double [][] allZTM=FOCUSING_FIELD.getAllZTM( noTiltScan, ff, // no tilt scan (supposed to be adjusted noMotors); // boolean noMotors) // do not calculate correction lastKT=MOTORS.focusingHistory.temperatureLinearApproximation( allZTM, runs Loading @@ -5511,6 +5553,7 @@ if (MORE_BUTTONS) { IJ.showMessage("Info",msg); } } */ } saveCurrentConfig(); return; Loading Loading @@ -9125,6 +9168,12 @@ if (MORE_BUTTONS) { double [][][] sampleCoord=null; if (FOCUSING_FIELD!=null){ sampleCoord=FOCUSING_FIELD.getSampleCoord(); FOCUSING_FIELD.testQualB(false); // optimize qualB, store results in this.qualBOptimizationResults if (MASTER_DEBUG_LEVEL>0) { System.out.println("Optimal absolute Zc="+FOCUSING_FIELD.qualBOptimizationResults[0]); System.out.println("Optimal Tx="+FOCUSING_FIELD.qualBOptimizationResults[1]); System.out.println("Optimal Ty="+FOCUSING_FIELD.qualBOptimizationResults[2]); } } else { sampleCoord=FOCUS_MEASUREMENT_PARAMETERS.sampleCoordinates( FOCUS_MEASUREMENT_PARAMETERS.result_PX0, Loading Loading @@ -9154,7 +9203,12 @@ if (MORE_BUTTONS) { //get measurement FocusingField.FocusingFieldMeasurement fFMeasurement=MOTORS.getThisFFMeasurement(FOCUSING_FIELD); // calculate z, tx, ty, m1,m2,m3 double [] zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA(false,fFMeasurement,false); // allow tilt scan double [] zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA( false, // allow tilt scan fFMeasurement, false, // parallel move true, // boolean noQualB, // do not re-claculate testQualB false); // boolean noAdjust); // do not calculate correction // show dialog: Apply, re-calculate, exit int [] currentMotors=fFMeasurement.motors; int [] newMotors=currentMotors.clone(); Loading Loading @@ -9279,7 +9333,13 @@ if (MORE_BUTTONS) { DEBUG_LEVEL=MASTER_DEBUG_LEVEL; FOCUSING_FIELD.setDebugLevel(DEBUG_LEVEL); if (parallelMove){ // ignore/recalculate newMotors data zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA(false,fFMeasurement,true); // recalculate with parallel move only, allow tilt scan zTxTyM1M2M3 = FOCUSING_FIELD.adjustLMA( false,// disable tilt scan fFMeasurement, true, // recalculate with parallel move only false, // boolean noQualB, // do not re-claculate testQualB - OPTIMIZE to do once false); // boolean noAdjust); // do not calculate correction newMotors=currentMotors.clone(); if (zTxTyM1M2M3!=null){ newMotors[0]=(int) Math.round(zTxTyM1M2M3[3]); Loading Loading @@ -11114,6 +11174,34 @@ if (MORE_BUTTONS) { debugLevel, loopDebugLevel); // System.out.println(">>"+focusingMotors.historySize()+": "+focusingMotors.curpos[0]+", "+focusingMotors.curpos[1]+", "+focusingMotors.curpos[2]); int ca=6; double [] zTxTy=null; // {Double.NaN,Double.NaN,Double.NaN}; double oldTx=Double.NaN,oldTy=Double.NaN,oldFarNear=Double.NaN; if (metrics!=null ){ oldFarNear=metrics[ca][0]; oldTx= metrics[ca][1]; oldTy= metrics[ca][2]; } if (FOCUS_MEASUREMENT_PARAMETERS.useLMAMetrics && (FOCUSING_FIELD!=null)){ FocusingField.FocusingFieldMeasurement fFMeasurement= FOCUSING_FIELD.getFocusingFieldMeasurement( ts, //focusingState.getTimestamp(), focusMeasurementParameters.sensorTemperature, focusingMotors.readElphel10364Motors(), //focusingHistory.getPosition(), //null? rFullResults[0]); //focusingState.getSamples()); zTxTy=FOCUSING_FIELD.adjustLMA( true, // false, // noTiltScan fFMeasurement, false, // parallel move true, // boolean noQualB, // do not re-claculate testQualB true); // boolean noAdjust); // do not calculate correction if (zTxTy!=null){ metrics[ca][0]=zTxTy[0]; // was far/near metrics[ca][1]=zTxTy[1]; metrics[ca][2]=zTxTy[2]; } } focusingMotors.addToHistory(ts,focusMeasurementParameters.sensorTemperature,metrics,rFullResults[0]); // System.out.println("focusMeasurementParameters.lensDistanceWeightK="+focusMeasurementParameters.lensDistanceWeightK); Loading @@ -11121,7 +11209,7 @@ if (MORE_BUTTONS) { if ((debugLevel>0) && (metrics!=null)){ // see if lens is calibrated double [] resolutions={1.0/metrics[1][6],1.0/metrics[5][6],1.0/metrics[2][6]}; // R,G,B double fDistance=focusingMotors.focusingHistory.getLensDistance( double fDistanceOld=focusingMotors.focusingHistory.getLensDistance( resolutions, // {R-sharpness,G-sharpness,B-sharpness} true, // boolean absolute, // return absolutely calibrated data focusMeasurementParameters.lensDistanceWeightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives Loading @@ -11129,18 +11217,25 @@ if (MORE_BUTTONS) { debugLevel ); int ca=6; // int ca=6; String sZTxTy=""; if (zTxTy!=null){ sZTxTy="z="+IJ.d2s(zTxTy[0],3)+"um"+" tX="+IJ.d2s(zTxTy[1],3)+"um/mm"+" tY="+IJ.d2s(zTxTy[2],3)+"um/mm"; } int [] actualPosition=focusingMotors.focusingHistory.getPosition(); System.out.println("##"+focusingMotors.historySize()+": "+actualPosition[0]+", "+actualPosition[1]+", "+actualPosition[2]+ ": fDistance="+IJ.d2s(fDistance,3)+"um"+ " Far/Near="+IJ.d2s(metrics[ca][0],3)+ " Tilt X="+IJ.d2s(metrics[ca][1],3)+ " Tilt Y="+IJ.d2s(metrics[ca][2],3)+ ": "+ sZTxTy+ " fDistanceOld="+IJ.d2s(fDistanceOld,3)+"um"+ " Far/Near="+IJ.d2s(oldFarNear,3)+ " Tilt X="+IJ.d2s(oldTx,3)+ " Tilt Y="+IJ.d2s(oldTy,3)+ " R50% average="+IJ.d2s(metrics[ca][3],3)+" sensor pixels,"+ " A50% average="+IJ.d2s(metrics[ca][4],3)+" sensor pixels,"+ " B50% average="+IJ.d2s(metrics[ca][5],3)+" sensor pixels,"+ " R50%Center="+IJ.d2s(metrics[ca][6],3)+" sensor pixels"+ " temp="+focusMeasurementParameters.sensorTemperature); double fDistance=(zTxTy==null)?fDistanceOld:zTxTy[0]; if (debugLevel>1){ String [] compColors={"green","red","blue","green","green","green","AVERAGE"}; for (int c=0;c<metrics.length-1;c++) if (metrics[c]!=null){ Loading @@ -11162,7 +11257,6 @@ if (MORE_BUTTONS) { focusMeasurementParameters.result_B50=metrics[ca][5]; // last measured B50 (simailar, but R^4 are averaged) focusMeasurementParameters.result_RC50=metrics[ca][6]; // last measured RC50(R50 calculated only for the 2 center samples) } }
src/main/java/CalibrationHardwareInterface.java +86 −20 Original line number Diff line number Diff line Loading @@ -2977,7 +2977,25 @@ public class CalibrationHardwareInterface { fullResults ); } public FocusingField.FocusingFieldMeasurement getThisFFMeasurement( FocusingField focusingField, String sTimestamp, double temperature, double[][] psfMetrics, double [][][][] fullResults){ return focusingField.getFocusingFieldMeasurement( sTimestamp, //focusingState.getTimestamp(), temperature, //focusingState.getTemperature(), this.curpos, //focusingState.motorsPos, fullResults); //focusingState.getSamples()); } /* * FocusingHistory.FocusingState focusingState public void addToHistory( String sTimestamp,double temperature, double[][] psfMetrics){ // null OK this.focusingHistory.add( sTimestamp, Loading @@ -3004,6 +3022,7 @@ public class CalibrationHardwareInterface { } public void listHistory( boolean useLMA, String path, String lensSerial, String comment, Loading @@ -3015,6 +3034,7 @@ public class CalibrationHardwareInterface { double weightY // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution ){ listHistory( useLMA, path, "", lensSerial, Loading @@ -3033,6 +3053,7 @@ public class CalibrationHardwareInterface { } public void listHistory( boolean useLMA, String path, String serialNumber, String lensSerial, Loading @@ -3051,6 +3072,7 @@ public class CalibrationHardwareInterface { ){ this.focusingHistory.list( useLMA, path, serialNumber, lensSerial, Loading Loading @@ -3084,6 +3106,7 @@ public class CalibrationHardwareInterface { pY0, sampleCoord); } public FocusingField.FocusingFieldMeasurement getThisFFMeasurement(FocusingField focusingField){ return getThisFFMeasurement(focusingField, -1); } Loading Loading @@ -3899,6 +3922,14 @@ public class CalibrationHardwareInterface { if ((index<0) || (index>=this.history.size())) return null; return this.history.get(index).getCenterResolutions(); } public double [] getzTxTy(int index){ if ((index<0) || (index>=this.history.size())) return null; return this.history.get(index).getzTxTy(); } public double [] getzTxTy(){ if (this.history.size()<1) return null; return getzTxTy(this.history.size()-1); } public int size(){ return this.history.size(); } Loading Loading @@ -5067,6 +5098,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " * @return array of 2 elements - {length at 0C, microns/degree} */ public double [] temperatureLinearApproximation( boolean useLMA, int numSamples, // number of last samples from history to use, 0 - use all double lensDistanceWeightK, // used in distance calculation double lensDistanceWeightY // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution Loading @@ -5079,8 +5111,11 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " int firstSample=this.history.size()-numSamples; for (int nSample=0;nSample<numSamples;nSample++){ resolutions= this.history.get(firstSample+nSample).getCenterResolutions(); data[nSample][0]=this.history.get(firstSample+nSample).getTemperature(); if (useLMA){ data[nSample][1]=this.history.get(firstSample+nSample).getzTxTy()[0]; } else { resolutions= this.history.get(firstSample+nSample).getCenterResolutions(); data[nSample][1]=getLensDistance( resolutions, // {R-sharpness,G-sharpness,B-sharpness} true, // boolean absolute, // return absolutely calibrated data Loading @@ -5089,6 +5124,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " 1 //debugLevel ); } } PolynomialApproximation pa= new PolynomialApproximation(debugLevel); double [] polyCoeff=pa.polynomialApproximation1d(data, 1); // just linear return polyCoeff; Loading Loading @@ -5524,6 +5560,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " // todo - add "probe around" - 6/3 points, +/- for each direction (fraction of sigma?) public void list( boolean useLMA, String path, String lensSerial, // if null - do not add average String comment, Loading @@ -5533,8 +5570,10 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " double weightRatioBlueToGreen, double weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives double weightY){ // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution list (path, "", list ( useLMA, path, "", // serial; number lensSerial, // if null - do not add average comment, showIndividualComponents, Loading Loading @@ -5641,6 +5680,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " } public void list( boolean useLMA, String path, String serialNumber, String lensSerial, // if null - do not add average Loading Loading @@ -5701,15 +5741,22 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " if (showIndividualComponents) { for (int i=0;i<this.history.size();i++){ FocusingState focusingState=this.history.get(i); double [] zTxTy=useLMA?focusingState.getzTxTy():null; double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen); double [][] resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen); double dist= getLensDistance( double dist= (zTxTy==null)?getLensDistance( focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness} true, //boolean absolute, // return absolutely calibrated data weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives weightY, // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution 1); //int debugLevel 1): //int debugLevel zTxTy[0]; double [] averageMetrics=metrics[3]; if (zTxTy!=null){ averageMetrics=metrics[3].clone(); // to modify w/o changing original averageMetrics[1]=zTxTy[1]; // tiltX averageMetrics[2]=zTxTy[2]; // tiltY } double [] averageResolution=resolution[3]; sb.append((i+1)+"\t"); String timestamp=focusingState.getTimestamp(); Loading Loading @@ -5779,9 +5826,15 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " for (int i=0;i<this.history.size();i++){ // int parIndex=0; FocusingState focusingState=this.history.get(i); double [] zTxTy=useLMA?focusingState.getzTxTy():null; double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen); double [][] resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen); double [] averageMetrics=metrics[3]; if (zTxTy!=null){ averageMetrics=metrics[3].clone(); // to modify w/o changing original averageMetrics[1]=zTxTy[1]; // tiltX averageMetrics[2]=zTxTy[2]; // tiltY } double [] averageResolution=resolution[3]; if (!justSummary) sb.append((i+1)+"\t"); String timestamp=focusingState.getTimestamp(); Loading @@ -5806,12 +5859,13 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " sums[4]+=focusingState.motorsPos[0]; sums[5]+=focusingState.motorsPos[1]; sums[6]+=focusingState.motorsPos[2]; double dist= getLensDistance( double dist= (zTxTy==null)?getLensDistance( focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness} true, //boolean absolute, // return absolutely calibrated data weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives weightY, // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution 1); //int debugLevel 1): //int debugLevel zTxTy[0]; if (Double.isNaN(dist)){ if (!justSummary) sb.append("\t---"); } else { Loading Loading @@ -6199,7 +6253,19 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " 1.0, weightRatioBlueToGreen); } // alternative mode (from aberration model) ising metrics[6][] public double [] getzTxTy(){ if (this.psfMetricses==null){ return null; } if ((this.psfMetricses.length<7) || (this.psfMetricses[6]==null)) { System.out.println("BUG? psfMetrics does not have line 6 with lens berration model z, tx, ty"); return null; } double [] zTxTy={this.psfMetricses[6][0],this.psfMetricses[6][1],this.psfMetricses[6][2]}; return zTxTy; } public double [][] getMetrics( double weightRed, double weightGreen, Loading
src/main/java/FocusingField.java +73 −56 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/main/java/LensAdjustment.java +12 −1 Original line number Diff line number Diff line Loading @@ -195,6 +195,7 @@ public class LensAdjustment { public String gridGeometryFile=""; public String initialCalibrationFile=""; public String focusingHistoryFile=""; public boolean useLMAMetrics=true; // measure/report focal distance and tilts using lens model/LMA (when available) public String strategyFile=""; public String resultsSuperDirectory=""; // directory with subdirectories named as serial numbers to stro results public int EEPROM_channel=1; // EEPROM channel to read serial number from Loading Loading @@ -430,6 +431,7 @@ public class LensAdjustment { String strategyFile, String resultsSuperDirectory, // directory with subdirectories named as serial numbers to stro results String focusingHistoryFile, boolean useLMAMetrics, // measure/report focal distance and tilts using lens model/LMA (when available) int EEPROM_channel, // EEPROM channel to read serial number from boolean saveResults, // save focusing results boolean showResults, // show focusing (includingh intermediate) results Loading Loading @@ -577,6 +579,7 @@ public class LensAdjustment { this.strategyFile=strategyFile; this.resultsSuperDirectory=resultsSuperDirectory; // directory with subdirectories named as serial numbers to stro results this.focusingHistoryFile=focusingHistoryFile; this.useLMAMetrics=useLMAMetrics; // measure/report focal distance and tilts using lens model/LMA (when available) this.EEPROM_channel=EEPROM_channel; // EEPROM channel to read serial number from this.saveResults=saveResults; // save focusing results this.showResults=showResults; // show focusing (includingh intermediate) results Loading Loading @@ -725,6 +728,7 @@ public class LensAdjustment { this.strategyFile, this.resultsSuperDirectory, // directory with subdirectories named as serial numbers to stro results this.focusingHistoryFile, this.useLMAMetrics, // measure/report focal distance and tilts using lens model/LMA (when available) this.EEPROM_channel,// EEPROM channel to read serial number from this.saveResults, // save focusing results this.showResults, // show focusing (includingh intermediate) results Loading Loading @@ -871,6 +875,7 @@ public class LensAdjustment { properties.setProperty(prefix+"strategyFile",this.strategyFile+""); properties.setProperty(prefix+"resultsSuperDirectory",this.resultsSuperDirectory+""); properties.setProperty(prefix+"focusingHistoryFile",this.focusingHistoryFile+""); properties.setProperty(prefix+"useLMAMetrics",this.useLMAMetrics+""); properties.setProperty(prefix+"serialNumber",this.serialNumber+""); if (!Double.isNaN(this.sensorTemperature))properties.setProperty(prefix+"sensorTemperature",this.sensorTemperature+""); if (!Double.isNaN(this.result_lastKT))properties.setProperty(prefix+"result_lastKT",this.result_lastKT+""); Loading Loading @@ -1030,6 +1035,9 @@ public class LensAdjustment { if (properties.getProperty(prefix+"focusingHistoryFile")!=null) this.focusingHistoryFile=properties.getProperty(prefix+"focusingHistoryFile"); if (properties.getProperty(prefix+"useLMAMetrics")!=null) this.useLMAMetrics=Boolean.parseBoolean(properties.getProperty(prefix+"useLMAMetrics")); if (properties.getProperty(prefix+"serialNumber")!=null) this.serialNumber=properties.getProperty(prefix+"serialNumber"); // this.serialNumber is only written, but never read from the configuration file (only from devivce) Loading Loading @@ -1441,7 +1449,8 @@ public class LensAdjustment { gd.addStringField ("Initial camera intrinsic/extrinsic parametres file", this.initialCalibrationFile,40); gd.addStringField ("Levenberg-Marquardt algorithm strategy file", this.strategyFile,40); gd.addStringField ("Focusing results superdirectory (individual will be named by serial numbers)", this.resultsSuperDirectory,40); gd.addStringField ("Measurement history (acquired during \"Scan Calib LMA\" file", this.focusingHistoryFile,80); gd.addStringField ("Measurement history (acquired during \"Scan Calib LMA\") file", this.focusingHistoryFile,80); gd.addCheckbox ("Use lens aberration model (if available) for focal distance and tilts", this.useLMAMetrics); gd.addNumericField("EEPROM channel to read sensor serial number from", this.EEPROM_channel, 0,4,""); gd.addCheckbox ("Save SFE focusing results (including intermediate) ", this.saveResults); gd.addCheckbox ("Show SFE focusing results (including intermediate) ", this.showResults); Loading Loading @@ -1618,6 +1627,8 @@ public class LensAdjustment { this.strategyFile= gd.getNextString(); this.resultsSuperDirectory= gd.getNextString(); this.focusingHistoryFile= gd.getNextString(); this.useLMAMetrics = gd.getNextBoolean(); this.EEPROM_channel= (int) gd.getNextNumber(); this.saveResults= gd.getNextBoolean(); this.showResults= gd.getNextBoolean(); Loading