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 @@
<version>1.135</version>
<relativePath />
</parent>
<!--
<properties>
<imagej.app.directory>/data/ImageJ/ImageJ</imagej.app.directory>
</properties>
-->
<groupId>com.elphel</groupId>
<artifactId>imagej-elphel</artifactId>
<!-- <artifactId>Aberration_Calibration</artifactId> -->
<version>1.0.0</version>
<name>plugins/ImageJ_Elphel.jar</name>
<name>plugins/imagej_elphel.jar</name>
<!-- <name>plugins/Aberration_Calibration.jar</name> -->
<description>A Maven project implementing imagej-elphel plugin</description>
......@@ -74,9 +78,8 @@
<artifactId>maven-plugin-plugin</artifactId>
<configuration>
<!-- see http://jira.codehaus.org/browse/MNG-5346 -->
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
......@@ -85,6 +88,7 @@
</goals>
</execution>
</executions>
</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;
import ij.process.ImageProcessor;
import ij.text.TextWindow;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
......@@ -44,12 +47,15 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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.Node;
import org.xml.sax.SAXException;
......@@ -1792,12 +1798,129 @@ public class CalibrationHardwareInterface {
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 int debugLevel=1;
......@@ -2513,7 +2636,7 @@ public class CalibrationHardwareInterface {
public FocusingSharpness focusingSharpness=new FocusingSharpness(1000);
public int debugLevel=1;
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();
public boolean interactiveRestore=true; // ask for confirmation to restore motor position
public boolean stateValid=false;
......@@ -2528,6 +2651,12 @@ public class CalibrationHardwareInterface {
public double getMicronsPerStep(){return 1000.0*this.threadPitch*this.linearReductionRatio/stepsPerRevolution;}
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(){
return this.stateValid;
}
......@@ -2568,7 +2697,7 @@ public class CalibrationHardwareInterface {
public void saveMotorState() throws IOException{
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]+"");
String path=this.prefsDirectory+this.motorsStatePath;
String path=this.getPrefsDir()+this.motorsStatePath;
OutputStream os;
try {
os = new FileOutputStream(path);
......@@ -2600,7 +2729,7 @@ public class CalibrationHardwareInterface {
}
public int [] loadMotorState() throws IOException{
String path=this.prefsDirectory+this.motorsStatePath;
String path=this.getPrefsDir()+this.motorsStatePath;
InputStream is;
try {
is = new FileInputStream(path);
......@@ -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.interactiveRestore){
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 select \"Cancel\" the current command will be aborted, you may check the file and restart the program.");
gd.showDialog();
......@@ -2966,7 +3095,25 @@ public class CalibrationHardwareInterface {
fullResults
);
}
public FocusingField.FocusingFieldMeasurement getThisFFMeasurement(
FocusingField focusingField,
String sTimestamp,
double temperature,
double[][] psfMetrics,
double [][][][] fullResults){
return focusingField.getFocusingFieldMeasurement(
sTimestamp, //focusingState.getTimestamp(),
temperature, //focusingState.getTemperature(),
this.curpos, //focusingState.motorsPos,
fullResults); //focusingState.getSamples());
}
/*
* FocusingHistory.FocusingState focusingState
public void addToHistory( String sTimestamp,double temperature, double[][] psfMetrics){ // null OK
this.focusingHistory.add(
sTimestamp,
......@@ -2993,6 +3140,7 @@ public class CalibrationHardwareInterface {
}
public void listHistory(
boolean useLMA,
String path,
String lensSerial,
String comment,
......@@ -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
){
listHistory(
useLMA,
path,
"",
lensSerial,
......@@ -3022,6 +3171,7 @@ public class CalibrationHardwareInterface {
}
public void listHistory(
boolean useLMA,
String path,
String serialNumber,
String lensSerial,
......@@ -3040,6 +3190,7 @@ public class CalibrationHardwareInterface {
){
this.focusingHistory.list(
useLMA,
path,
serialNumber,
lensSerial,
......@@ -3056,7 +3207,84 @@ public class CalibrationHardwareInterface {
result_lastKT,
result_allHistoryKT);
}
public int historySize(){
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(){
return this.focusingHistory.history.size();
}
public void setLastProbed(){
......@@ -3808,10 +4036,18 @@ public class CalibrationHardwareInterface {
if (this.history.size()<1) return null;
return getCenterResolutions(this.history.size()-1);
}
public double [] getCenterResolutions(int index){
public double [] getCenterResolutions(int index){
if ((index<0) || (index>=this.history.size())) return null;
return this.history.get(index).getCenterResolutions();
}
}
public double [] getzTxTy(int index){
if ((index<0) || (index>=this.history.size())) return null;
return this.history.get(index).getzTxTy();
}
public double [] getzTxTy(){
if (this.history.size()<1) return null;
return getzTxTy(this.history.size()-1);
}
public int size(){
return this.history.size();
}
......@@ -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
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
if (metrics==null) continue;
double l2=
1.0/metrics[0][indexR50]/metrics[0][indexR50]+
1.0/metrics[1][indexR50]/metrics[1][indexR50]+
......@@ -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}
*/
public double [] temperatureLinearApproximation(
boolean useLMA,
int numSamples, // number of last samples from history to use, 0 - use all
double lensDistanceWeightK, // used in distance calculation
double lensDistanceWeightY // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution
......@@ -4991,20 +5229,53 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
int firstSample=this.history.size()-numSamples;
for (int nSample=0;nSample<numSamples;nSample++){
resolutions= this.history.get(firstSample+nSample).getCenterResolutions();
data[nSample][0]=this.history.get(firstSample+nSample).getTemperature();
data[nSample][1]=getLensDistance(
resolutions, // {R-sharpness,G-sharpness,B-sharpness}
true, // boolean absolute, // return absolutely calibrated data
lensDistanceWeightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives
lensDistanceWeightY, // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution
1 //debugLevel
);
if (useLMA){
data[nSample][1]=this.history.get(firstSample+nSample).getzTxTy()[0];
} else {
resolutions= this.history.get(firstSample+nSample).getCenterResolutions();
data[nSample][1]=getLensDistance(
resolutions, // {R-sharpness,G-sharpness,B-sharpness}
true, // boolean absolute, // return absolutely calibrated data
lensDistanceWeightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives
lensDistanceWeightY, // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution
1 //debugLevel
);
}
}
PolynomialApproximation pa= new PolynomialApproximation(debugLevel);
double [] polyCoeff=pa.polynomialApproximation1d(data, 1); // just linear
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
* @param useTheBest
......@@ -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?)
public void list(
boolean useLMA,
String path,
String lensSerial, // if null - do not add average
String comment,
......@@ -5420,8 +5692,10 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
double weightRatioBlueToGreen,
double weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives
double weightY){ // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution
list (path,
"",
list (
useLMA,
path,
"", // serial; number
lensSerial, // if null - do not add average
comment,
showIndividualComponents,
......@@ -5436,9 +5710,99 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
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(
boolean useLMA,
String path,
String serialNumber,
String lensSerial, // if null - do not add average
......@@ -5479,14 +5843,18 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
if (showIndividualSamples){
if (showIndividualComponents) { // additional 3 per-color rows
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 {
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"+
"\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";
// 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+"_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]+" "
if (showIndividualComponents) {
for (int i=0;i<this.history.size();i++){
FocusingState focusingState=this.history.get(i);
double [] zTxTy=useLMA?focusingState.getzTxTy():null;
double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen);
double [][] resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen);
double dist= getLensDistance(
double dist= (zTxTy==null)?getLensDistance(
focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness}
true, //boolean absolute, // return absolutely calibrated data
weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives
weightY, // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution
1); //int debugLevel
1): //int debugLevel
zTxTy[0];
double [] averageMetrics=metrics[3];
if (zTxTy!=null){
averageMetrics=metrics[3].clone(); // to modify w/o changing original
averageMetrics[1]=zTxTy[1]; // tiltX
averageMetrics[2]=zTxTy[2]; // tiltY
}
double [] averageResolution=resolution[3];
sb.append((i+1)+"\t");
String timestamp=focusingState.getTimestamp();
......@@ -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)) {
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][2],3));
} 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]+" "
for (int i=0;i<this.history.size();i++){
// int parIndex=0;
FocusingState focusingState=this.history.get(i);
double [] zTxTy=useLMA?focusingState.getzTxTy():null;
double [][] metrics=focusingState.getMetrics(weightRatioRedToGreen,weightRatioBlueToGreen);
double [][] resolution=focusingState.getSharpness(weightRatioRedToGreen,weightRatioBlueToGreen);
double [][] 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];
if (zTxTy!=null){
averageMetrics=metrics[3].clone(); // to modify w/o changing original
averageMetrics[1]=zTxTy[1]; // tiltX
averageMetrics[2]=zTxTy[2]; // tiltY
}
double [] averageResolution=resolution[3];
if (!justSummary) sb.append((i+1)+"\t");
String timestamp=focusingState.getTimestamp();
......@@ -5599,12 +5987,13 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
sums[4]+=focusingState.motorsPos[0];
sums[5]+=focusingState.motorsPos[1];
sums[6]+=focusingState.motorsPos[2];
double dist= getLensDistance(
focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness}
true, //boolean absolute, // return absolutely calibrated data
weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives
weightY, // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution
1); //int debugLevel
double dist= (zTxTy==null)?getLensDistance(
focusingState.getCenterResolutions(), // {R-sharpness,G-sharpness,B-sharpness}
true, //boolean absolute, // return absolutely calibrated data
weightK, // 0.0 - all 3 component errors are combined with the same weights. 1.0 - proportional to squared first derivatives
weightY, // R-frac, Y-frac have the same scale regardless of the sharpness, but not Y. This is to balance Y contribution
1): //int debugLevel
zTxTy[0];
if (Double.isNaN(dist)){
if (!justSummary) sb.append("\t---");
} else {
......@@ -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)) {
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][2],3));
} 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]+" "
double weightBlue){
double [][] metrics=getMetrics(weightRed, weightGreen, weightBlue);
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[2][this.indexR50All],1.0/metrics[2][this.indexR50Center]},
{0.0,0.0}};
......@@ -5976,11 +6366,15 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
return sharpness;
}
public double [] getCenterResolutions(){
try {
double [] resolutions={
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[2]][this.indexR50Center]}; // blue, r50% center
return resolutions;
} catch (Exception e){
return null;
}
}
public double [][] getMetrics(
......@@ -5991,7 +6385,19 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
1.0,
weightRatioBlueToGreen);
}
// alternative mode (from aberration model) ising metrics[6][]
public double [] getzTxTy(){
if (this.psfMetricses==null){
return null;
}
if ((this.psfMetricses.length<7) || (this.psfMetricses[6]==null)) {
System.out.println("BUG? psfMetrics does not have line 6 with lens berration model z, tx, ty");
return null;
}
double [] zTxTy={this.psfMetricses[6][0],this.psfMetricses[6][1],this.psfMetricses[6][2]};
return zTxTy;
}
public double [][] getMetrics(
double weightRed,
double weightGreen,
......@@ -6002,8 +6408,12 @@ if (debugLevel>=debugThreshold) System.out.println(i+" "+diff[0]+" "+diff[1]+" "
double w=0.0;
for (int i=0;i<weights.length;i++) w+=weights[i];
for (int i=0;i<weights.length;i++) weights[i]/=w;
metrics[3]=new double[this.psfMetricses[this.indices[0]].length];
for (int c=0;c<3;c++) metrics[c]= this.psfMetricses[this.indices[c]];
try {
metrics[3]=new double[this.psfMetricses[this.indices[0]].length];
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++) {
metrics[3][i]=0.0;
if (squared[i]){
......
......@@ -12398,7 +12398,7 @@ Which parameters affect which matrices
public int getGoniometerHorizontalIndex(){return 6;}
public int getGoniometerAxialIndex(){return 7;}
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 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
......@@ -13952,6 +13952,33 @@ Which parameters affect which matrices
this.flipVertical=flipVertical;
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
){
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 {
public static class FocusMeasurementParameters {
public String gridGeometryFile="";
public String initialCalibrationFile="";
public String focusingHistoryFile="";
public boolean useLMAMetrics=true; // measure/report focal distance and tilts using lens model/LMA (when available)
public String strategyFile="";
public String resultsSuperDirectory=""; // directory with subdirectories named as serial numbers to stro results
public int EEPROM_channel=1; // EEPROM channel to read serial number from
......@@ -224,13 +226,14 @@ public class LensAdjustment {
public int lensSerialLength=4;
public String lensSerial=""; // Lens serial number
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 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
// 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 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 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
......@@ -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 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 scanNumberNegative=15; // number of scanStep steps negative from the start
public boolean scanHysteresis=true; // scan both ways
public int scanNumberNegative=20; // 15; // number of scanStep steps negative from the start
public boolean scanHysteresis=false; // true; // scan both ways
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 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
......@@ -318,6 +331,12 @@ public class LensAdjustment {
public boolean lensDistanceShowResults=true; // show results window from foca
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 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)
......@@ -405,7 +424,7 @@ public class LensAdjustment {
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_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_PX0=Double.NaN; // lens center shift, X
this.result_PY0=Double.NaN; // lens center shift, Y
......@@ -418,6 +437,8 @@ public class LensAdjustment {
String initialCalibrationFile,
String strategyFile,
String resultsSuperDirectory, // directory with subdirectories named as serial numbers to stro results
String focusingHistoryFile,
boolean useLMAMetrics, // measure/report focal distance and tilts using lens model/LMA (when available)
int EEPROM_channel, // EEPROM channel to read serial number from
boolean saveResults, // save focusing results
boolean showResults, // show focusing (includingh intermediate) results
......@@ -509,6 +530,17 @@ public class LensAdjustment {
int scanNumberNegative, // of them negative
boolean scanHysteresis, // scan both ways
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,
double measuredHysteresis, // actually measured (will be saved/restored)
double motorCalm, // wait (seconds) after motors reached final position (for the first time) before acquiring image
......@@ -521,6 +553,11 @@ public class LensAdjustment {
boolean lensDistanceInteractive, // Open dialog when calibrating focal distance
boolean lensDistanceShowResults, // show results window from foca
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
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)
......@@ -547,12 +584,15 @@ public class LensAdjustment {
int numIterations, // maximal number of iterations
boolean cameraIsConfigured,
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.initialCalibrationFile=initialCalibrationFile;
this.strategyFile=strategyFile;
this.resultsSuperDirectory=resultsSuperDirectory; // directory with subdirectories named as serial numbers to stro results
this.focusingHistoryFile=focusingHistoryFile;
this.useLMAMetrics=useLMAMetrics; // measure/report focal distance and tilts using lens model/LMA (when available)
this.EEPROM_channel=EEPROM_channel; // EEPROM channel to read serial number from
this.saveResults=saveResults; // save focusing results
this.showResults=showResults; // show focusing (includingh intermediate) results
......@@ -643,6 +683,16 @@ public class LensAdjustment {
this.scanNumberNegative=scanNumberNegative; // of them negative
this.scanHysteresis=scanHysteresis; // scan both ways
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.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
......@@ -655,6 +705,11 @@ public class LensAdjustment {
this.lensDistanceInteractive=lensDistanceInteractive; // Open dialog when calibrating focal distance
this.lensDistanceShowResults=lensDistanceShowResults; // show results window from foca
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.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)
......@@ -681,7 +736,7 @@ public class LensAdjustment {
this.cameraIsConfigured=cameraIsConfigured;
this.motorPos=motorPos;
this.ampsSeconds=ampsSeconds; // cumulative Amps*seconds (read only, but will be saved/restored)
this.reportTemperature=reportTemperature;
}
public FocusMeasurementParameters clone(){
......@@ -690,6 +745,8 @@ public class LensAdjustment {
this.initialCalibrationFile,
this.strategyFile,
this.resultsSuperDirectory, // directory with subdirectories named as serial numbers to stro results
this.focusingHistoryFile,
this.useLMAMetrics, // measure/report focal distance and tilts using lens model/LMA (when available)
this.EEPROM_channel,// EEPROM channel to read serial number from
this.saveResults, // save focusing results
this.showResults, // show focusing (includingh intermediate) results
......@@ -779,7 +836,17 @@ public class LensAdjustment {
this.scanNumberNegative, // of them negative
this.scanHysteresis, // scan both ways
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.measuredHysteresis, // actually measured (will be saved/restored)
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
......@@ -791,6 +858,11 @@ public class LensAdjustment {
this.lensDistanceInteractive, // Open dialog when calibrating focal distance
this.lensDistanceShowResults, // show results window from foca
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.uvLasersBus, // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369
this.uvLasersCurrents, // default LED on currents (mA)
......@@ -817,7 +889,8 @@ public class LensAdjustment {
this.numIterations,
this.cameraIsConfigured,
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){
......@@ -825,6 +898,8 @@ public class LensAdjustment {
properties.setProperty(prefix+"initialCalibrationFile",this.initialCalibrationFile+"");
properties.setProperty(prefix+"strategyFile",this.strategyFile+"");
properties.setProperty(prefix+"resultsSuperDirectory",this.resultsSuperDirectory+"");
properties.setProperty(prefix+"focusingHistoryFile",this.focusingHistoryFile+"");
properties.setProperty(prefix+"useLMAMetrics",this.useLMAMetrics+"");
properties.setProperty(prefix+"serialNumber",this.serialNumber+"");
if (!Double.isNaN(this.sensorTemperature))properties.setProperty(prefix+"sensorTemperature",this.sensorTemperature+"");
if (!Double.isNaN(this.result_lastKT))properties.setProperty(prefix+"result_lastKT",this.result_lastKT+"");
......@@ -919,15 +994,19 @@ public class LensAdjustment {
properties.setProperty(prefix+"scanStep",this.scanStep+"");
properties.setProperty(prefix+"scanNumber",this.scanNumber+"");
properties.setProperty(prefix+"scanNumberNegative",this.scanNumberNegative+"");
properties.setProperty(prefix+"scanHysteresis",this.scanHysteresis+"");
properties.setProperty(prefix+"scanHysteresisNumber",this.scanHysteresisNumber+"");
properties.setProperty(prefix+"scanTiltEnable",this.scanTiltEnable+""); // enable scanning tilt
properties.setProperty(prefix+"scanTiltReverse",this.scanTiltReverse+"");
properties.setProperty(prefix+"scanMeasureLast",this.scanMeasureLast+"");
properties.setProperty(prefix+"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+"measuredHysteresis",this.measuredHysteresis+"");
properties.setProperty(prefix+"motorCalm",this.motorCalm+"");
properties.setProperty(prefix+"linearReductionRatio",this.linearReductionRatio+"");
properties.setProperty(prefix+"motorDebug",this.motorDebug+"");
properties.setProperty(prefix+"lensDistanceNumPoints",this.lensDistanceNumPoints+"");
......@@ -937,7 +1016,13 @@ public class LensAdjustment {
properties.setProperty(prefix+"lensDistanceInteractive",this.lensDistanceInteractive+"");
properties.setProperty(prefix+"lensDistanceShowResults",this.lensDistanceShowResults+"");
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+"uvLasersBus",this.uvLasersBus+"");
properties.setProperty(prefix+"uvLasersCurrents_0",this.uvLasersCurrents[0]+"");
......@@ -967,6 +1052,7 @@ public class LensAdjustment {
properties.setProperty(prefix+"numIterations",this.numIterations+"");
for (int i=0;i<this.ampsSeconds.length;i++)
properties.setProperty(prefix+"ampsSeconds_"+i,this.ampsSeconds[i]+"");
properties.setProperty(prefix+"reportTemperature",this.reportTemperature+"");
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"gridGeometryFile")!=null)
......@@ -977,6 +1063,12 @@ public class LensAdjustment {
this.strategyFile=properties.getProperty(prefix+"strategyFile");
if (properties.getProperty(prefix+"resultsSuperDirectory")!=null)
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)
this.serialNumber=properties.getProperty(prefix+"serialNumber");
// this.serialNumber is only written, but never read from the configuration file (only from devivce)
......@@ -1168,6 +1260,28 @@ public class LensAdjustment {
this.scanHysteresis=Boolean.parseBoolean(properties.getProperty(prefix+"scanHysteresis"));
if (properties.getProperty(prefix+"scanHysteresisNumber")!=null)
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)
this.motorHysteresis=Integer.parseInt(properties.getProperty(prefix+"motorHysteresis"));
if (properties.getProperty(prefix+"measuredHysteresis")!=null)
......@@ -1192,6 +1306,18 @@ public class LensAdjustment {
this.lensDistanceShowResults=Boolean.parseBoolean(properties.getProperty(prefix+"lensDistanceShowResults"));
if (properties.getProperty(prefix+"lensDistanceMoveToGoal")!=null)
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)
this.uvLasersIP=properties.getProperty(prefix+"uvLasersIP");
......@@ -1246,9 +1372,10 @@ public class LensAdjustment {
this.thresholdFinish=Double.parseDouble(properties.getProperty(prefix+"thresholdFinish"));
if (properties.getProperty(prefix+"numIterations")!=null)
this.numIterations=Integer.parseInt(properties.getProperty(prefix+"numIterations"));
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));
if (properties.getProperty(prefix+"reportTemperature")!=null)
this.reportTemperature=Double.parseDouble(properties.getProperty(prefix+"reportTemperature"));
}
public boolean getLensSerial(){
while (true) { // loop until OK-ed
......@@ -1266,6 +1393,8 @@ public class LensAdjustment {
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.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();
if (gd.wasCanceled()) return false;
this.comment= gd.getNextString();
......@@ -1276,6 +1405,8 @@ public class LensAdjustment {
int manIndex= gd.getNextChoiceIndex();
int manMod= (int) gd.getNextNumber();
this.askLensSerial= gd.getNextBoolean();
this.centerDeltaX= gd.getNextNumber();
this.centerDeltaY= gd.getNextNumber();
if (manMod<0) manMod=0;
else if (manMod>maxMod) manMod=maxMod;
if (manIndex<manufacturingIndexMod[0]){
......@@ -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) {
GenericDialog gd = new GenericDialog(title);
// this.serialNumber, // camera serial number string
......@@ -1312,12 +1491,14 @@ public class LensAdjustment {
gd.addCheckbox ("Ask lens serial number on each camera power cycle",this.askLensSerial);
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.addStringField ("Grid geometry file", this.gridGeometryFile,40);
gd.addStringField ("Initial camera intrinsic/extrinsic parametres file", this.initialCalibrationFile,40);
gd.addStringField ("Levenberg-Marquardt algorithm strategy file", this.strategyFile,40);
gd.addStringField ("Focusing results superdirectory (individual will be named by serial numbers)", this.resultsSuperDirectory,40);
gd.addStringField ("Measurement history (acquired during \"Scan Calib LMA\") file", this.focusingHistoryFile,80);
gd.addCheckbox ("Use lens aberration model (if available) for focal distance and tilts", this.useLMAMetrics);
gd.addNumericField("EEPROM channel to read sensor serial number from", this.EEPROM_channel, 0,4,"");
gd.addCheckbox ("Save SFE focusing results (including intermediate) ", this.saveResults);
gd.addCheckbox ("Show SFE focusing results (including intermediate) ", this.showResults);
......@@ -1391,12 +1572,18 @@ public class LensAdjustment {
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 ("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.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 LED2 \"on\" current (right/near when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
gd.addNumericField("UV LED3 \"on\" current (right/far when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
gd.addNumericField("UV LED4 \"on\" current (left/far 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");
gd.addNumericField("UV LED2 \"on\" current (right/near when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
gd.addNumericField("UV LED3 \"on\" current (right/far when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
gd.addNumericField("UV LED4 \"on\" current (left/far when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
gd.addMessage("");
gd.addNumericField("Minimal correction movement to initiate final series of corrections - focus/tilt mode", this.minCorr, 1,5,"motors steps");
......@@ -1414,6 +1601,17 @@ public class LensAdjustment {
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.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.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);
......@@ -1435,13 +1633,23 @@ public class LensAdjustment {
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("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.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_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_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_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);
......@@ -1457,6 +1665,7 @@ public class LensAdjustment {
if (!Double.isNaN(this.result_FocalLength)) gd.addMessage("Lens focal length "+this.result_FocalLength+" mm");
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)");
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
......@@ -1482,6 +1691,9 @@ public class LensAdjustment {
this.initialCalibrationFile= gd.getNextString();
this.strategyFile= gd.getNextString();
this.resultsSuperDirectory= gd.getNextString();
this.focusingHistoryFile= gd.getNextString();
this.useLMAMetrics = gd.getNextBoolean();
this.EEPROM_channel= (int) gd.getNextNumber();
this.saveResults= gd.getNextBoolean();
this.showResults= gd.getNextBoolean();
......@@ -1549,6 +1761,12 @@ public class LensAdjustment {
this.lensDistanceInteractive= gd.getNextBoolean();
this.lensDistanceShowResults= 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.uvLasersBus= (int) gd.getNextNumber();
......@@ -1571,6 +1789,16 @@ public class LensAdjustment {
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.scanTiltRangeX= (int) gd.getNextNumber();
this.scanTiltRangeY= (int) gd.getNextNumber();
this.scanTiltStepsX= (int) gd.getNextNumber();
this.scanTiltStepsY= (int) gd.getNextNumber();
this.smallestSubPix= gd.getNextNumber();
this.bitmapNonuniforityThreshold=gd.getNextNumber();
this.subdiv= (int) gd.getNextNumber();
......@@ -1591,6 +1819,7 @@ public class LensAdjustment {
this.flatFieldExpand= gd.getNextNumber();
this.thresholdFinish= gd.getNextNumber();
this.numIterations= (int) gd.getNextNumber();
this.reportTemperature= gd.getNextNumber();
return true;
}
/* ======================================================================== */
......
......@@ -5332,6 +5332,7 @@ java.lang.ArrayIndexOutOfBoundsException: -3566
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, 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) {
double x=(i % size) - hsize;
......@@ -5344,13 +5345,62 @@ java.lang.ArrayIndexOutOfBoundsException: -3566
ST+=d*tc;
SR2+=d*rc*rc;
ST2+=d*tc*tc;
// SRT+=d*rc*tc;
// nn++;
}
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};
// 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;
}
//====================================================
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(
......@@ -5382,7 +5432,8 @@ java.lang.ArrayIndexOutOfBoundsException: -3566
}
if (maxValue<=0.0){
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);
}
ix=Index % size;
......@@ -8506,6 +8557,7 @@ d()/dy=C*x+2*B*y+E=0
IJ.showMessage("Error",msg);
throw new IllegalArgumentException (msg);
}
if (this.PATTERN_GRID.length==0) return null;
double x1=x0,y1=y0;
double x2=x1+size;
double y2=y1+size;
......
......@@ -8,9 +8,9 @@
#
# 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.
Process, "Process Pixels", Process_Pixels
#Process, "Process Pixels", Process_Pixels
Process, "Aberration Calibration", Aberration_Calibration
#Plugins, "Aberration Calibration", Aberration_Calibration
#Process, "Aberration Correction", Aberration_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