Commit 7a17cbe2 authored by Luc Deschenaux's avatar Luc Deschenaux

Merge branch 'master' of https://github.com/Elphel/imagej-elphel

parents b8af8a1c d14a3970
...@@ -11,14 +11,18 @@ ...@@ -11,14 +11,18 @@
<version>1.135</version> <version>1.135</version>
<relativePath /> <relativePath />
</parent> </parent>
<!--
<properties>
<imagej.app.directory>/data/ImageJ/ImageJ</imagej.app.directory>
</properties>
-->
<groupId>com.elphel</groupId> <groupId>com.elphel</groupId>
<artifactId>imagej-elphel</artifactId> <artifactId>imagej-elphel</artifactId>
<!-- <artifactId>Aberration_Calibration</artifactId> --> <!-- <artifactId>Aberration_Calibration</artifactId> -->
<version>1.0.0</version> <version>1.0.0</version>
<name>plugins/ImageJ_Elphel.jar</name> <name>plugins/imagej_elphel.jar</name>
<!-- <name>plugins/Aberration_Calibration.jar</name> --> <!-- <name>plugins/Aberration_Calibration.jar</name> -->
<description>A Maven project implementing imagej-elphel plugin</description> <description>A Maven project implementing imagej-elphel plugin</description>
...@@ -76,7 +80,6 @@ ...@@ -76,7 +80,6 @@
<!-- see http://jira.codehaus.org/browse/MNG-5346 --> <!-- see http://jira.codehaus.org/browse/MNG-5346 -->
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound> <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration> </configuration>
<executions> <executions>
<execution> <execution>
<id>mojo-descriptor</id> <id>mojo-descriptor</id>
...@@ -85,6 +88,7 @@ ...@@ -85,6 +88,7 @@
</goals> </goals>
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin> <plugin>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -31,9 +31,12 @@ import ij.process.FloatProcessor; ...@@ -31,9 +31,12 @@ import ij.process.FloatProcessor;
import ij.process.ImageProcessor; import ij.process.ImageProcessor;
import ij.text.TextWindow; import ij.text.TextWindow;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
...@@ -44,12 +47,15 @@ import java.util.ArrayList; ...@@ -44,12 +47,15 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
...@@ -1792,12 +1798,129 @@ public class CalibrationHardwareInterface { ...@@ -1792,12 +1798,129 @@ public class CalibrationHardwareInterface {
throw new RuntimeException(ie); throw new RuntimeException(ie);
} }
} }
}
public static class PowerControl{
public boolean [] states={false,false,false};
public String [] groups={"heater","fan","light"};
public int debugLevel=1;
private String powerIP="192.168.0.80";
private double lightsDelay=5.0;
private final String urlFormat="http://%s/insteon/index.php?cmd=%s&group=%s";
private final String rootElement="Document";
public boolean powerConrtolEnabled=false;
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"powerIP",this.powerIP+"");
properties.setProperty(prefix+"powerConrtolEnabled",this.powerConrtolEnabled+"");
properties.setProperty(prefix+"lightsDelay",this.lightsDelay+"");
}
//Integer.decode(string)
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"powerIP")!=null)
this.powerIP=properties.getProperty(prefix+"powerIP");
if (properties.getProperty(prefix+"powerConrtolEnabled")!=null)
this.powerConrtolEnabled=Boolean.parseBoolean(properties.getProperty(prefix+"powerConrtolEnabled"));
if (properties.getProperty(prefix+"lightsDelay")!=null)
this.lightsDelay=Double.parseDouble(properties.getProperty(prefix+"lightsDelay"));
}
public boolean setPower (String group, String state){
if (!powerConrtolEnabled) {
System.out.println("=== Power control is disabled ===");
return false;
}
System.out.println("=== Power control: "+group+":"+state+" ===");
String url=String.format(urlFormat,this.powerIP,state,group);
if (this.debugLevel>2) System.out.println("setPower: "+url);
Document dom=null;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
dom = db.parse(url);
if (!dom.getDocumentElement().getNodeName().equals(rootElement)) {
System.out.println("Root element: expected \""+rootElement+"\", got \"" + dom.getDocumentElement().getNodeName()+"\"");
IJ.showMessage("Error","Root element: expected \""+rootElement+"\", got \"" + dom.getDocumentElement().getNodeName()+"\"");
return false;
}
// boolean responceError= (dom.getDocumentElement().getElementsByTagName("error").getLength()!=0);
// if (responceError) {
// System.out.println("ERROR: register write ("+url+") FAILED" );
// IJ.showMessage("Error","register write ("+url+") FAILED");
// return false;
// }
} catch(MalformedURLException e){
System.out.println("Please check the URL:" + e.toString() );
return false;
} catch(IOException e1){
IJ.showStatus("");
String error = e1.getMessage();
if (error==null || error.equals("")) error = ""+e1;
IJ.showMessage("setPower ERROR", ""+error);
return false;
}catch(ParserConfigurationException pce) {
pce.printStackTrace();
return false;
}catch(SAXException se) {
se.printStackTrace();
return false;
}
for (int i=0;i<this.groups.length;i++) if (this.groups[i].equals(group)){
this.states[i]=state.equals("on");
}
return true;
}
public boolean showDialog(String title, boolean control) {
GenericDialog gd = new GenericDialog(title);
boolean heaterOn=false, fanOn=false, lightOn=false;
gd.addCheckbox("Enable power control (heater, fan, lights) ", this.powerConrtolEnabled);
gd.addStringField("IP address of the power control",this.powerIP,15);
gd.addNumericField("Delay after lights on", this.lightsDelay, 1,4,"sec");
if (control){
gd.addCheckbox("Heater On", heaterOn);
gd.addCheckbox("Fan On", fanOn);
gd.addCheckbox("Lights On", lightOn);
}
WindowTools.addScrollBars(gd);
if (control) gd.enableYesNoCancel("OK", "Control Power");
gd.showDialog();
if (gd.wasCanceled()) return false;
this.powerConrtolEnabled=gd.getNextBoolean();
this.powerIP=gd.getNextString();
this.lightsDelay=gd.getNextNumber();
if (control){
heaterOn=gd.getNextBoolean();
fanOn=gd.getNextBoolean();
lightOn=gd.getNextBoolean();
if (!gd.wasOKed()) {
setPower("heater",heaterOn?"on":"off");
setPower("fan",fanOn?"on":"off");
setPower("light",lightOn?"on":"off");
}
}
return true;
}
public void lightsOnWithDelay(){
if (this.states[2] || !this.powerConrtolEnabled) return; // already on
setPower("light","on");
System.out.print("Sleeping "+this.lightsDelay+" seconds to let lights stibilize on...");
try {
TimeUnit.MILLISECONDS.sleep((long) (1000*this.lightsDelay));
} catch (InterruptedException e) {
System.out.println("Sleep was interrupted");
// TODO Auto-generated catch block
}
System.out.println(" Done");
} }
public boolean isPowerControlEnabled(){
return this.powerConrtolEnabled;
}
public void setDebugLevel(int debugLevel){
this.debugLevel=debugLevel;
}
}
public static class LaserPointers{ public static class LaserPointers{
public int debugLevel=1; public int debugLevel=1;
...@@ -2513,7 +2636,7 @@ public class CalibrationHardwareInterface { ...@@ -2513,7 +2636,7 @@ public class CalibrationHardwareInterface {
public FocusingSharpness focusingSharpness=new FocusingSharpness(1000); public FocusingSharpness focusingSharpness=new FocusingSharpness(1000);
public int debugLevel=1; public int debugLevel=1;
public String motorsStatePath="lensAdjustmentMotorPosition.xml"; // will be saved in ~/.imagej/ public String motorsStatePath="lensAdjustmentMotorPosition.xml"; // will be saved in ~/.imagej/
public String prefsDirectory=Prefs.getPrefsDir()+Prefs.getFileSeparator(); // "~/.imagej/" public String prefsDirectory=null; // prefs.getPrefsDir()+Prefs.getFileSeparator(); // "~/.imagej/" - too early !!!
private Properties motorProperties=new Properties(); private Properties motorProperties=new Properties();
public boolean interactiveRestore=true; // ask for confirmation to restore motor position public boolean interactiveRestore=true; // ask for confirmation to restore motor position
public boolean stateValid=false; public boolean stateValid=false;
...@@ -2528,6 +2651,12 @@ public class CalibrationHardwareInterface { ...@@ -2528,6 +2651,12 @@ public class CalibrationHardwareInterface {
public double getMicronsPerStep(){return 1000.0*this.threadPitch*this.linearReductionRatio/stepsPerRevolution;} public double getMicronsPerStep(){return 1000.0*this.threadPitch*this.linearReductionRatio/stepsPerRevolution;}
public void setLinearReductionRatio(double lrr){this.linearReductionRatio=lrr;} public void setLinearReductionRatio(double lrr){this.linearReductionRatio=lrr;}
public String getPrefsDir(){
if (prefsDirectory==null) prefsDirectory=Prefs.getPrefsDir();
if (prefsDirectory!=null) prefsDirectory+=Prefs.getFileSeparator(); // "~/.imagej/"
return prefsDirectory;
}
public boolean isInitialized(){ public boolean isInitialized(){
return this.stateValid; return this.stateValid;
} }
...@@ -2568,7 +2697,7 @@ public class CalibrationHardwareInterface { ...@@ -2568,7 +2697,7 @@ public class CalibrationHardwareInterface {
public void saveMotorState() throws IOException{ public void saveMotorState() throws IOException{
if (!this.stateValid) return; // do not save until allowed if (!this.stateValid) return; // do not save until allowed
for (int i=0;i<curpos.length;i++) this.motorProperties.setProperty("motor"+(i+1),this.curpos[i]+""); for (int i=0;i<curpos.length;i++) this.motorProperties.setProperty("motor"+(i+1),this.curpos[i]+"");
String path=this.prefsDirectory+this.motorsStatePath; String path=this.getPrefsDir()+this.motorsStatePath;
OutputStream os; OutputStream os;
try { try {
os = new FileOutputStream(path); os = new FileOutputStream(path);
...@@ -2600,7 +2729,7 @@ public class CalibrationHardwareInterface { ...@@ -2600,7 +2729,7 @@ public class CalibrationHardwareInterface {
} }
public int [] loadMotorState() throws IOException{ public int [] loadMotorState() throws IOException{
String path=this.prefsDirectory+this.motorsStatePath; String path=this.getPrefsDir()+this.motorsStatePath;
InputStream is; InputStream is;
try { try {
is = new FileInputStream(path); is = new FileInputStream(path);
...@@ -2756,7 +2885,7 @@ public class CalibrationHardwareInterface { ...@@ -2756,7 +2885,7 @@ public class CalibrationHardwareInterface {
if (this.debugLevel>2) System.out.println("--savedPosition="+((savedPosition==null)?"null":("{"+savedPosition[0]+","+savedPosition[1]+","+savedPosition[2]+"}"))); if (this.debugLevel>2) System.out.println("--savedPosition="+((savedPosition==null)?"null":("{"+savedPosition[0]+","+savedPosition[1]+","+savedPosition[2]+"}")));
if (this.interactiveRestore){ if (this.interactiveRestore){
gd = new GenericDialog("Missing motor position file"); gd = new GenericDialog("Missing motor position file");
gd.addMessage("No motor position file ("+this.prefsDirectory+this.motorsStatePath+") found."); gd.addMessage("No motor position file ("+this.getPrefsDir()+this.motorsStatePath+") found.");
gd.addMessage("If you run the program for the first time it is normal, you may click \"OK\" and the new file will be created"); gd.addMessage("If you run the program for the first time it is normal, you may click \"OK\" and the new file will be created");
gd.addMessage("If you select \"Cancel\" the current command will be aborted, you may check the file and restart the program."); gd.addMessage("If you select \"Cancel\" the current command will be aborted, you may check the file and restart the program.");
gd.showDialog(); gd.showDialog();
...@@ -2966,7 +3095,25 @@ public class CalibrationHardwareInterface { ...@@ -2966,7 +3095,25 @@ public class CalibrationHardwareInterface {
fullResults 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 public void addToHistory( String sTimestamp,double temperature, double[][] psfMetrics){ // null OK
this.focusingHistory.add( this.focusingHistory.add(
sTimestamp, sTimestamp,
...@@ -2993,6 +3140,7 @@ public class CalibrationHardwareInterface { ...@@ -2993,6 +3140,7 @@ public class CalibrationHardwareInterface {
} }
public void listHistory( public void listHistory(
boolean useLMA,
String path, String path,
String lensSerial, String lensSerial,
String comment, String comment,
...@@ -3004,6 +3152,7 @@ public class CalibrationHardwareInterface { ...@@ -3004,6 +3152,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 double weightY // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution
){ ){
listHistory( listHistory(
useLMA,
path, path,
"", "",
lensSerial, lensSerial,
...@@ -3022,6 +3171,7 @@ public class CalibrationHardwareInterface { ...@@ -3022,6 +3171,7 @@ public class CalibrationHardwareInterface {
} }
public void listHistory( public void listHistory(
boolean useLMA,
String path, String path,
String serialNumber, String serialNumber,
String lensSerial, String lensSerial,
...@@ -3040,6 +3190,7 @@ public class CalibrationHardwareInterface { ...@@ -3040,6 +3190,7 @@ public class CalibrationHardwareInterface {
){ ){
this.focusingHistory.list( this.focusingHistory.list(
useLMA,
path, path,
serialNumber, serialNumber,
lensSerial, lensSerial,
...@@ -3056,6 +3207,83 @@ public class CalibrationHardwareInterface { ...@@ -3056,6 +3207,83 @@ public class CalibrationHardwareInterface {
result_lastKT, result_lastKT,
result_allHistoryKT); result_allHistoryKT);
} }
public void saveHistoryXML(
String path,
String serialNumber,
String lensSerial, // if null - do not add average
String comment,
double pX0,
double pY0,
double [][][] sampleCoord){ // x,y,r
this.focusingHistory.saveXML(
path,
serialNumber,
lensSerial, // if null - do not add average
comment,
pX0,
pY0,
sampleCoord);
}
public FocusingField.FocusingFieldMeasurement getThisFFMeasurement(FocusingField focusingField){
return getThisFFMeasurement(focusingField, -1);
}
public FocusingField.FocusingFieldMeasurement getThisFFMeasurement(FocusingField focusingField, int index){
return focusingField. getFocusingFieldMeasurement(
historyGetTimestamp(index), //focusingState.getTimestamp(),
historyGetTemperature(index), //focusingState.getTemperature(),
historyGetMotors(index), //focusingState.motorsPos,
historyGetSamples(index)); //focusingState.getSamples());
}
private FocusingHistory.FocusingState getFocusingState(int index){
if (index<0) index+=historySize();
if ((index>=0) && (index<historySize())) return this.focusingHistory.history.get(index);
return null;
}
public void addCurrentHistoryToFocusingField(
FocusingField focusingField,
int start,
int end){
for (int i=start;i<end;i++){
addCurrentHistoryToFocusingField(focusingField,i);
}
}
public void addCurrentHistoryToFocusingField(FocusingField focusingField){
addCurrentHistoryToFocusingField(
focusingField,
0,
historySize()
);
}
public void addCurrentHistoryToFocusingField(
FocusingField focusingField,
int index){ // -1 - last (negative - from length)
focusingField.addSample(
historyGetTimestamp(index), //focusingState.getTimestamp(),
historyGetTemperature(index), //focusingState.getTemperature(),
historyGetMotors(index), //focusingState.motorsPos,
historyGetSamples(index)); //focusingState.getSamples());
}
public String historyGetTimestamp(int index){
return getFocusingState(index).getTimestamp();
}
public double historyGetTemperature(int index){
return getFocusingState(index).getTemperature();
}
public int [] historyGetMotors(int index){
return getFocusingState(index).getMotors();
}
public double [][][][] historyGetSamples(int index){
return getFocusingState(index).getSamples();
}
public int historySize(){ public int historySize(){
return this.focusingHistory.history.size(); return this.focusingHistory.history.size();
} }
...@@ -3812,6 +4040,14 @@ public class CalibrationHardwareInterface { ...@@ -3812,6 +4040,14 @@ public class CalibrationHardwareInterface {
if ((index<0) || (index>=this.history.size())) return null; if ((index<0) || (index>=this.history.size())) return null;
return this.history.get(index).getCenterResolutions(); 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(){ public int size(){
return this.history.size(); return this.history.size();
} }
...@@ -4688,6 +4924,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -4688,6 +4924,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
if ((x<xMin) || (x>xMax)) continue; // out of range point if ((x<xMin) || (x>xMax)) continue; // out of range point
data[i][0]= scale*(x - x0); // interval center data[i][0]= scale*(x - x0); // interval center
double [][] metrics= this.history.get(i).getMetrics(0.0,0.0,0.0); // average is not used, any scales double [][] metrics= this.history.get(i).getMetrics(0.0,0.0,0.0); // average is not used, any scales
if (metrics==null) continue;
double l2= double l2=
1.0/metrics[0][indexR50]/metrics[0][indexR50]+ 1.0/metrics[0][indexR50]/metrics[0][indexR50]+
1.0/metrics[1][indexR50]/metrics[1][indexR50]+ 1.0/metrics[1][indexR50]/metrics[1][indexR50]+
...@@ -4979,6 +5216,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -4979,6 +5216,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
* @return array of 2 elements - {length at 0C, microns/degree} * @return array of 2 elements - {length at 0C, microns/degree}
*/ */
public double [] temperatureLinearApproximation( public double [] temperatureLinearApproximation(
boolean useLMA,
int numSamples, // number of last samples from history to use, 0 - use all int numSamples, // number of last samples from history to use, 0 - use all
double lensDistanceWeightK, // used in distance calculation 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 double lensDistanceWeightY // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution
...@@ -4991,8 +5229,11 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -4991,8 +5229,11 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
int firstSample=this.history.size()-numSamples; int firstSample=this.history.size()-numSamples;
for (int nSample=0;nSample<numSamples;nSample++){ for (int nSample=0;nSample<numSamples;nSample++){
resolutions= this.history.get(firstSample+nSample).getCenterResolutions();
data[nSample][0]=this.history.get(firstSample+nSample).getTemperature(); 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( data[nSample][1]=getLensDistance(
resolutions, // {R-sharpness,G-sharpness,B-sharpness} resolutions, // {R-sharpness,G-sharpness,B-sharpness}
true, // boolean absolute, // return absolutely calibrated data true, // boolean absolute, // return absolutely calibrated data
...@@ -5001,10 +5242,40 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5001,10 +5242,40 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
1 //debugLevel 1 //debugLevel
); );
} }
}
PolynomialApproximation pa= new PolynomialApproximation(debugLevel); PolynomialApproximation pa= new PolynomialApproximation(debugLevel);
double [] polyCoeff=pa.polynomialApproximation1d(data, 1); // just linear double [] polyCoeff=pa.polynomialApproximation1d(data, 1); // just linear
return polyCoeff; return polyCoeff;
} }
public double [] temperatureLinearApproximation(
double [][] ZTT, // Z, tXx, tY, m1,m2,m3 found with LMA - may contain NaN
int numSamples // number of last samples from history to use, 0 - use all
){
// if (numSamples<=0) this.history.size();
// if (numSamples>this.history.size()) numSamples=this.history.size();
// int firstSample=this.history.size()-numSamples;
if (numSamples<=0) numSamples=ZTT.length;
if (numSamples>ZTT.length) numSamples=ZTT.length;
int firstSample=ZTT.length-numSamples;
int numGoodSamples=0;
for (int nSample=0;nSample<numSamples;nSample++){
if (ZTT[firstSample+nSample]!=null) numGoodSamples++;
}
double [][] data =new double [numGoodSamples][2]; // no weights
int index=0;
for (int nSample=0;nSample<numSamples;nSample++) if (ZTT[firstSample+nSample]!=null) {
// data[index][0]=this.history.get(firstSample+nSample).getTemperature();
data[index][0]=ZTT[firstSample+nSample][3];
data[index++][1]=ZTT[firstSample+nSample][0]; // Z
}
PolynomialApproximation pa= new PolynomialApproximation(debugLevel);
double [] polyCoeff=pa.polynomialApproximation1d(data, 1); // just linear
return polyCoeff;
}
/** /**
* will return same coordinates if tolerances are met * will return same coordinates if tolerances are met
* @param useTheBest * @param useTheBest
...@@ -5411,6 +5682,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5411,6 +5682,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?) // todo - add "probe around" - 6/3 points, +/- for each direction (fraction of sigma?)
public void list( public void list(
boolean useLMA,
String path, String path,
String lensSerial, // if null - do not add average String lensSerial, // if null - do not add average
String comment, String comment,
...@@ -5420,8 +5692,10 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5420,8 +5692,10 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
double weightRatioBlueToGreen, double weightRatioBlueToGreen,
double weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives 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 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 lensSerial, // if null - do not add average
comment, comment,
showIndividualComponents, showIndividualComponents,
...@@ -5436,9 +5710,99 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5436,9 +5710,99 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
Double.NaN, Double.NaN,
Double.NaN); Double.NaN);
} }
/*
public void addCurrentHistory(
FocusingField focusingField)
{
for (int i=0;i<this.history.size();i++){
FocusingState focusingState=this.history.get(i);
focusingField.addSample(
focusingState.getTimestamp(),
focusingState.getTemperature(),
focusingState.motorsPos,
focusingState.getSamples());
}
}
*/
public void saveXML(
String path,
String serialNumber,
String lensSerial, // if null - do not add average
String comment,
double pX0,
double pY0,
double [][][] sampleCoord){ // x,y,r
String sep=" "; //",";
ArrayList<String> nodeList=new ArrayList<String>();
XMLConfiguration hConfig=new XMLConfiguration();
hConfig.setRootElementName("focusingHistory");
if (comment!=null) hConfig.addProperty("comment",comment);
if (serialNumber!=null) hConfig.addProperty("serialNumber",serialNumber);
if (lensSerial!=null) hConfig.addProperty("lensSerial",lensSerial);
hConfig.addProperty("lens_center_x",pX0);
hConfig.addProperty("lens_center_y",pY0);
if ((sampleCoord!=null) && (sampleCoord.length>0) && (sampleCoord[0] != null) && (sampleCoord[0].length>0)){
hConfig.addProperty("samples_x",sampleCoord[0].length);
hConfig.addProperty("samples_y",sampleCoord.length);
for (int i=0;i<sampleCoord.length;i++)
for (int j=0;j<sampleCoord[i].length;j++){
// double coord[] = {sampleCoord[i][j][0],sampleCoord[i][j][1]};
hConfig.addProperty("sample_"+i+"_"+j,sampleCoord[i][j][0]+sep+sampleCoord[i][j][1]);
}
}
hConfig.addProperty("measurements",this.history.size());
for (int i=0;i<this.history.size();i++){
FocusingState focusingState=this.history.get(i);
String prefix="measurement_"+i+".";
if (focusingState.getTimestamp()!=null)
hConfig.addProperty(prefix+"timestamp",focusingState.getTimestamp());
hConfig.addProperty(prefix+"temperature",focusingState.getTemperature());
hConfig.addProperty(prefix+"motors",focusingState.motorsPos[0]+sep+focusingState.motorsPos[1]+sep+focusingState.motorsPos[2]); // array of 3
double [][][][] samples=focusingState.getSamples();
nodeList.clear();
if ((samples!=null) && (samples.length>0) && (samples[0]!=null) && (samples[0].length>0)){
for (int ii=0;ii<samples.length;ii++) for (int jj=0;jj<samples[ii].length;jj++){
if ((samples[ii][jj]!=null) && (samples[ii][jj].length>0)) {
String sdata=ii+sep+jj;
for (int cc=0;cc<samples[ii][jj].length;cc++) {
/*
double rt=samples[ii][jj][cc][0]/Math.sqrt((1+samples[ii][jj][cc][1]*samples[ii][jj][cc][1])/2.0); // tangential;
double rs=rt*samples[ii][jj][cc][1]; // saggital
sdata += sep+rs+ // saggital
sep+rt; // tangential
*/
sdata += sep+samples[ii][jj][cc][0]+ // x2
sep+samples[ii][jj][cc][1]+ // y2
sep+samples[ii][jj][cc][2]; // xy
// double [] samples_st={
// samples[ii][jj][cc][0], // saggital
// samples[ii][jj][cc][0]/samples[ii][jj][cc][1] // tangential (was ratio)
// };
}
nodeList.add(sdata);
}
}
hConfig.addProperty(prefix+"sample",nodeList);
}
}
File file=new File (path);
BufferedWriter writer;
try {
writer = new BufferedWriter(new FileWriter(file));
hConfig.save(writer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void list( public void list(
boolean useLMA,
String path, String path,
String serialNumber, String serialNumber,
String lensSerial, // if null - do not add average String lensSerial, // if null - do not add average
...@@ -5479,14 +5843,18 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5479,14 +5843,18 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
if (showIndividualSamples){ if (showIndividualSamples){
if (showIndividualComponents) { // additional 3 per-color rows if (showIndividualComponents) { // additional 3 per-color rows
for (int i=0;i<sampleRows;i++) for (int j=0;j<sampleColumns;j++){ for (int i=0;i<sampleRows;i++) for (int j=0;j<sampleColumns;j++){
header+="\tY"+i+"X"+j+"_R"+"\tY"+i+"X"+j+"_R/T"; // header+="\tY"+i+"X"+j+"_R"+"\tY"+i+"X"+j+"_R/T";
header+="\tY"+i+"X"+j+"_X2"+"\tY"+i+"X"+j+"_Y2"+"\tY"+i+"X"+j+"_XY";
} }
} else { } else {
for (int i=0;i<sampleRows;i++) for (int j=0;j<sampleColumns;j++){ // single row fro all colors for (int i=0;i<sampleRows;i++) for (int j=0;j<sampleColumns;j++){ // single row fro all colors
header+="\tY"+i+"X"+j+"_Red_R"+"\tY"+i+"X"+j+"_Red_R/T"+ // header+="\tY"+i+"X"+j+"_Red_R"+"\tY"+i+"X"+j+"_Red_R/T"+
"\tY"+i+"X"+j+"_Green_R"+"\tY"+i+"X"+j+"_Green_R/T"+ // "\tY"+i+"X"+j+"_Green_R"+"\tY"+i+"X"+j+"_Green_R/T"+
"\tY"+i+"X"+j+"_Blue_R"+"\tY"+i+"X"+j+"_Blue_R/T"; // "\tY"+i+"X"+j+"_Blue_R"+"\tY"+i+"X"+j+"_Blue_R/T";
header+="\tY"+i+"X"+j+"_Red_X2"+"\tY"+i+"X"+j+"_Red_Y2"+"\tY"+i+"X"+j+"_Red_XY"+
"\tY"+i+"X"+j+"_Green_X2"+"\tY"+i+"X"+j+"_Green_Y2"+"\tY"+i+"X"+j+"_Green_XY"+
"\tY"+i+"X"+j+"_Blue_X2"+"\tY"+i+"X"+j+"_Blue_Y2"+"\tY"+i+"X"+j+"_Blue_XY";
} }
} }
} }
...@@ -5495,15 +5863,22 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5495,15 +5863,22 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
if (showIndividualComponents) { if (showIndividualComponents) {
for (int i=0;i<this.history.size();i++){ for (int i=0;i<this.history.size();i++){
FocusingState focusingState=this.history.get(i); FocusingState focusingState=this.history.get(i);
double [] zTxTy=useLMA?focusingState.getzTxTy():null;
double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen); double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen);
double [][] resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen); double [][] resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen);
double dist= getLensDistance( double dist= (zTxTy==null)?getLensDistance(
focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness} focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness}
true, //boolean absolute, // return absolutely calibrated data 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 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 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]; 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]; double [] averageResolution=resolution[3];
sb.append((i+1)+"\t"); sb.append((i+1)+"\t");
String timestamp=focusingState.getTimestamp(); String timestamp=focusingState.getTimestamp();
...@@ -5555,8 +5930,9 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5555,8 +5930,9 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
if ((samples[ii][jj]!=null) && (samples[ii][jj][c]!=null)) { if ((samples[ii][jj]!=null) && (samples[ii][jj][c]!=null)) {
sb.append( "\t"+IJ.d2s(samples[ii][jj][c][0],3)); sb.append( "\t"+IJ.d2s(samples[ii][jj][c][0],3));
sb.append( "\t"+IJ.d2s(samples[ii][jj][c][1],3)); sb.append( "\t"+IJ.d2s(samples[ii][jj][c][1],3));
sb.append( "\t"+IJ.d2s(samples[ii][jj][c][2],3));
} else { } else {
sb.append( "\t---\t---"); sb.append( "\t---\t---\t---");
} }
} }
} }
...@@ -5572,9 +5948,21 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5572,9 +5948,21 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
for (int i=0;i<this.history.size();i++){ for (int i=0;i<this.history.size();i++){
// int parIndex=0; // int parIndex=0;
FocusingState focusingState=this.history.get(i); FocusingState focusingState=this.history.get(i);
double [] zTxTy=useLMA?focusingState.getzTxTy():null;
double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen); double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen);
double [][] resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen); double [][] resolution={{Double.NaN,Double.NaN},{Double.NaN,Double.NaN},{Double.NaN,Double.NaN},{Double.NaN,Double.NaN}};
try {
resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen);
} catch (Exception e){
System.out.println("Failed to get resolution for history("+i+")");
continue; // skip the whole line
}
double [] averageMetrics=metrics[3]; 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]; double [] averageResolution=resolution[3];
if (!justSummary) sb.append((i+1)+"\t"); if (!justSummary) sb.append((i+1)+"\t");
String timestamp=focusingState.getTimestamp(); String timestamp=focusingState.getTimestamp();
...@@ -5599,12 +5987,13 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5599,12 +5987,13 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
sums[4]+=focusingState.motorsPos[0]; sums[4]+=focusingState.motorsPos[0];
sums[5]+=focusingState.motorsPos[1]; sums[5]+=focusingState.motorsPos[1];
sums[6]+=focusingState.motorsPos[2]; sums[6]+=focusingState.motorsPos[2];
double dist= getLensDistance( double dist= (zTxTy==null)?getLensDistance(
focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness} focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness}
true, //boolean absolute, // return absolutely calibrated data 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 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 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 (Double.isNaN(dist)){
if (!justSummary) sb.append("\t---"); if (!justSummary) sb.append("\t---");
} else { } else {
...@@ -5635,8 +6024,9 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5635,8 +6024,9 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
if ((samples[ii][jj]!=null) && (samples[ii][jj][cc]!=null)) { if ((samples[ii][jj]!=null) && (samples[ii][jj][cc]!=null)) {
sb.append( "\t"+IJ.d2s(samples[ii][jj][cc][0],3)); sb.append( "\t"+IJ.d2s(samples[ii][jj][cc][0],3));
sb.append( "\t"+IJ.d2s(samples[ii][jj][cc][1],3)); sb.append( "\t"+IJ.d2s(samples[ii][jj][cc][1],3));
sb.append( "\t"+IJ.d2s(samples[ii][jj][cc][2],3));
} else { } else {
sb.append( "\t---\t---"); sb.append( "\t---\t---\t---");
} }
} }
} }
...@@ -5964,7 +6354,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5964,7 +6354,7 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
double weightBlue){ double weightBlue){
double [][] metrics=getMetrics(weightRed, weightGreen, weightBlue); double [][] metrics=getMetrics(weightRed, weightGreen, weightBlue);
double [][]sharpness={ double [][]sharpness={
{1.0/metrics[0][this.indexR50All],1.0/metrics[0][this.indexR50Center]}, {1.0/metrics[0][this.indexR50All],1.0/metrics[0][this.indexR50Center]}, //java.lang.NullPointerException
{1.0/metrics[1][this.indexR50All],1.0/metrics[1][this.indexR50Center]}, {1.0/metrics[1][this.indexR50All],1.0/metrics[1][this.indexR50Center]},
{1.0/metrics[2][this.indexR50All],1.0/metrics[2][this.indexR50Center]}, {1.0/metrics[2][this.indexR50All],1.0/metrics[2][this.indexR50Center]},
{0.0,0.0}}; {0.0,0.0}};
...@@ -5976,11 +6366,15 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5976,11 +6366,15 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
return sharpness; return sharpness;
} }
public double [] getCenterResolutions(){ public double [] getCenterResolutions(){
try {
double [] resolutions={ double [] resolutions={
1.0/this.psfMetricses[this.indices[0]][this.indexR50Center], // red, r50% center 1.0/this.psfMetricses[this.indices[0]][this.indexR50Center], // red, r50% center
1.0/this.psfMetricses[this.indices[1]][this.indexR50Center], // green, r50% center 1.0/this.psfMetricses[this.indices[1]][this.indexR50Center], // green, r50% center
1.0/this.psfMetricses[this.indices[2]][this.indexR50Center]}; // blue, r50% center 1.0/this.psfMetricses[this.indices[2]][this.indexR50Center]}; // blue, r50% center
return resolutions; return resolutions;
} catch (Exception e){
return null;
}
} }
public double [][] getMetrics( public double [][] getMetrics(
...@@ -5991,7 +6385,19 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -5991,7 +6385,19 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
1.0, 1.0,
weightRatioBlueToGreen); 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( public double [][] getMetrics(
double weightRed, double weightRed,
double weightGreen, double weightGreen,
...@@ -6002,8 +6408,12 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" " ...@@ -6002,8 +6408,12 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
double w=0.0; double w=0.0;
for (int i=0;i<weights.length;i++) w+=weights[i]; for (int i=0;i<weights.length;i++) w+=weights[i];
for (int i=0;i<weights.length;i++) weights[i]/=w; for (int i=0;i<weights.length;i++) weights[i]/=w;
try {
metrics[3]=new double[this.psfMetricses[this.indices[0]].length]; metrics[3]=new double[this.psfMetricses[this.indices[0]].length];
for (int c=0;c<3;c++) metrics[c]= this.psfMetricses[this.indices[c]]; for (int c=0;c<3;c++) metrics[c]= this.psfMetricses[this.indices[c]];
} catch (Exception e){
return null;
}
for (int i=0; i<metrics[3].length;i++) { for (int i=0; i<metrics[3].length;i++) {
metrics[3][i]=0.0; metrics[3][i]=0.0;
if (squared[i]){ if (squared[i]){
......
...@@ -12398,7 +12398,7 @@ Which parameters affect which matrices ...@@ -12398,7 +12398,7 @@ Which parameters affect which matrices
public int getGoniometerHorizontalIndex(){return 6;} public int getGoniometerHorizontalIndex(){return 6;}
public int getGoniometerAxialIndex(){return 7;} public int getGoniometerAxialIndex(){return 7;}
public int getSensorWidth() { return this.sensorWidth;} public int getSensorWidth() { return this.sensorWidth;}
public int getSensorHeight() { return this.sensorWidth;} public int getSensorHeight() { return this.sensorHeight;}
public int getSensorWidth(int subCam) { return this.sensorWidth;} // for the future? different sensors public int getSensorWidth(int subCam) { return this.sensorWidth;} // for the future? different sensors
public int getSensorHeight(int subCam) { return this.sensorHeight;}// for the future? different sensors public int getSensorHeight(int subCam) { return this.sensorHeight;}// for the future? different sensors
public double getPixelSize(int subCamNumber){return this.eyesisSubCameras[0][subCamNumber].pixelSize;} // use station 0's pixel size public double getPixelSize(int subCamNumber){return this.eyesisSubCameras[0][subCamNumber].pixelSize;} // use station 0's pixel size
...@@ -13952,6 +13952,33 @@ Which parameters affect which matrices ...@@ -13952,6 +13952,33 @@ Which parameters affect which matrices
this.flipVertical=flipVertical; this.flipVertical=flipVertical;
recalcCommons(); recalcCommons();
} }
public void setIntrincicFromSubcamera(EyesisSubCameraParameters pars){
setLensDistortionParameters(
pars.focalLength,
pars.pixelSize, //um
pars.distortionRadius, // mm
pars.distortionA8, // r^7
pars.distortionA7, // r^6
pars.distortionA6, // r^5
pars.distortionA5, // r^4
pars.distortionA, // r^4
pars.distortionB, // r^3
pars.distortionC, // r^2
// orientation/position parameters
this.yaw, // (keep) angle in degrees from perpendicular to the pattern, 0 - towards wall, positive - clockwise from top
this.pitch, // (keep) angle in degrees from perpendicular to the pattern, 0 - towards wall, positive - up
this.roll, // (keep) angle in degrees rotation around camera optical axis (perpendicular to pattern if yaw==0, pitch==0), positive - clockwise
this.x0, // (keep) lens axis from pattern center, mm (to the right)
this.y0, // (keep) lens axis from pattern center, mm (down)
this.z0, // (keep) lens axis from pattern center, mm (away)
this.distance, // (keep) distance from the lens input pupil to the pattern plane along the camera axis, mm
pars.px0, // center of the lens on the sensor, pixels
pars.py0, // center of the lens on the sensor, pixels
this.flipVertical // (keep) acquired image is mirrored vertically (mirror used)
);
}
public void setLensDistortionParameters(LensDistortionParameters ldp public void setLensDistortionParameters(LensDistortionParameters ldp
){ ){
this.focalLength=ldp.focalLength; this.focalLength=ldp.focalLength;
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -194,6 +194,8 @@ public class LensAdjustment { ...@@ -194,6 +194,8 @@ public class LensAdjustment {
public static class FocusMeasurementParameters { public static class FocusMeasurementParameters {
public String gridGeometryFile=""; public String gridGeometryFile="";
public String initialCalibrationFile=""; 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 strategyFile="";
public String resultsSuperDirectory=""; // directory with subdirectories named as serial numbers to stro results 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 public int EEPROM_channel=1; // EEPROM channel to read serial number from
...@@ -224,13 +226,14 @@ public class LensAdjustment { ...@@ -224,13 +226,14 @@ public class LensAdjustment {
public int lensSerialLength=4; public int lensSerialLength=4;
public String lensSerial=""; // Lens serial number public String lensSerial=""; // Lens serial number
public boolean askLensSerial=true; // Ask lens serial on camera power cycle public boolean askLensSerial=true; // Ask lens serial on camera power cycle
public double reportTemperature=50; // temperature to report focal length
public boolean includeLensSerial=true; // add lens serial to config filename public boolean includeLensSerial=true; // add lens serial to config filename
public double centerDeltaX=0.0; // required X-difference between lens center and sensor center public double centerDeltaX=0.0; // required X-difference between lens center and sensor center
public double centerDeltaY=0.0; // required Y-difference between lens center and sensor center public double centerDeltaY=0.0; // required Y-difference between lens center and sensor center
// with the seam in the middle - make even # of samples horizontally // with the seam in the middle - make even # of samples horizontally
public Rectangle margins=new Rectangle (100,100,2392,1736) ; // maximal height 1816 (1936-120) public Rectangle margins=new Rectangle (100,100,2392,1736) ; // maximal height 1816 (1936-120)
public int [] numSamples={4,3}; // number of samples in x and y directions public int [] numSamples={8,5}; // number of samples in x and y directions
public int sampleSize=256;// 512; // size of square (2^n), in sensor pixels (twice FFT size) public int sampleSize=256;// 512; // size of square (2^n), in sensor pixels (twice FFT size)
public int numInCenter=(numSamples[0]-2)*(numSamples[1]-2);// 2 - number of "center" samples public int numInCenter=(numSamples[0]-2)*(numSamples[1]-2);// 2 - number of "center" samples
public boolean centerSamples=true; // Select samples in the WOI symmetrical around the lens center public boolean centerSamples=true; // Select samples in the WOI symmetrical around the lens center
...@@ -297,12 +300,22 @@ public class LensAdjustment { ...@@ -297,12 +300,22 @@ public class LensAdjustment {
public double motorsPreSigma=3584.0; // when fitting parabola for focusing sharpness in the center, far measurements decay with this sigma public double motorsPreSigma=3584.0; // when fitting parabola for focusing sharpness in the center, far measurements decay with this sigma
public double maxLinearStep= 3584.0; // If there are insufficient measurements to fit parabola - make this step public double maxLinearStep= 3584.0; // If there are insufficient measurements to fit parabola - make this step
public int scanStep=200; // motor step (all 3 motors) in scan focus mode (signed value) public int scanStep=320; // 200; // motor step (all 3 motors) in scan focus mode (signed value)
public int scanNumber=50; // number of scanStep steps to run public int scanNumber=50; // number of scanStep steps to run
public int scanNumberNegative=15; // number of scanStep steps negative from the start public int scanNumberNegative=20; // 15; // number of scanStep steps negative from the start
public boolean scanHysteresis=true; // scan both ways public boolean scanHysteresis=false; // true; // scan both ways
public int scanHysteresisNumber=5; // number of test points for the Hysteresis measurement public int scanHysteresisNumber=5; // number of test points for the Hysteresis measurement
public boolean scanTiltEnable=false; //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 boolean scanRunLMA=true; // Calculate PSF after last move (to original position)
public int scanTiltRangeX=14336; // 4 periods
public int scanTiltRangeY=14336; // 4 periods
public int scanTiltStepsX=24;
public int scanTiltStepsY=24;
public int motorHysteresis=300; public int motorHysteresis=300;
public double measuredHysteresis=0; // actually measured (will be saved/restored) public double measuredHysteresis=0; // actually measured (will be saved/restored)
public double motorCalm=2; // wait (seconds) after motors reached final position (for the first time) before acquiring image public double motorCalm=2; // wait (seconds) after motors reached final position (for the first time) before acquiring image
...@@ -318,6 +331,12 @@ public class LensAdjustment { ...@@ -318,6 +331,12 @@ public class LensAdjustment {
public boolean lensDistanceShowResults=true; // show results window from foca public boolean lensDistanceShowResults=true; // show results window from foca
public boolean lensDistanceMoveToGoal=true; // Move to targetMicrons public boolean lensDistanceMoveToGoal=true; // Move to targetMicrons
public boolean powerControlEnable=true;
public double powerControlMaximalTemperature=60.0;
public double powerControlHeaterOnMinutes=10.0;
public double powerControlNeitherOnMinutes=5.0;
public double powerControlFanOnMinutes=15.0;
public String uvLasersIP="192.168.0.236"; // IP address of the camera with UV LEDs and aiming lasers are connected public String uvLasersIP="192.168.0.236"; // IP address of the camera with UV LEDs and aiming lasers are connected
public int uvLasersBus=0; // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369 public int uvLasersBus=0; // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369
public double [] uvLasersCurrents={40.0,40.0,40.0,40.0}; // default LED on currents (mA) public double [] uvLasersCurrents={40.0,40.0,40.0,40.0}; // default LED on currents (mA)
...@@ -405,7 +424,7 @@ public class LensAdjustment { ...@@ -405,7 +424,7 @@ public class LensAdjustment {
this.result_tiltY=Double.NaN; // last measured tilt Y this.result_tiltY=Double.NaN; // last measured tilt Y
this.result_R50=Double.NaN; // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings) this.result_R50=Double.NaN; // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings)
this.result_A50=Double.NaN; // last measured A50 (simailar, but R^2 are averaged) this.result_A50=Double.NaN; // last measured A50 (simailar, but R^2 are averaged)
this.result_B50=Double.NaN; // last measured B50 (simailar, but R^4 are averaged) this.result_B50=Double.NaN; // last measured B50 (similar, but R^4 are averaged)
this.result_RC50=Double.NaN; // last measured RC50(R50 calculated only for the 2 center samples) this.result_RC50=Double.NaN; // last measured RC50(R50 calculated only for the 2 center samples)
this.result_PX0=Double.NaN; // lens center shift, X this.result_PX0=Double.NaN; // lens center shift, X
this.result_PY0=Double.NaN; // lens center shift, Y this.result_PY0=Double.NaN; // lens center shift, Y
...@@ -418,6 +437,8 @@ public class LensAdjustment { ...@@ -418,6 +437,8 @@ public class LensAdjustment {
String initialCalibrationFile, String initialCalibrationFile,
String strategyFile, String strategyFile,
String resultsSuperDirectory, // directory with subdirectories named as serial numbers to stro results 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 int EEPROM_channel, // EEPROM channel to read serial number from
boolean saveResults, // save focusing results boolean saveResults, // save focusing results
boolean showResults, // show focusing (includingh intermediate) results boolean showResults, // show focusing (includingh intermediate) results
...@@ -509,6 +530,17 @@ public class LensAdjustment { ...@@ -509,6 +530,17 @@ public class LensAdjustment {
int scanNumberNegative, // of them negative int scanNumberNegative, // of them negative
boolean scanHysteresis, // scan both ways boolean scanHysteresis, // scan both ways
int scanHysteresisNumber, // number of test points for the Hysteresis measurement int scanHysteresisNumber, // number of test points for the Hysteresis measurement
boolean scanTiltEnable, //=true; // enable scanning tilt
boolean scanTiltReverse,
boolean scanMeasureLast,
boolean scanRunLMA,
int scanTiltRangeX, //=14336; // 4 periods
int scanTiltRangeY, //=14336; // 4 periods
int scanTiltStepsX, //=24;
int scanTiltStepsY, //=24;
int motorHysteresis, int motorHysteresis,
double measuredHysteresis, // actually measured (will be saved/restored) double measuredHysteresis, // actually measured (will be saved/restored)
double motorCalm, // wait (seconds) after motors reached final position (for the first time) before acquiring image double motorCalm, // wait (seconds) after motors reached final position (for the first time) before acquiring image
...@@ -521,6 +553,11 @@ public class LensAdjustment { ...@@ -521,6 +553,11 @@ public class LensAdjustment {
boolean lensDistanceInteractive, // Open dialog when calibrating focal distance boolean lensDistanceInteractive, // Open dialog when calibrating focal distance
boolean lensDistanceShowResults, // show results window from foca boolean lensDistanceShowResults, // show results window from foca
boolean lensDistanceMoveToGoal, // Move to targetMicrons boolean lensDistanceMoveToGoal, // Move to targetMicrons
boolean powerControlEnable,
double powerControlMaximalTemperature,
double powerControlHeaterOnMinutes,
double powerControlNeitherOnMinutes,
double powerControlFanOnMinutes,
String uvLasersIP, // IP address of the camera with UV LEDs and aiming lasers are connected String uvLasersIP, // IP address of the camera with UV LEDs and aiming lasers are connected
int uvLasersBus, // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369 int uvLasersBus, // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369
double [] uvLasersCurrents, // default LED on currents (mA) double [] uvLasersCurrents, // default LED on currents (mA)
...@@ -547,12 +584,15 @@ public class LensAdjustment { ...@@ -547,12 +584,15 @@ public class LensAdjustment {
int numIterations, // maximal number of iterations int numIterations, // maximal number of iterations
boolean cameraIsConfigured, boolean cameraIsConfigured,
int [] motorPos, int [] motorPos,
double [] ampsSeconds // cumulative Amps*seconds (read only, but will be saved/restored) double [] ampsSeconds, // cumulative Amps*seconds (read only, but will be saved/restored)
double reportTemperature // temperature to report focal length
){ ){
this.gridGeometryFile=gridGeometryFile; this.gridGeometryFile=gridGeometryFile;
this.initialCalibrationFile=initialCalibrationFile; this.initialCalibrationFile=initialCalibrationFile;
this.strategyFile=strategyFile; this.strategyFile=strategyFile;
this.resultsSuperDirectory=resultsSuperDirectory; // directory with subdirectories named as serial numbers to stro results 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.EEPROM_channel=EEPROM_channel; // EEPROM channel to read serial number from
this.saveResults=saveResults; // save focusing results this.saveResults=saveResults; // save focusing results
this.showResults=showResults; // show focusing (includingh intermediate) results this.showResults=showResults; // show focusing (includingh intermediate) results
...@@ -643,6 +683,16 @@ public class LensAdjustment { ...@@ -643,6 +683,16 @@ public class LensAdjustment {
this.scanNumberNegative=scanNumberNegative; // of them negative this.scanNumberNegative=scanNumberNegative; // of them negative
this.scanHysteresis=scanHysteresis; // scan both ways this.scanHysteresis=scanHysteresis; // scan both ways
this.scanHysteresisNumber=scanHysteresisNumber; // number of test points for the Hysteresis measurement this.scanHysteresisNumber=scanHysteresisNumber; // number of test points for the Hysteresis measurement
this.scanTiltEnable=scanTiltEnable; //=true; // enable scanning tilt
this.scanTiltReverse=scanTiltReverse;
this.scanMeasureLast=scanMeasureLast;
this.scanRunLMA=scanRunLMA;
this.scanTiltRangeX=scanTiltRangeX; //, //=14336; // 4 periods
this.scanTiltRangeY=scanTiltRangeY; //, //=14336; // 4 periods
this.scanTiltStepsX=scanTiltStepsX; //=24;
this.scanTiltStepsY=scanTiltStepsY; //=24;
this.motorHysteresis=motorHysteresis; this.motorHysteresis=motorHysteresis;
this.measuredHysteresis=measuredHysteresis; // actually measured (will be saved/restored) this.measuredHysteresis=measuredHysteresis; // actually measured (will be saved/restored)
this.motorCalm=motorCalm; // wait (seconds) after motors reached final position (for the first time) before acquiring image this.motorCalm=motorCalm; // wait (seconds) after motors reached final position (for the first time) before acquiring image
...@@ -655,6 +705,11 @@ public class LensAdjustment { ...@@ -655,6 +705,11 @@ public class LensAdjustment {
this.lensDistanceInteractive=lensDistanceInteractive; // Open dialog when calibrating focal distance this.lensDistanceInteractive=lensDistanceInteractive; // Open dialog when calibrating focal distance
this.lensDistanceShowResults=lensDistanceShowResults; // show results window from foca this.lensDistanceShowResults=lensDistanceShowResults; // show results window from foca
this.lensDistanceMoveToGoal=lensDistanceMoveToGoal; // Move to targetMicrons this.lensDistanceMoveToGoal=lensDistanceMoveToGoal; // Move to targetMicrons
this.powerControlEnable=powerControlEnable;
this.powerControlMaximalTemperature=powerControlMaximalTemperature;
this.powerControlHeaterOnMinutes=powerControlHeaterOnMinutes;
this.powerControlNeitherOnMinutes=powerControlNeitherOnMinutes;
this.powerControlFanOnMinutes=powerControlFanOnMinutes;
this.uvLasersIP=new String(uvLasersIP); // IP address of the camera with UV LEDs and aiming lasers are connected this.uvLasersIP=new String(uvLasersIP); // IP address of the camera with UV LEDs and aiming lasers are connected
this.uvLasersBus=uvLasersBus; // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369 this.uvLasersBus=uvLasersBus; // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369
this.uvLasersCurrents=uvLasersCurrents.clone(); // default LED on currents (mA) this.uvLasersCurrents=uvLasersCurrents.clone(); // default LED on currents (mA)
...@@ -681,7 +736,7 @@ public class LensAdjustment { ...@@ -681,7 +736,7 @@ public class LensAdjustment {
this.cameraIsConfigured=cameraIsConfigured; this.cameraIsConfigured=cameraIsConfigured;
this.motorPos=motorPos; this.motorPos=motorPos;
this.ampsSeconds=ampsSeconds; // cumulative Amps*seconds (read only, but will be saved/restored) this.ampsSeconds=ampsSeconds; // cumulative Amps*seconds (read only, but will be saved/restored)
this.reportTemperature=reportTemperature;
} }
public FocusMeasurementParameters clone(){ public FocusMeasurementParameters clone(){
...@@ -690,6 +745,8 @@ public class LensAdjustment { ...@@ -690,6 +745,8 @@ public class LensAdjustment {
this.initialCalibrationFile, this.initialCalibrationFile,
this.strategyFile, this.strategyFile,
this.resultsSuperDirectory, // directory with subdirectories named as serial numbers to stro results 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.EEPROM_channel,// EEPROM channel to read serial number from
this.saveResults, // save focusing results this.saveResults, // save focusing results
this.showResults, // show focusing (includingh intermediate) results this.showResults, // show focusing (includingh intermediate) results
...@@ -779,7 +836,17 @@ public class LensAdjustment { ...@@ -779,7 +836,17 @@ public class LensAdjustment {
this.scanNumberNegative, // of them negative this.scanNumberNegative, // of them negative
this.scanHysteresis, // scan both ways this.scanHysteresis, // scan both ways
this.scanHysteresisNumber, // number of test points for the Hysteresis measurement this.scanHysteresisNumber, // number of test points for the Hysteresis measurement
this.scanTiltEnable, // enable scanning tilt
this.scanTiltReverse,
this.scanMeasureLast,
this.scanRunLMA,
this.scanTiltRangeX, // 4 periods
this.scanTiltRangeY, // 4 periods
this.scanTiltStepsX,
this.scanTiltStepsY,
this.motorHysteresis, this.motorHysteresis,
this.measuredHysteresis, // actually measured (will be saved/restored) this.measuredHysteresis, // actually measured (will be saved/restored)
this.motorCalm, // wait (seconds) after motors reached final position (for the first time) before acquiring image this.motorCalm, // wait (seconds) after motors reached final position (for the first time) before acquiring image
this.linearReductionRatio, // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105 this.linearReductionRatio, // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105
...@@ -791,6 +858,11 @@ public class LensAdjustment { ...@@ -791,6 +858,11 @@ public class LensAdjustment {
this.lensDistanceInteractive, // Open dialog when calibrating focal distance this.lensDistanceInteractive, // Open dialog when calibrating focal distance
this.lensDistanceShowResults, // show results window from foca this.lensDistanceShowResults, // show results window from foca
this.lensDistanceMoveToGoal, // Move to targetMicrons this.lensDistanceMoveToGoal, // Move to targetMicrons
this.powerControlEnable,
this.powerControlMaximalTemperature,
this.powerControlHeaterOnMinutes,
this.powerControlNeitherOnMinutes,
this.powerControlFanOnMinutes,
this.uvLasersIP, // IP address of the camera with UV LEDs and aiming lasers are connected this.uvLasersIP, // IP address of the camera with UV LEDs and aiming lasers are connected
this.uvLasersBus, // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369 this.uvLasersBus, // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369
this.uvLasersCurrents, // default LED on currents (mA) this.uvLasersCurrents, // default LED on currents (mA)
...@@ -817,7 +889,8 @@ public class LensAdjustment { ...@@ -817,7 +889,8 @@ public class LensAdjustment {
this.numIterations, this.numIterations,
this.cameraIsConfigured, this.cameraIsConfigured,
this.motorPos, this.motorPos,
this.ampsSeconds // cumulative Amps*seconds (read only, but will be saved/restored) this.ampsSeconds, // cumulative Amps*seconds (read only, but will be saved/restored)
this.reportTemperature
); );
} }
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
...@@ -825,6 +898,8 @@ public class LensAdjustment { ...@@ -825,6 +898,8 @@ public class LensAdjustment {
properties.setProperty(prefix+"initialCalibrationFile",this.initialCalibrationFile+""); properties.setProperty(prefix+"initialCalibrationFile",this.initialCalibrationFile+"");
properties.setProperty(prefix+"strategyFile",this.strategyFile+""); properties.setProperty(prefix+"strategyFile",this.strategyFile+"");
properties.setProperty(prefix+"resultsSuperDirectory",this.resultsSuperDirectory+""); properties.setProperty(prefix+"resultsSuperDirectory",this.resultsSuperDirectory+"");
properties.setProperty(prefix+"focusingHistoryFile",this.focusingHistoryFile+"");
properties.setProperty(prefix+"useLMAMetrics",this.useLMAMetrics+"");
properties.setProperty(prefix+"serialNumber",this.serialNumber+""); properties.setProperty(prefix+"serialNumber",this.serialNumber+"");
if (!Double.isNaN(this.sensorTemperature))properties.setProperty(prefix+"sensorTemperature",this.sensorTemperature+""); 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+""); if (!Double.isNaN(this.result_lastKT))properties.setProperty(prefix+"result_lastKT",this.result_lastKT+"");
...@@ -919,15 +994,19 @@ public class LensAdjustment { ...@@ -919,15 +994,19 @@ public class LensAdjustment {
properties.setProperty(prefix+"scanStep",this.scanStep+""); properties.setProperty(prefix+"scanStep",this.scanStep+"");
properties.setProperty(prefix+"scanNumber",this.scanNumber+""); properties.setProperty(prefix+"scanNumber",this.scanNumber+"");
properties.setProperty(prefix+"scanNumberNegative",this.scanNumberNegative+""); properties.setProperty(prefix+"scanNumberNegative",this.scanNumberNegative+"");
properties.setProperty(prefix+"scanHysteresis",this.scanHysteresis+""); properties.setProperty(prefix+"scanHysteresis",this.scanHysteresis+"");
properties.setProperty(prefix+"scanHysteresisNumber",this.scanHysteresisNumber+""); 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+"scanRunLMA",this.scanRunLMA+"");
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+"motorHysteresis",this.motorHysteresis+"");
properties.setProperty(prefix+"measuredHysteresis",this.measuredHysteresis+""); properties.setProperty(prefix+"measuredHysteresis",this.measuredHysteresis+"");
properties.setProperty(prefix+"motorCalm",this.motorCalm+""); properties.setProperty(prefix+"motorCalm",this.motorCalm+"");
properties.setProperty(prefix+"linearReductionRatio",this.linearReductionRatio+""); properties.setProperty(prefix+"linearReductionRatio",this.linearReductionRatio+"");
properties.setProperty(prefix+"motorDebug",this.motorDebug+""); properties.setProperty(prefix+"motorDebug",this.motorDebug+"");
properties.setProperty(prefix+"lensDistanceNumPoints",this.lensDistanceNumPoints+""); properties.setProperty(prefix+"lensDistanceNumPoints",this.lensDistanceNumPoints+"");
...@@ -938,6 +1017,12 @@ public class LensAdjustment { ...@@ -938,6 +1017,12 @@ public class LensAdjustment {
properties.setProperty(prefix+"lensDistanceShowResults",this.lensDistanceShowResults+""); properties.setProperty(prefix+"lensDistanceShowResults",this.lensDistanceShowResults+"");
properties.setProperty(prefix+"lensDistanceMoveToGoal",this.lensDistanceMoveToGoal+""); properties.setProperty(prefix+"lensDistanceMoveToGoal",this.lensDistanceMoveToGoal+"");
properties.setProperty(prefix+"powerControlEnable",this.powerControlEnable+"");
properties.setProperty(prefix+"powerControlMaximalTemperature",this.powerControlMaximalTemperature+"");
properties.setProperty(prefix+"powerControlHeaterOnMinutes",this.powerControlHeaterOnMinutes+"");
properties.setProperty(prefix+"powerControlNeitherOnMinutes",this.powerControlNeitherOnMinutes+"");
properties.setProperty(prefix+"powerControlFanOnMinutes",this.powerControlFanOnMinutes+"");
properties.setProperty(prefix+"uvLasersIP",this.uvLasersIP); properties.setProperty(prefix+"uvLasersIP",this.uvLasersIP);
properties.setProperty(prefix+"uvLasersBus",this.uvLasersBus+""); properties.setProperty(prefix+"uvLasersBus",this.uvLasersBus+"");
properties.setProperty(prefix+"uvLasersCurrents_0",this.uvLasersCurrents[0]+""); properties.setProperty(prefix+"uvLasersCurrents_0",this.uvLasersCurrents[0]+"");
...@@ -967,6 +1052,7 @@ public class LensAdjustment { ...@@ -967,6 +1052,7 @@ public class LensAdjustment {
properties.setProperty(prefix+"numIterations",this.numIterations+""); properties.setProperty(prefix+"numIterations",this.numIterations+"");
for (int i=0;i<this.ampsSeconds.length;i++) for (int i=0;i<this.ampsSeconds.length;i++)
properties.setProperty(prefix+"ampsSeconds_"+i,this.ampsSeconds[i]+""); properties.setProperty(prefix+"ampsSeconds_"+i,this.ampsSeconds[i]+"");
properties.setProperty(prefix+"reportTemperature",this.reportTemperature+"");
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"gridGeometryFile")!=null) if (properties.getProperty(prefix+"gridGeometryFile")!=null)
...@@ -977,6 +1063,12 @@ public class LensAdjustment { ...@@ -977,6 +1063,12 @@ public class LensAdjustment {
this.strategyFile=properties.getProperty(prefix+"strategyFile"); this.strategyFile=properties.getProperty(prefix+"strategyFile");
if (properties.getProperty(prefix+"resultsSuperDirectory")!=null) if (properties.getProperty(prefix+"resultsSuperDirectory")!=null)
this.resultsSuperDirectory=properties.getProperty(prefix+"resultsSuperDirectory"); this.resultsSuperDirectory=properties.getProperty(prefix+"resultsSuperDirectory");
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) if (properties.getProperty(prefix+"serialNumber")!=null)
this.serialNumber=properties.getProperty(prefix+"serialNumber"); this.serialNumber=properties.getProperty(prefix+"serialNumber");
// this.serialNumber is only written, but never read from the configuration file (only from devivce) // this.serialNumber is only written, but never read from the configuration file (only from devivce)
...@@ -1168,6 +1260,28 @@ public class LensAdjustment { ...@@ -1168,6 +1260,28 @@ public class LensAdjustment {
this.scanHysteresis=Boolean.parseBoolean(properties.getProperty(prefix+"scanHysteresis")); this.scanHysteresis=Boolean.parseBoolean(properties.getProperty(prefix+"scanHysteresis"));
if (properties.getProperty(prefix+"scanHysteresisNumber")!=null) if (properties.getProperty(prefix+"scanHysteresisNumber")!=null)
this.scanHysteresisNumber=Integer.parseInt(properties.getProperty(prefix+"scanHysteresisNumber")); this.scanHysteresisNumber=Integer.parseInt(properties.getProperty(prefix+"scanHysteresisNumber"));
if (properties.getProperty(prefix+"scanTiltEnable")!=null)
this.scanTiltEnable=Boolean.parseBoolean(properties.getProperty(prefix+"scanTiltEnable"));
if (properties.getProperty(prefix+"scanTiltReverse")!=null)
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+"scanRunLMA")!=null)
this.scanRunLMA=Boolean.parseBoolean(properties.getProperty(prefix+"scanRunLMA"));
if (properties.getProperty(prefix+"scanTiltRangeX")!=null)
this.scanTiltRangeX=Integer.parseInt(properties.getProperty(prefix+"scanTiltRangeX"));
if (properties.getProperty(prefix+"scanTiltRangeY")!=null)
this.scanTiltRangeY=Integer.parseInt(properties.getProperty(prefix+"scanTiltRangeY"));
if (properties.getProperty(prefix+"scanTiltStepsX")!=null)
this.scanTiltStepsX=Integer.parseInt(properties.getProperty(prefix+"scanTiltStepsX"));
if (properties.getProperty(prefix+"scanTiltStepsY")!=null)
this.scanTiltStepsY=Integer.parseInt(properties.getProperty(prefix+"scanTiltStepsY"));
if (properties.getProperty(prefix+"motorHysteresis")!=null) if (properties.getProperty(prefix+"motorHysteresis")!=null)
this.motorHysteresis=Integer.parseInt(properties.getProperty(prefix+"motorHysteresis")); this.motorHysteresis=Integer.parseInt(properties.getProperty(prefix+"motorHysteresis"));
if (properties.getProperty(prefix+"measuredHysteresis")!=null) if (properties.getProperty(prefix+"measuredHysteresis")!=null)
...@@ -1193,6 +1307,18 @@ public class LensAdjustment { ...@@ -1193,6 +1307,18 @@ public class LensAdjustment {
if (properties.getProperty(prefix+"lensDistanceMoveToGoal")!=null) if (properties.getProperty(prefix+"lensDistanceMoveToGoal")!=null)
this.lensDistanceMoveToGoal=Boolean.parseBoolean(properties.getProperty(prefix+"lensDistanceMoveToGoal")); this.lensDistanceMoveToGoal=Boolean.parseBoolean(properties.getProperty(prefix+"lensDistanceMoveToGoal"));
if (properties.getProperty(prefix+"powerControlEnable")!=null)
this.powerControlEnable=Boolean.parseBoolean(properties.getProperty(prefix+"powerControlEnable"));
if (properties.getProperty(prefix+"powerControlMaximalTemperature")!=null)
this.powerControlMaximalTemperature=Double.parseDouble(properties.getProperty(prefix+"powerControlMaximalTemperature"));
if (properties.getProperty(prefix+"powerControlHeaterOnMinutes")!=null)
this.powerControlHeaterOnMinutes=Double.parseDouble(properties.getProperty(prefix+"powerControlHeaterOnMinutes"));
if (properties.getProperty(prefix+"powerControlNeitherOnMinutes")!=null)
this.powerControlNeitherOnMinutes=Double.parseDouble(properties.getProperty(prefix+"powerControlNeitherOnMinutes"));
if (properties.getProperty(prefix+"powerControlFanOnMinutes")!=null)
this.powerControlFanOnMinutes=Double.parseDouble(properties.getProperty(prefix+"powerControlFanOnMinutes"));
if (properties.getProperty(prefix+"uvLasersIP")!=null) if (properties.getProperty(prefix+"uvLasersIP")!=null)
this.uvLasersIP=properties.getProperty(prefix+"uvLasersIP"); this.uvLasersIP=properties.getProperty(prefix+"uvLasersIP");
if (properties.getProperty(prefix+"uvLasersBus")!=null) if (properties.getProperty(prefix+"uvLasersBus")!=null)
...@@ -1246,9 +1372,10 @@ public class LensAdjustment { ...@@ -1246,9 +1372,10 @@ public class LensAdjustment {
this.thresholdFinish=Double.parseDouble(properties.getProperty(prefix+"thresholdFinish")); this.thresholdFinish=Double.parseDouble(properties.getProperty(prefix+"thresholdFinish"));
if (properties.getProperty(prefix+"numIterations")!=null) if (properties.getProperty(prefix+"numIterations")!=null)
this.numIterations=Integer.parseInt(properties.getProperty(prefix+"numIterations")); this.numIterations=Integer.parseInt(properties.getProperty(prefix+"numIterations"));
for (int i=0;i<this.ampsSeconds.length;i++) if (properties.getProperty(prefix+"ampsSeconds_"+i)!=null) for (int i=0;i<this.ampsSeconds.length;i++) if (properties.getProperty(prefix+"ampsSeconds_"+i)!=null)
this.ampsSeconds[i]=Double.parseDouble(properties.getProperty(prefix+"ampsSeconds_"+i)); this.ampsSeconds[i]=Double.parseDouble(properties.getProperty(prefix+"ampsSeconds_"+i));
if (properties.getProperty(prefix+"reportTemperature")!=null)
this.reportTemperature=Double.parseDouble(properties.getProperty(prefix+"reportTemperature"));
} }
public boolean getLensSerial(){ public boolean getLensSerial(){
while (true) { // loop until OK-ed while (true) { // loop until OK-ed
...@@ -1266,6 +1393,8 @@ public class LensAdjustment { ...@@ -1266,6 +1393,8 @@ public class LensAdjustment {
gd.addNumericField("Optional manufacturing state modifier (0.."+maxMod+")", manufacturingIndexMod[1], 0,1,""); gd.addNumericField("Optional manufacturing state modifier (0.."+maxMod+")", manufacturingIndexMod[1], 0,1,"");
gd.addCheckbox ("Ask lens serial number on each camera power cycle",this.askLensSerial); gd.addCheckbox ("Ask lens serial number on each camera power cycle",this.askLensSerial);
gd.addNumericField("Required X-shift between the lens axis and the sensor center", this.centerDeltaX, 0,4,"pix (180 for tilted)");
gd.addNumericField("Required Y-shift between the lens axis and the sensor center", this.centerDeltaY, 0,4,"pix");
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
this.comment= gd.getNextString(); this.comment= gd.getNextString();
...@@ -1276,6 +1405,8 @@ public class LensAdjustment { ...@@ -1276,6 +1405,8 @@ public class LensAdjustment {
int manIndex= gd.getNextChoiceIndex(); int manIndex= gd.getNextChoiceIndex();
int manMod= (int) gd.getNextNumber(); int manMod= (int) gd.getNextNumber();
this.askLensSerial= gd.getNextBoolean(); this.askLensSerial= gd.getNextBoolean();
this.centerDeltaX= gd.getNextNumber();
this.centerDeltaY= gd.getNextNumber();
if (manMod<0) manMod=0; if (manMod<0) manMod=0;
else if (manMod>maxMod) manMod=maxMod; else if (manMod>maxMod) manMod=maxMod;
if (manIndex<manufacturingIndexMod[0]){ if (manIndex<manufacturingIndexMod[0]){
...@@ -1294,6 +1425,54 @@ public class LensAdjustment { ...@@ -1294,6 +1425,54 @@ public class LensAdjustment {
} }
} }
} }
// subset of showDialog() - only set parameters realated to scanning
public boolean showScanningSetup(String title) {
GenericDialog gd = new GenericDialog(title);
gd.addNumericField("Motor single movement (all 3 motors) in scan focus mode (signed value)", this.scanStep, 0,7,"motors steps");
gd.addNumericField("Number of scan steps during (center) focus scanning", this.scanNumber, 0);
gd.addNumericField("... of them - in the negative direction (closer lens to sensor)", this.scanNumberNegative, 0);
gd.addCheckbox ("Scan focus in 2 directions, after the calibration estimate hysteresis (play)", this.scanHysteresis);
gd.addNumericField("Number of scan steps during hysteresis (play) measurement", this.scanHysteresisNumber, 0);
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.addCheckbox ("Calculate model parameters after scanning", this.scanRunLMA);
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");
gd.addNumericField("Number of stops measurements when tilting in X-deirection", this.scanTiltStepsX, 0);
gd.addNumericField("Number of stops measurements when tilting in Y-deirection", this.scanTiltStepsY, 0);
gd.addMessage("");
gd.addNumericField("Motor anti-hysteresis travel (last measured was "+IJ.d2s(this.measuredHysteresis,0)+")", this.motorHysteresis, 0,7,"motors steps");
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
this.scanStep= (int) gd.getNextNumber();
this.scanNumber= (int) gd.getNextNumber();
this.scanNumberNegative= (int) gd.getNextNumber();
this.scanHysteresis= gd.getNextBoolean();
this.scanHysteresisNumber= (int) gd.getNextNumber();
this.scanTiltEnable= gd.getNextBoolean();
this.scanTiltReverse= gd.getNextBoolean();
this.scanMeasureLast= gd.getNextBoolean();
this.scanRunLMA= gd.getNextBoolean();
this.scanTiltRangeX= (int) gd.getNextNumber();
this.scanTiltRangeY= (int) gd.getNextNumber();
this.scanTiltStepsX= (int) gd.getNextNumber();
this.scanTiltStepsY= (int) gd.getNextNumber();
this.motorHysteresis= (int) gd.getNextNumber();
return true;
}
public boolean showDialog(String title) { public boolean showDialog(String title) {
GenericDialog gd = new GenericDialog(title); GenericDialog gd = new GenericDialog(title);
// this.serialNumber, // camera serial number string // this.serialNumber, // camera serial number string
...@@ -1312,12 +1491,14 @@ public class LensAdjustment { ...@@ -1312,12 +1491,14 @@ public class LensAdjustment {
gd.addCheckbox ("Ask lens serial number on each camera power cycle",this.askLensSerial); gd.addCheckbox ("Ask lens serial number on each camera power cycle",this.askLensSerial);
gd.addCheckbox ("Add lens serial number to filenames",this.includeLensSerial); gd.addCheckbox ("Add lens serial number to filenames",this.includeLensSerial);
gd.addNumericField("Required X-shift between the lens axis and the sensor center", this.centerDeltaX, 0,4,"pix"); gd.addNumericField("Required X-shift between the lens axis and the sensor center", this.centerDeltaX, 0,4,"pix (180 for tilted)");
gd.addNumericField("Required Y-shift between the lens axis and the sensor center", this.centerDeltaY, 0,4,"pix"); gd.addNumericField("Required Y-shift between the lens axis and the sensor center", this.centerDeltaY, 0,4,"pix");
gd.addStringField ("Grid geometry file", this.gridGeometryFile,40); gd.addStringField ("Grid geometry file", this.gridGeometryFile,40);
gd.addStringField ("Initial camera intrinsic/extrinsic parametres file", this.initialCalibrationFile,40); gd.addStringField ("Initial camera intrinsic/extrinsic parametres file", this.initialCalibrationFile,40);
gd.addStringField ("Levenberg-Marquardt algorithm strategy file", this.strategyFile,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 ("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.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.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 ("Save SFE focusing results (including intermediate) ", this.saveResults);
gd.addCheckbox ("Show SFE focusing results (including intermediate) ", this.showResults); gd.addCheckbox ("Show SFE focusing results (including intermediate) ", this.showResults);
...@@ -1391,6 +1572,12 @@ public class LensAdjustment { ...@@ -1391,6 +1572,12 @@ public class LensAdjustment {
gd.addCheckbox ("Show results window from focal distance calibration", this.lensDistanceShowResults); gd.addCheckbox ("Show results window from focal distance calibration", this.lensDistanceShowResults);
gd.addCheckbox ("Move motors together to the requested microns from the \"best focus\"", this.lensDistanceMoveToGoal); gd.addCheckbox ("Move motors together to the requested microns from the \"best focus\"", this.lensDistanceMoveToGoal);
gd.addCheckbox ("Enable power control for heater and fan", this.powerControlEnable);
gd.addNumericField("Maximal allowed temperature", this.powerControlMaximalTemperature, 3,5,"C");
gd.addNumericField("Heater ON time", this.powerControlHeaterOnMinutes, 1,5,"min");
gd.addNumericField("Both heater and fan OFF time", this.powerControlNeitherOnMinutes, 1,5,"min");
gd.addNumericField("Fan ON time", this.powerControlFanOnMinutes, 1,5,"min");
gd.addStringField ("IP address of the camera with 103641 board (UV LEDs and lasers) are attached", this.uvLasersIP,40); gd.addStringField ("IP address of the camera with 103641 board (UV LEDs and lasers) are attached", this.uvLasersIP,40);
gd.addNumericField("I2C bus where LED/laser board is attached (0 - through 10359, 1 - through 10369)",this.uvLasersBus, 0); gd.addNumericField("I2C bus where LED/laser board is attached (0 - through 10359, 1 - through 10369)",this.uvLasersBus, 0);
gd.addNumericField("UV LED1 \"on\" current (left/near when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA"); gd.addNumericField("UV LED1 \"on\" current (left/near when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
...@@ -1414,6 +1601,17 @@ public class LensAdjustment { ...@@ -1414,6 +1601,17 @@ public class LensAdjustment {
gd.addCheckbox ("Scan focus in 2 directions, after the calibration estimate hysteresis (play)", this.scanHysteresis); gd.addCheckbox ("Scan focus in 2 directions, after the calibration estimate hysteresis (play)", this.scanHysteresis);
gd.addNumericField("Number of scan steps during hysteresis (play) measurement", this.scanHysteresisNumber, 0); gd.addNumericField("Number of scan steps during hysteresis (play) measurement", this.scanHysteresisNumber, 0);
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");
gd.addNumericField("Number of stops measurements when tilting in X-deirection", this.scanTiltStepsX, 0);
gd.addNumericField("Number of stops measurements when tilting in Y-deirection", this.scanTiltStepsY, 0);
gd.addMessage ("The following parameters overwrite some defined for aberration measurements in other dialogs"); gd.addMessage ("The following parameters overwrite some defined for aberration measurements in other dialogs");
gd.addNumericField("Smallest fraction to subdivide pixels at simulation", this.smallestSubPix, 3,5,"sensor pix"); gd.addNumericField("Smallest fraction to subdivide pixels at simulation", this.smallestSubPix, 3,5,"sensor pix");
gd.addNumericField("Maximal difference of the pattern value in the corners that triggers subdivision", this.bitmapNonuniforityThreshold, 3); gd.addNumericField("Maximal difference of the pattern value in the corners that triggers subdivision", this.bitmapNonuniforityThreshold, 3);
...@@ -1435,13 +1633,23 @@ public class LensAdjustment { ...@@ -1435,13 +1633,23 @@ public class LensAdjustment {
gd.addNumericField("Expand during extrapolation (relative to the average grid period)", this.flatFieldExpand, 3); gd.addNumericField("Expand during extrapolation (relative to the average grid period)", this.flatFieldExpand, 3);
gd.addNumericField("Threshold RMS to exit LMA", this.thresholdFinish, 7,9,"pix"); gd.addNumericField("Threshold RMS to exit LMA", this.thresholdFinish, 7,9,"pix");
gd.addNumericField("Maximal number of LMA iterations per series",this.numIterations, 0); gd.addNumericField("Maximal number of LMA iterations per series",this.numIterations, 0);
gd.addMessage("-----");
gd.addNumericField("Report focal length at this temperature", this.reportTemperature, 1,5,"C");
if (!Double.isNaN(this.sensorTemperature)) gd.addMessage("Last measured sensor temperature is "+this.sensorTemperature+" C"); if (!Double.isNaN(this.sensorTemperature)) gd.addMessage("Last measured sensor temperature is "+this.sensorTemperature+" C");
if (!Double.isNaN(this.result_lastKT)) gd.addMessage("Temperature focal distance coefficient measured in last run is "+this.result_lastKT+"microns/C"); if (!Double.isNaN(this.result_lastKT)) gd.addMessage("Temperature focal distance coefficient measured in last run is "+this.result_lastKT+"microns/C");
if (!Double.isNaN(this.result_lastFD20)) gd.addMessage("Focal distance @20C measured at last run is "+this.result_lastFD20+" microns"); if (!Double.isNaN(this.result_lastFD20)) gd.addMessage("Focal distance @20C measured at last run is "+this.result_lastFD20+" microns");
if (!Double.isNaN(this.result_lastKT) && !Double.isNaN(this.result_lastFD20)){
gd.addMessage("Focal distance @"+this.reportTemperature+"C measured at last run is "+
(this.result_lastFD20+(this.reportTemperature-20.0)*this.result_lastKT)+" microns");
}
if (!Double.isNaN(this.result_allHistoryKT)) gd.addMessage("Temperature focal distance coefficient calculated from all measurements is "+this.result_allHistoryKT+" microns"); if (!Double.isNaN(this.result_allHistoryKT)) gd.addMessage("Temperature focal distance coefficient calculated from all measurements is "+this.result_allHistoryKT+" microns");
if (!Double.isNaN(this.result_allHistoryFD20)) gd.addMessage("Focal distance @20C calculated from all measurements is "+this.result_allHistoryFD20+" microns"); if (!Double.isNaN(this.result_allHistoryFD20)) gd.addMessage("Focal distance @20C calculated from all measurements is "+this.result_allHistoryFD20+" microns");
if (!Double.isNaN(this.result_allHistoryKT) && !Double.isNaN(this.result_allHistoryFD20)){
gd.addMessage("Focal distance @"+this.reportTemperature+"C calculated from all measurements is "+
(this.result_allHistoryFD20+(this.reportTemperature-20.0)*this.result_allHistoryKT)+" microns");
}
if (!Double.isNaN(this.result_fDistance)) gd.addMessage("Focal distance is "+this.result_fDistance+" microns"); if (!Double.isNaN(this.result_fDistance)) gd.addMessage("Focal distance is "+this.result_fDistance+" microns");
if (!Double.isNaN(this.result_tiltX)) gd.addMessage("Horizontal angular/tangential asymmetry "+this.result_tiltX); if (!Double.isNaN(this.result_tiltX)) gd.addMessage("Horizontal angular/tangential asymmetry "+this.result_tiltX);
if (!Double.isNaN(this.result_tiltY)) gd.addMessage("Vertical angular/tangential asymmetry "+this.result_tiltY); if (!Double.isNaN(this.result_tiltY)) gd.addMessage("Vertical angular/tangential asymmetry "+this.result_tiltY);
...@@ -1457,6 +1665,7 @@ public class LensAdjustment { ...@@ -1457,6 +1665,7 @@ public class LensAdjustment {
if (!Double.isNaN(this.result_FocalLength)) gd.addMessage("Lens focal length "+this.result_FocalLength+" mm"); if (!Double.isNaN(this.result_FocalLength)) gd.addMessage("Lens focal length "+this.result_FocalLength+" mm");
gd.addMessage("Cumulative currents that ran through UV LEDs:"); gd.addMessage("Cumulative currents that ran through UV LEDs:");
for (int i=0;i<this.ampsSeconds.length;i++) gd.addMessage("UV LED "+(i+1)+":"+IJ.d2s(this.ampsSeconds[i],3)+" coulombs (amp-seconds)"); for (int i=0;i<this.ampsSeconds.length;i++) gd.addMessage("UV LED "+(i+1)+":"+IJ.d2s(this.ampsSeconds[i],3)+" coulombs (amp-seconds)");
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
...@@ -1482,6 +1691,9 @@ public class LensAdjustment { ...@@ -1482,6 +1691,9 @@ public class LensAdjustment {
this.initialCalibrationFile= gd.getNextString(); this.initialCalibrationFile= gd.getNextString();
this.strategyFile= gd.getNextString(); this.strategyFile= gd.getNextString();
this.resultsSuperDirectory= gd.getNextString(); this.resultsSuperDirectory= gd.getNextString();
this.focusingHistoryFile= gd.getNextString();
this.useLMAMetrics = gd.getNextBoolean();
this.EEPROM_channel= (int) gd.getNextNumber(); this.EEPROM_channel= (int) gd.getNextNumber();
this.saveResults= gd.getNextBoolean(); this.saveResults= gd.getNextBoolean();
this.showResults= gd.getNextBoolean(); this.showResults= gd.getNextBoolean();
...@@ -1550,6 +1762,12 @@ public class LensAdjustment { ...@@ -1550,6 +1762,12 @@ public class LensAdjustment {
this.lensDistanceShowResults= gd.getNextBoolean(); this.lensDistanceShowResults= gd.getNextBoolean();
this.lensDistanceMoveToGoal= gd.getNextBoolean(); this.lensDistanceMoveToGoal= gd.getNextBoolean();
this.powerControlEnable= gd.getNextBoolean();
this.powerControlMaximalTemperature=gd.getNextNumber();
this.powerControlHeaterOnMinutes= gd.getNextNumber();
this.powerControlNeitherOnMinutes= gd.getNextNumber();
this.powerControlFanOnMinutes= gd.getNextNumber();
this.uvLasersIP= gd.getNextString(); this.uvLasersIP= gd.getNextString();
this.uvLasersBus= (int) gd.getNextNumber(); this.uvLasersBus= (int) gd.getNextNumber();
this.uvLasersCurrents[0]= gd.getNextNumber(); this.uvLasersCurrents[0]= gd.getNextNumber();
...@@ -1571,6 +1789,16 @@ public class LensAdjustment { ...@@ -1571,6 +1789,16 @@ public class LensAdjustment {
this.scanNumberNegative= (int) gd.getNextNumber(); this.scanNumberNegative= (int) gd.getNextNumber();
this.scanHysteresis= gd.getNextBoolean(); this.scanHysteresis= gd.getNextBoolean();
this.scanHysteresisNumber= (int) gd.getNextNumber(); this.scanHysteresisNumber= (int) gd.getNextNumber();
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();
this.scanTiltStepsY= (int) gd.getNextNumber();
this.smallestSubPix= gd.getNextNumber(); this.smallestSubPix= gd.getNextNumber();
this.bitmapNonuniforityThreshold=gd.getNextNumber(); this.bitmapNonuniforityThreshold=gd.getNextNumber();
this.subdiv= (int) gd.getNextNumber(); this.subdiv= (int) gd.getNextNumber();
...@@ -1591,6 +1819,7 @@ public class LensAdjustment { ...@@ -1591,6 +1819,7 @@ public class LensAdjustment {
this.flatFieldExpand= gd.getNextNumber(); this.flatFieldExpand= gd.getNextNumber();
this.thresholdFinish= gd.getNextNumber(); this.thresholdFinish= gd.getNextNumber();
this.numIterations= (int) gd.getNextNumber(); this.numIterations= (int) gd.getNextNumber();
this.reportTemperature= gd.getNextNumber();
return true; return true;
} }
/* ======================================================================== */ /* ======================================================================== */
......
...@@ -5332,6 +5332,7 @@ java.lang.ArrayIndexOutOfBoundsException: -3566 ...@@ -5332,6 +5332,7 @@ java.lang.ArrayIndexOutOfBoundsException: -3566
if (mask[i]<maskCutOff) mask[i]=0.0; if (mask[i]<maskCutOff) mask[i]=0.0;
int size = (int) Math.sqrt(psf.length); int size = (int) Math.sqrt(psf.length);
int hsize=size/2; int hsize=size/2;
// int nn=0;
double S0=0.0, SR=0.0, ST=0.0,SR2=0.0,ST2=0.0; //,SRT=0.0; double S0=0.0, SR=0.0, ST=0.0,SR2=0.0,ST2=0.0; //,SRT=0.0;
for (int i=0;i<mask.length;i++) if (mask[i]>0.0) { for (int i=0;i<mask.length;i++) if (mask[i]>0.0) {
double x=(i % size) - hsize; double x=(i % size) - hsize;
...@@ -5344,13 +5345,62 @@ java.lang.ArrayIndexOutOfBoundsException: -3566 ...@@ -5344,13 +5345,62 @@ java.lang.ArrayIndexOutOfBoundsException: -3566
ST+=d*tc; ST+=d*tc;
SR2+=d*rc*rc; SR2+=d*rc*rc;
ST2+=d*tc*tc; ST2+=d*tc*tc;
// SRT+=d*rc*tc; // nn++;
} }
if (S0==0.0) return null; // make sure it is OK if (S0==0.0) return null; // make sure it is OK
double [] result={ Math.sqrt(ST2*S0 - ST*ST)/S0, Math.sqrt(SR2*S0 - SR*SR)/S0}; double [] result={ Math.sqrt(ST2*S0 - ST*ST)/S0, Math.sqrt(SR2*S0 - SR*SR)/S0};
// System.out.println(" mask.length="+mask.length+" nn="+nn+" S0="+S0+" SR="+SR+" ST="+ST+" SR2="+SR2+" ST2="+ST2+
// " result={"+result[0]+","+result[1]+"}");
return result; return result;
} }
//====================================================
public double [] x2y2xySizes(
double [] psf, // PSF function, square array, nominally positive
double cutoffEnergy, // fraction of energy in the pixels to be used
double cutoffLevel, // minimal level as a fraction of maximal
int minArea, // minimal selected area in pixels
double blurSigma, // optionally blur the selection
double maskCutOff,
int debugLevel, // debug level
String title) { // prefix used for debug images
double [] mask=findClusterOnPSF(
psf,
cutoffEnergy,
cutoffLevel,
minArea,
blurSigma,
debugLevel,
title);
for (int i=0;i<mask.length;i++)
if (mask[i]<maskCutOff) mask[i]=0.0;
int size = (int) Math.sqrt(psf.length);
int hsize=size/2;
// int nn=0;
double S0=0.0, SX=0.0, SY=0.0,SX2=0.0,SY2=0.0,SXY=0.0;
for (int i=0;i<mask.length;i++) if (mask[i]>0.0) {
double x=(i % size) - hsize;
double y=(i / size) - hsize;
double d=psf[i]*mask[i];
S0+=d;
SX+=d*x;
SY+=d*y;
SX2+=d*x*x;
SY2+=d*y*y;
SXY+=d*x*y;
// nn++;
}
if (S0==0.0) return null; // make sure it is OK
double [] result={
(SX2*S0 - SX*SX)/S0/S0,
(SY2*S0 - SY*SY)/S0/S0,
(SXY*S0 - SX*SY)/S0/S0}; // this may be negative
// System.out.println(" mask.length="+mask.length+" nn="+nn+" S0="+S0+" SX="+SX+" SY="+SY+" SX2="+SXR2+" SY2="+SY2+" SXY="+SXY+
// " result={"+result[0]+","+result[1]+","+result[2]+"}");
return result;
}
//==================================================== //====================================================
public double [] findClusterOnPSF( public double [] findClusterOnPSF(
...@@ -5382,7 +5432,8 @@ java.lang.ArrayIndexOutOfBoundsException: -3566 ...@@ -5382,7 +5432,8 @@ java.lang.ArrayIndexOutOfBoundsException: -3566
} }
if (maxValue<=0.0){ if (maxValue<=0.0){
String msg="psf array does not contain any positive values"; String msg="psf array does not contain any positive values";
IJ.showMessage("Error",msg); // IJ.showMessage("Error",msg);
System.out.println("Error "+msg);
throw new IllegalArgumentException (msg); throw new IllegalArgumentException (msg);
} }
ix=Index % size; ix=Index % size;
...@@ -8506,6 +8557,7 @@ d()/dy=C*x+2*B*y+E=0 ...@@ -8506,6 +8557,7 @@ d()/dy=C*x+2*B*y+E=0
IJ.showMessage("Error",msg); IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg); throw new IllegalArgumentException (msg);
} }
if (this.PATTERN_GRID.length==0) return null;
double x1=x0,y1=y0; double x1=x0,y1=y0;
double x2=x1+size; double x2=x1+size;
double y2=y1+size; double y2=y1+size;
......
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
# #
# If something like ("<arg>") is appended to the class name, the setup() method # If something like ("<arg>") is appended to the class name, the setup() method
# will get that as arg parameter; otherwise arg is simply the empty string. # will get that as arg parameter; otherwise arg is simply the empty string.
Process, "Process Pixels", Process_Pixels #Process, "Process Pixels", Process_Pixels
Process, "Aberration Calibration", Aberration_Calibration Process, "Aberration Calibration", Aberration_Calibration
#Plugins, "Aberration Calibration", Aberration_Calibration #Plugins, "Aberration Calibration", Aberration_Calibration
#Process, "Aberration Correction", Aberration_Correction #Process, "Aberration Correction", Aberration_Correction
Process, "Eyesis Correction", Eyesis_Correction Process, "Eyesis Correction", Eyesis_Correction
#Process, "JP46 Reader camera", JP46_Reader_camera Process, "JP46 Reader camera", JP46_Reader_camera
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment