Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
imagej-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
imagej-elphel
Commits
ecdccabe
Commit
ecdccabe
authored
Aug 19, 2014
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Working on SFE adjustmnent using lens test results
parent
fd3a84bd
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
2066 additions
and
962 deletions
+2066
-962
Aberration_Calibration.java
src/main/java/Aberration_Calibration.java
+66
-8
FocusingField.java
src/main/java/FocusingField.java
+2000
-954
No files found.
src/main/java/Aberration_Calibration.java
View file @
ecdccabe
...
...
@@ -45,6 +45,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
//import FocusingField.MeasuredSample;
import
Jama.Matrix
;
// Download here: http://math.nist.gov/javanumerics/jama/
...
...
@@ -787,14 +788,18 @@ if (MORE_BUTTONS) {
panelCurvature
.
setLayout
(
new
GridLayout
(
1
,
0
,
5
,
5
));
addButton
(
"Scan Calib LMA"
,
panelCurvature
,
color_process
);
addButton
(
"Save History"
,
panelCurvature
,
color_debug
);
addButton
(
"Restore History"
,
panelCurvature
,
color_debug
);
addButton
(
"Modify LMA"
,
panelCurvature
,
color_debug
);
addButton
(
"Restore History"
,
panelCurvature
,
color_restore
);
addButton
(
"Modify LMA"
,
panelCurvature
,
color_configure
);
addButton
(
"Load strategies"
,
panelCurvature
,
color_restore
);
addButton
(
"Organize strategies"
,
panelCurvature
,
color_configure
);
addButton
(
"Save strategies"
,
panelCurvature
,
color_bundle
);
addButton
(
"LMA History"
,
panelCurvature
,
color_process
);
addButton
(
"List curv pars"
,
panelCurvature
,
color_debug
);
addButton
(
"List curv data"
,
panelCurvature
,
color_debug
);
addButton
(
"List qualB"
,
panelCurvature
,
color_report
);
addButton
(
"List curv"
,
panelCurvature
,
color_report
);
addButton
(
"Show curv corr"
,
panelCurvature
,
color_report
);
addButton
(
"Test measurement"
,
panelCurvature
,
color_process
);
add
(
panelCurvature
);
//panelGoniometer
...
...
@@ -4386,10 +4391,21 @@ if (MORE_BUTTONS) {
if
(
PROPERTIES
!=
null
)
FOCUSING_FIELD
.
getProperties
(
"FOCUSING_FIELD."
,
PROPERTIES
);
System
.
out
.
println
(
"Loaded FocusingField"
);
if
(!
FOCUSING_FIELD
.
configureDataVector
(
"Configure curvature"
,
true
,
true
))
return
;
FOCUSING_FIELD
.
setDataVector
(
FOCUSING_FIELD
.
createDataVector
());
double
[]
focusing_fx
=
FOCUSING_FIELD
.
createFXandJacobian
(
true
);
double
rms
=
FOCUSING_FIELD
.
getRMS
(
focusing_fx
,
false
);
System
.
out
.
println
(
"rms="
+
rms
);
/// FOCUSING_FIELD.fieldFitting.initSampleCorrChnParIndex(FOCUSING_FIELD.flattenSampleCoord()); //+
/// FOCUSING_FIELD.setDataVector(
/// true, // calibrate mode
/// FOCUSING_FIELD.createDataVector());
// FOCUSING_FIELD.fieldFitting.initSampleCorrVector( //+
// FOCUSING_FIELD.flattenSampleCoord(), //double [][] sampleCoordinates,
// FOCUSING_FIELD.getSeriesWeights()); //double [][] sampleSeriesWeights);
double
[]
sv
=
FOCUSING_FIELD
.
fieldFitting
.
createParameterVector
(
FOCUSING_FIELD
.
sagittalMaster
);
FOCUSING_FIELD
.
setDataVector
(
true
,
// calibrate mode
FOCUSING_FIELD
.
createDataVector
());
double
[]
focusing_fx
=
FOCUSING_FIELD
.
createFXandJacobian
(
sv
,
false
);
double
rms
=
FOCUSING_FIELD
.
calcErrorDiffY
(
focusing_fx
,
false
);
double
rms_pure
=
FOCUSING_FIELD
.
calcErrorDiffY
(
focusing_fx
,
true
);
System
.
out
.
println
(
"rms="
+
rms
+
", rms_pure="
+
rms_pure
);
return
;
}
/* ======================================================================== */
...
...
@@ -4398,15 +4414,49 @@ if (MORE_BUTTONS) {
if
(
FOCUSING_FIELD
==
null
)
return
;
FOCUSING_FIELD
.
setDebugLevel
(
DEBUG_LEVEL
);
if
(!
FOCUSING_FIELD
.
configureDataVector
(
"Re-configure curvature parameters"
,
false
,
true
))
return
;
FOCUSING_FIELD
.
setDataVector
(
FOCUSING_FIELD
.
createDataVector
());
FOCUSING_FIELD
.
setDataVector
(
true
,
// calibrate mode
FOCUSING_FIELD
.
createDataVector
());
return
;
}
/* ======================================================================== */
if
(
label
.
equals
(
"Load strategies"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
if
(
FOCUSING_FIELD
==
null
)
return
;
FOCUSING_FIELD
.
setDebugLevel
(
DEBUG_LEVEL
);
FOCUSING_FIELD
.
fieldFitting
.
fieldStrategies
.
loadStrategies
(
null
,
PROCESS_PARAMETERS
.
kernelsDirectory
);
return
;
}
/* ======================================================================== */
if
(
label
.
equals
(
"Save strategies"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
if
(
FOCUSING_FIELD
==
null
)
return
;
FOCUSING_FIELD
.
setDebugLevel
(
DEBUG_LEVEL
);
FOCUSING_FIELD
.
fieldFitting
.
fieldStrategies
.
saveStrategies
(
null
,
PROCESS_PARAMETERS
.
kernelsDirectory
);
return
;
}
/* ======================================================================== */
if
(
label
.
equals
(
"Organize strategies"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
if
(
FOCUSING_FIELD
==
null
)
return
;
FOCUSING_FIELD
.
setDebugLevel
(
DEBUG_LEVEL
);
int
resp
=
0
;
while
(
resp
==
0
){
resp
=
FOCUSING_FIELD
.
organizeStrategies
(
"Organize LMA strategies"
);
}
return
;
}
///organizeStrategies(String title)
/* ======================================================================== */
if
(
label
.
equals
(
"LMA History"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
if
(
FOCUSING_FIELD
==
null
)
return
;
FOCUSING_FIELD
.
setDebugLevel
(
DEBUG_LEVEL
);
FOCUSING_FIELD
.
LevenbergMarquardt
(
true
,
DEBUG_LEVEL
);
//boolean openDialog, int debugLevel){
FOCUSING_FIELD
.
LevenbergMarquardt
(
null
,
// measurement
true
,
// open dialog
false
,
// filterZ
DEBUG_LEVEL
);
//boolean openDialog, int debugLevel){
return
;
}
/* ======================================================================== */
...
...
@@ -4450,6 +4500,14 @@ if (MORE_BUTTONS) {
FOCUSING_FIELD
.
showCurvCorr
();
// to screen
return
;
}
/* ======================================================================== */
if
(
label
.
equals
(
"Test measurement"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
if
(
FOCUSING_FIELD
==
null
)
return
;
FOCUSING_FIELD
.
setDebugLevel
(
DEBUG_LEVEL
);
FOCUSING_FIELD
.
testMeasurement
();
return
;
}
//
/* ======================================================================== */
if
(
label
.
equals
(
"Show PSF"
))
{
...
...
src/main/java/FocusingField.java
View file @
ecdccabe
...
...
@@ -30,8 +30,13 @@ import ij.text.TextWindow;
import
java.awt.Point
;
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
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashMap
;
...
...
@@ -42,6 +47,12 @@ import org.apache.commons.configuration.ConfigurationException;
import
org.apache.commons.configuration.XMLConfiguration
;
//import Distortions.LMAArrays; // may still reuse?
import
Jama.LUDecomposition
;
import
Jama.Matrix
;
...
...
@@ -68,6 +79,9 @@ public class FocusingField {
boolean
filterInputConcaveRemoveFew
;
int
filterInputConcaveMinSeries
;
double
filterInputConcaveScale
;
boolean
filterZ
;
// (adjustment mode)filter samples by Z
int
minLeftSamples
;
// minimal number of samples (channel/dir/location) for adjustment
// when false - tangential is master
double
[]
minMeas
;
// pixels
double
[]
maxMeas
;
// pixels
...
...
@@ -107,12 +121,17 @@ public class FocusingField {
private
int
numIterations
;
// maximal number of iterations
private
double
maxLambda
;
// max lambda to fail
private
double
lambda
;
// copied from series
private
String
strategyComment
;
private
boolean
lastInSeries
;
private
int
currentStrategyStep
;
// -1 do not read from strategies
private
boolean
stopEachStep
;
// open dialog after each fitting step
private
boolean
stopEachSeries
;
// stop after each series
private
boolean
stopOnFailure
;
// open dialog when fitting series failed
private
boolean
showParams
;
// show modified parameters
private
boolean
showDisabledParams
;
private
boolean
showCorrectionParams
;
private
boolean
keepCorrectionParameters
;
private
boolean
resetCenter
;
// use distortion center
private
boolean
saveSeries
;
// just for the dialog
private
boolean
showMotors
;
private
boolean
[]
showMeasCalc
;
...
...
@@ -151,6 +170,9 @@ public class FocusingField {
public
ArrayList
<
FocusingFieldMeasurement
>
measurements
;
double
[]
weightReference
=
null
;
// calculated per-channel (6) array of maximal PSF FWHM after applying min/max correction
MeasuredSample
[]
dataVector
;
double
[][][]
zRanges
;
// min/max "reliable" z for each channel/sample - will be used during adjustment
boolean
[]
prevEnable
;
// used in adjustment mode to save previous result of filterByZRanges()
// boolean changedEnable; // used in adjustment mode to signal if new result of filterByZRanges() differes from the previous one
double
[]
dataValues
;
double
[]
dataWeights
;
// int [][][] dataIndex=null; // [measurement][channel][sample] - index in dataValues (and dataWeights) or -1
...
...
@@ -162,7 +184,8 @@ public class FocusingField {
private
LMAArrays
lMAArrays
=
null
;
private
LMAArrays
savedLMAArrays
=
null
;
private
double
[]
currentfX
=
null
;
// array of "f(x)" - simulated data for all images, combining pixel-X and pixel-Y (odd/even)
// temporarily changing visibility of currentfX
double
[]
currentfX
=
null
;
// array of "f(x)" - simulated data for all images, combining pixel-X and pixel-Y (odd/even)
private
double
[]
nextfX
=
null
;
// array of "f(x)" - simulated data for all images, combining pixel-X and pixel-Y (odd/even)
private
double
currentRMS
=-
1.0
;
// calculated RMS for the currentVector->currentfX
private
double
currentRMSPure
=-
1.0
;
// calculated RMS for the currentVector->currentfX
...
...
@@ -174,6 +197,9 @@ public class FocusingField {
public
void
setDefaults
(){
zRanges
=
null
;
prevEnable
=
null
;
// changedEnable=true;
z0_estimates
=
null
;
sagittalMaster
=
false
;
// center data is the same, when true sagittal fitting only may change r=0 coefficients,
parallelOnly
=
true
;
// only process measurements for parallel moves
...
...
@@ -188,6 +214,9 @@ public class FocusingField {
filterInputConcaveRemoveFew
=
true
;
filterInputConcaveMinSeries
=
5
;
filterInputConcaveScale
=
0.9
;
filterZ
=
true
;
// (adjustment mode)filter samples by Z
minLeftSamples
=
10
;
// minimal number of samples (channel/dir/location) for adjustment
// when false - tangential is master
double
[]
minMeasDflt
=
{
0.5
,
0.5
,
0.5
,
0.5
,
0.5
,
0.5
};
// pixels
minMeas
=
minMeasDflt
;
// pixels
...
...
@@ -229,14 +258,20 @@ public class FocusingField {
thresholdFinish
=
0.001
;
// (copied from series) stop iterations if 2 last steps had less improvement (but not worsening )
numIterations
=
100
;
// maximal number of iterations
maxLambda
=
100.0
;
// max lambda to fail
lambda
=
0.001
;
// copied from series
stopEachStep
=
true
;
// open dialog after each fitting step
stopEachSeries
=
false
;
stopOnFailure
=
true
;
// open dialog when fitting series failed
strategyComment
=
""
;
lastInSeries
=
true
;
currentStrategyStep
=-
1
;
// -1 do not read from strategies
showParams
=
false
;
// show modified parameters
showDisabledParams
=
false
;
showCorrectionParams
=
false
;
keepCorrectionParameters
=
true
;
resetCenter
=
false
;
saveSeries
=
false
;
// just for the dialog
showMotors
=
true
;
...
...
@@ -283,21 +318,19 @@ public class FocusingField {
properties
.
setProperty
(
prefix
+
"filterInputFirstLast"
,
filterInputFirstLast
+
""
);
properties
.
setProperty
(
prefix
+
"filterInputTooFar"
,
filterInputTooFar
+
""
);
properties
.
setProperty
(
prefix
+
"filterInputFarRatio"
,
filterInputFarRatio
+
""
);
properties
.
setProperty
(
prefix
+
"filterInputConcave"
,
filterInputConcave
+
""
);
properties
.
setProperty
(
prefix
+
"filterInputConcaveSigma"
,
filterInputConcaveSigma
+
""
);
properties
.
setProperty
(
prefix
+
"filterInputConcaveRemoveFew"
,
filterInputConcaveRemoveFew
+
""
);
properties
.
setProperty
(
prefix
+
"filterInputConcaveMinSeries"
,
filterInputConcaveMinSeries
+
""
);
properties
.
setProperty
(
prefix
+
"filterInputConcaveScale"
,
filterInputConcaveScale
+
""
);
properties
.
setProperty
(
prefix
+
"filterZ"
,
filterZ
+
""
);
properties
.
setProperty
(
prefix
+
"minLeftSamples"
,
minLeftSamples
+
""
);
for
(
int
chn
=
0
;
chn
<
minMeas
.
length
;
chn
++)
properties
.
setProperty
(
prefix
+
"minMeas_"
+
chn
,
minMeas
[
chn
]+
""
);
for
(
int
chn
=
0
;
chn
<
maxMeas
.
length
;
chn
++)
properties
.
setProperty
(
prefix
+
"maxMeas_"
+
chn
,
maxMeas
[
chn
]+
""
);
for
(
int
chn
=
0
;
chn
<
thresholdMax
.
length
;
chn
++)
properties
.
setProperty
(
prefix
+
"thresholdMax_"
+
chn
,
thresholdMax
[
chn
]+
""
);
properties
.
setProperty
(
prefix
+
"useMinMeas"
,
useMinMeas
+
""
);
properties
.
setProperty
(
prefix
+
"useMaxMeas"
,
useMaxMeas
+
""
);
properties
.
setProperty
(
prefix
+
"useThresholdMax"
,
useThresholdMax
+
""
);
properties
.
setProperty
(
prefix
+
"weightMode"
,
weightMode
+
""
);
properties
.
setProperty
(
prefix
+
"weightRadius"
,
weightRadius
+
""
);
properties
.
setProperty
(
prefix
+
"k_red"
,
k_red
+
""
);
...
...
@@ -321,6 +354,17 @@ public class FocusingField {
properties
.
setProperty
(
prefix
+
"rslt_mtf50_mode"
,
rslt_mtf50_mode
+
""
);
properties
.
setProperty
(
prefix
+
"rslt_solve"
,
rslt_solve
+
""
);
for
(
int
chn
=
0
;
chn
<
rslt_show_chn
.
length
;
chn
++)
properties
.
setProperty
(
prefix
+
"rslt_show_chn_"
+
chn
,
rslt_show_chn
[
chn
]+
""
);
// always re-calculate here?
zRanges
=
calcZRanges
(
dataWeightsToBoolean
());
if
(
zRanges
!=
null
){
properties
.
setProperty
(
prefix
+
"zRanges_length"
,
zRanges
.
length
+
""
);
for
(
int
chn
=
0
;
chn
<
zRanges
.
length
;
chn
++)
if
(
zRanges
[
chn
]!=
null
)
{
properties
.
setProperty
(
prefix
+
"zRanges_"
+
chn
+
"_length"
,
zRanges
[
chn
].
length
+
""
);
for
(
int
sample
=
0
;
sample
<
zRanges
[
chn
].
length
;
sample
++)
if
(
zRanges
[
chn
][
sample
]!=
null
)
{
properties
.
setProperty
(
prefix
+
"zRanges_"
+
chn
+
"_"
+
sample
,
zRanges
[
chn
][
sample
][
0
]+
","
+
zRanges
[
chn
][
sample
][
1
]);
}
}
}
}
public
void
getProperties
(
String
prefix
,
Properties
properties
){
...
...
@@ -363,7 +407,6 @@ public class FocusingField {
if
(
properties
.
getProperty
(
prefix
+
"filterInputConcaveSigma"
)!=
null
)
filterInputConcaveSigma
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"filterInputConcaveSigma"
));
if
(
properties
.
getProperty
(
prefix
+
"filterInputConcaveRemoveFew"
)!=
null
)
filterInputConcaveRemoveFew
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"filterInputConcaveRemoveFew"
));
if
(
properties
.
getProperty
(
prefix
+
"filterInputConcaveMinSeries"
)!=
null
)
...
...
@@ -371,6 +414,11 @@ public class FocusingField {
if
(
properties
.
getProperty
(
prefix
+
"filterInputConcaveScale"
)!=
null
)
filterInputConcaveScale
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"filterInputConcaveScale"
));
if
(
properties
.
getProperty
(
prefix
+
"filterZ"
)!=
null
)
filterZ
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"filterZ"
));
if
(
properties
.
getProperty
(
prefix
+
"minLeftSamples"
)!=
null
)
minLeftSamples
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"minLeftSamples"
));
for
(
int
chn
=
0
;
chn
<
minMeas
.
length
;
chn
++)
if
(
properties
.
getProperty
(
prefix
+
"minMeas_"
+
chn
)!=
null
)
minMeas
[
chn
]=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"minMeas_"
+
chn
));
for
(
int
chn
=
0
;
chn
<
maxMeas
.
length
;
chn
++)
if
(
properties
.
getProperty
(
prefix
+
"maxMeas_"
+
chn
)!=
null
)
...
...
@@ -429,6 +477,26 @@ public class FocusingField {
rslt_solve
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"rslt_solve"
));
for
(
int
chn
=
0
;
chn
<
rslt_show_chn
.
length
;
chn
++)
if
(
properties
.
getProperty
(
prefix
+
"rslt_show_chn_"
+
chn
)!=
null
)
rslt_show_chn
[
chn
]=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"rslt_show_chn_"
+
chn
));
zRanges
=
null
;
if
(
properties
.
getProperty
(
prefix
+
"zRanges_length"
)!=
null
){
zRanges
=
new
double
[
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"zRanges_length"
))][][];
for
(
int
chn
=
0
;
chn
<
zRanges
.
length
;
chn
++)
{
zRanges
[
chn
]=
null
;
if
(
properties
.
getProperty
(
prefix
+
"zRanges_"
+
chn
+
"_length"
)!=
null
){
zRanges
[
chn
]=
new
double
[
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"zRanges_"
+
chn
+
"_length"
))][];
for
(
int
sample
=
0
;
sample
<
zRanges
[
chn
].
length
;
sample
++)
{
zRanges
[
chn
][
sample
]=
null
;
String
s
=
properties
.
getProperty
(
prefix
+
"zRanges_"
+
chn
+
"_"
+
sample
);
if
(
s
!=
null
){
zRanges
[
chn
][
sample
]=
new
double
[
2
];
String
[]
ss
=
s
.
split
(
","
);
zRanges
[
chn
][
sample
][
0
]=
Double
.
parseDouble
(
ss
[
0
]);
zRanges
[
chn
][
sample
][
1
]=
Double
.
parseDouble
(
ss
[
1
]);
}
}
}
}
}
}
public
void
setDebugLevel
(
int
debugLevel
){
this
.
debugLevel
=
debugLevel
;
...
...
@@ -666,6 +734,67 @@ public double [][] getSeriesWeights(){
return
seriesWeights
;
}
private
double
[][][]
calcZRanges
(
boolean
[]
enable
){
double
[][][]
zRanges
=
new
double
[
getNumChannels
()][
getNumSamples
()][];
for
(
int
chn
=
0
;
chn
<
zRanges
.
length
;
chn
++)
for
(
int
sample
=
0
;
sample
<
zRanges
[
chn
].
length
;
sample
++)
zRanges
[
chn
][
sample
]=
null
;
double
[][]
sCoord
=
flattenSampleCoord
();
for
(
int
index
=
0
;
index
<
dataVector
.
length
;
index
++)
if
((
index
>=
enable
.
length
)
||
enable
[
index
]){
int
chn
=
dataVector
[
index
].
channel
;
int
sample
=
dataVector
[
index
].
sampleIndex
;
double
z
=
fieldFitting
.
getMotorsZ
(
dataVector
[
index
].
motors
,
// 3 motor coordinates
sCoord
[
sample
][
0
],
// pixel x
sCoord
[
sample
][
1
]);
// pixel y
if
(
zRanges
[
chn
][
sample
]==
null
){
zRanges
[
chn
][
sample
]=
new
double
[
2
];
zRanges
[
chn
][
sample
][
0
]=
z
;
zRanges
[
chn
][
sample
][
1
]=
z
;
}
else
{
if
(
z
<
zRanges
[
chn
][
sample
][
0
])
zRanges
[
chn
][
sample
][
0
]=
z
;
if
(
z
>
zRanges
[
chn
][
sample
][
1
])
zRanges
[
chn
][
sample
][
1
]=
z
;
}
}
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"calcZRanges()"
);
return
zRanges
;
}
private
boolean
[]
filterByZRanges
(
double
[][][]
zRanges
,
boolean
[]
enable_in
){
boolean
[]
enable_out
=
enable_in
.
clone
();
double
[][]
sCoord
=
flattenSampleCoord
();
int
numFiltered
=
0
;
int
numLeft
=
0
;
if
(
zRanges
!=
null
)
{
for
(
int
index
=
0
;
index
<
dataVector
.
length
;
index
++)
if
((
index
>=
enable_in
.
length
)
||
enable_in
[
index
]){
int
chn
=
dataVector
[
index
].
channel
;
int
sample
=
dataVector
[
index
].
sampleIndex
;
double
z
=
fieldFitting
.
getMotorsZ
(
dataVector
[
index
].
motors
,
// 3 motor coordinates
sCoord
[
sample
][
0
],
// pixel x
sCoord
[
sample
][
1
]);
// pixel y
if
((
zRanges
[
chn
]!=
null
)
&&
(
zRanges
[
chn
][
sample
]!=
null
)){
if
((
z
<
zRanges
[
chn
][
sample
][
0
])
||
(
z
>
zRanges
[
chn
][
sample
][
1
]))
{
enable_out
[
index
]=
false
;
numFiltered
++;
}
else
{
numLeft
++;
}
}
}
}
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"filterByZRanges(): Filtered "
+
numFiltered
+
" samples, left "
+
numLeft
+
" samples"
);
return
enable_out
;
}
private
int
getNumEnabledSamples
(
boolean
[]
enable
){
int
num_en
=
0
;
for
(
int
index
=
0
;
index
<
dataVector
.
length
;
index
++)
if
((
index
>=
enable
.
length
)
||
enable
[
index
])
num_en
++;
return
num_en
;
}
private
boolean
[]
filterConcave
(
double
sigma
,
...
...
@@ -1029,10 +1158,12 @@ private int [] getParallelDiff(MeasuredSample [] vector){
// includes deselected channels
public
void
setDataVector
(
MeasuredSample
[]
vector
){
// remove unused channels if any. vector is already corrected from input data, FWHM psf
public
void
setDataVector
(
boolean
calibrateMode
,
MeasuredSample
[]
vector
){
// remove unused channels if any. vector is already corrected from input data, FWHM psf
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"+++++ (Re)calculating sample weights +++++"
);
int
[]
diffs
=
null
;
if
(
parallelOnly
)
diffs
=
getParallelDiff
(
vector
);
if
(
calibrateMode
&&
parallelOnly
)
diffs
=
getParallelDiff
(
vector
);
boolean
[]
chanSel
=
fieldFitting
.
getSelectedChannels
();
int
numSamples
=
0
;
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
if
(
chanSel
[
vector
[
i
].
channel
]){
...
...
@@ -1052,36 +1183,21 @@ public void setDataVector(MeasuredSample [] vector){ // remove unused channels i
int
corrLength
=
fieldFitting
.
getNumberOfCorrParameters
();
dataValues
=
new
double
[
dataVector
.
length
+
corrLength
];
dataWeights
=
new
double
[
dataVector
.
length
+
corrLength
];
// sumWeights=0.0;
// int mode=weightMode;
double
kw
=
(
weightRadius
>
0.0
)?(-
0.5
*
getPixelMM
()*
getPixelMM
()/(
weightRadius
*
weightRadius
)):
0
;
//weightRadius
// if (weightReference==null) mode=0;
for
(
int
i
=
0
;
i
<
dataVector
.
length
;
i
++){
MeasuredSample
ms
=
dataVector
[
i
];
dataValues
[
i
]=
ms
.
value
;
dataWeights
[
i
]=
1.0
/
Math
.
pow
(
ms
.
value
,
weightMode
);
/*
double diff=weightReference[ms.channel]-ms.value;
if (diff<0.0) diff=0;
switch (mode){
case 0: dataWeights[i]=1.0; break;
case 1: dataWeights[i]=diff; break;
case 2: dataWeights[i]=diff*diff; break;
default: dataWeights[i]=1.0;
}
*/
if
(
weightRadius
>
0.0
){
double
r2
=(
ms
.
px
-
currentPX0
)*(
ms
.
px
-
currentPX0
)+(
ms
.
py
-
currentPY0
)*(
ms
.
py
-
currentPY0
);
dataWeights
[
i
]*=
Math
.
exp
(
kw
*
r2
);
}
// sumWeights+=dataWeights[i];
}
for
(
int
i
=
0
;
i
<
corrLength
;
i
++){
dataValues
[
i
+
dataVector
.
length
]=
0.0
;
// correction target is always 0
dataWeights
[
i
+
dataVector
.
length
]=
1.0
;
// improve?
}
if
(
filterInput
){
if
(
calibrateMode
&&
filterInput
){
boolean
[]
en
=
dataWeightsToBoolean
();
en
=
filterCrazyInput
(
en
,
// [meas][cjn][sample] (or null) // can be shorter or longer than dataVector
...
...
@@ -1091,7 +1207,7 @@ public void setDataVector(MeasuredSample [] vector){ // remove unused channels i
);
maskDataWeights
(
en
);
}
if
(
filterInputTooFar
){
if
(
calibrateMode
&&
filterInputTooFar
){
boolean
[]
en
=
dataWeightsToBoolean
();
en
=
filterTooFar
(
filterInputFarRatio
,
...
...
@@ -1099,7 +1215,7 @@ public void setDataVector(MeasuredSample [] vector){ // remove unused channels i
maskDataWeights
(
en
);
}
if
(
filterInputConcave
){
if
(
calibrateMode
&&
filterInputConcave
){
boolean
[]
en
=
dataWeightsToBoolean
();
en
=
filterConcave
(
filterInputConcaveSigma
,
...
...
@@ -1126,16 +1242,17 @@ public void commitParameterVector(double [] vector){
if
(
centerSelect
[
0
]
||
centerSelect
[
1
]){
// do not do that if XC, YC are not modified
// recalculate data vector
double
[]
pXY
=
fieldFitting
.
getCenterXY
();
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Updated currentPX0="
+
pXY
[
0
]+
"("
+
currentPX0
+
")"
+
", currentPY0="
+
pXY
[
1
]+
"("
+
currentPY0
+
")"
);
currentPX0
=
pXY
[
0
];
currentPY0
=
pXY
[
1
];
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Updated currentPX0="
+
currentPX0
+
", currentPY0="
+
currentPY0
);
if
(
correct_measurement_ST
&&
updateWeightWhileFitting
)
{
setDataVector
(
createDataVector
(
setDataVector
(
true
,
createDataVector
(
false
,
// boolean updateSelection,
pXY
[
0
],
//double centerPX,
pXY
[
1
]));
//double centerPY
}
}
}
...
...
@@ -1310,6 +1427,22 @@ public double getRMS(double [] fx, boolean pure){
return
Math
.
sqrt
(
sum
);
}
public
MeasuredSample
[]
createDataVector
(
FocusingFieldMeasurement
measurement
){
ArrayList
<
FocusingFieldMeasurement
>
singleMeasurement
=
new
ArrayList
<
FocusingFieldMeasurement
>();
singleMeasurement
.
add
(
measurement
);
return
createDataVector
(
singleMeasurement
,
false
,
// calibrate
true
,
// update selection
currentPX0
,
// ignored
currentPY0
,
// ignored
(
this
.
useMinMeas
?
this
.
minMeas
:
null
),
// pixels
(
this
.
useMaxMeas
?
this
.
maxMeas
:
null
),
// pixels
(
this
.
useThresholdMax
?
this
.
thresholdMax
:
null
));
// pixels
}
public
MeasuredSample
[]
createDataVector
(){
return
createDataVector
(
true
,
// boolean updateSelection,
...
...
@@ -1322,6 +1455,8 @@ public MeasuredSample [] createDataVector(
double
centerPY
){
// use this data
return
createDataVector
(
measurements
,
true
,
// calibrate
updateSelection
,
centerPX
,
centerPY
,
...
...
@@ -1379,6 +1514,8 @@ d_cs/dy0= delta_x*(2*delta_y^2-r2)/r2^2
*/
public
MeasuredSample
[]
createDataVector
(
ArrayList
<
FocusingFieldMeasurement
>
measurements
,
boolean
calibrate
,
// false - adjust, should have updateSelection==true and a single-element measurements list
boolean
updateSelection
,
double
centerPX
,
double
centerPY
,
...
...
@@ -1386,8 +1523,10 @@ public MeasuredSample [] createDataVector(
double
[]
maxMeas
,
// pixels
double
[]
thresholdMax
){
// pixels
debugDerivatives
=
debugLevel
==
3
;
if
(
calibrate
)
{
currentPX0
=
centerPX
;
currentPY0
=
centerPY
;
}
final
int
numColors
=
3
;
final
int
numDirs
=
2
;
if
(
sampleMask
==
null
)
updateSelection
=
true
;
...
...
@@ -1401,7 +1540,7 @@ public MeasuredSample [] createDataVector(
for
(
int
d
=
0
;
d
<
numDirs
;
d
++)
sampleMask
[
n
][
i
][
j
][
c
][
d
]=
false
;
}
/*
/*
d_c2/d_x0= 2*delta_x*(delta_x^2 - r2)/r2^2
d_c2/d_y0= 2*delta_y*delta_x^2/r2^2
...
...
@@ -1410,7 +1549,7 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2
2*d_cs/dx0= 2*delta_y*(2*delta_x^2-r2)/r2^2
2*d_cs/dy0= 2*delta_x*(2*delta_y^2-r2)/r2^2
*/
*/
double
[][][]
cosSin2Tab
=
new
double
[
sampleCoord
.
length
][
sampleCoord
[
0
].
length
][
3
];
double
[][][]
debugCosSin2Tab_dx
=
null
;
double
[][][]
debugCosSin2Tab_dy
=
null
;
...
...
@@ -1636,8 +1775,8 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2
}
double
f
=
value
;
value
=
1.0
/
Math
.
sqrt
(
1.0
/(
value
*
value
)-
1.0
/(
maxMeas
[
chn
]*
maxMeas
[
chn
]));
// value_dx0*=1.0/(value*f*f*f);
// value_dy0*=1.0/(value*f*f*f);
// value_dx0*=1.0/(value*f*f*f);
// value_dy0*=1.0/(value*f*f*f);
f
=
value
/
f
;
f
*=
f
*
f
;
value_dx0
*=
f
;
...
...
@@ -1891,7 +2030,7 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2
this
.
lMAArrays
=
calculateJacobianArrays
(
this
.
currentfX
);
this
.
currentRMS
=
calcErrorDiffY
(
this
.
currentfX
,
false
);
this
.
currentRMSPure
=
calcErrorDiffY
(
this
.
currentfX
,
true
);
msg
=
": initial RMS="
+
IJ
.
d2s
(
this
.
currentRMS
,
8
)+
" (pure RMS="
+
IJ
.
d2s
(
this
.
currentRMSPure
,
8
)+
")"
+
msg
=
this
.
currentStrategyStep
+
": initial RMS="
+
IJ
.
d2s
(
this
.
currentRMS
,
8
)+
" (pure RMS="
+
IJ
.
d2s
(
this
.
currentRMSPure
,
8
)+
")"
+
". Calculating next Jacobian. Points:"
+
this
.
dataValues
.
length
+
" Parameters:"
+
this
.
currentVector
.
length
;
if
(
debugLevel
>
1
)
System
.
out
.
println
(
msg
);
if
(
this
.
updateStatus
)
IJ
.
showStatus
(
msg
);
...
...
@@ -2023,13 +2162,24 @@ public boolean selectLMAParameters(){
// int numSeries=fittingStrategy.getNumSeries();
// boolean resetCorrections=false;
GenericDialog
gd
=
new
GenericDialog
(
"Levenberg-Marquardt algorithm parameters for cameras distortions/locations"
);
//TODO: change to selection using series comments
// gd.addNumericField("Fitting series number", this.currentStrategyStep, 0, 3," (-1 - current)");
FieldStrategies
fs
=
fieldFitting
.
fieldStrategies
;
String
[]
indices
=
new
String
[
fs
.
getNumStrategies
()+
1
];
indices
[
0
]=
"current strategy"
;
for
(
int
i
=
0
;
i
<
fs
.
getNumStrategies
();
i
++)
{
indices
[
i
+
1
]=
i
+
": "
+
fs
.
getComment
(
i
)+
" ("
+(
fs
.
isStopAfterThis
(
i
)?
"STOP"
:
"CONTINUE"
)+
")"
;
}
if
(
this
.
currentStrategyStep
>=(
indices
.
length
-
1
))
this
.
currentStrategyStep
=
indices
.
length
-
2
;
gd
.
addChoice
(
"Fitting series"
,
indices
,
indices
[
this
.
currentStrategyStep
+
1
]);
gd
.
addCheckbox
(
"Debug df/dX0, df/dY0"
,
false
);
gd
.
addNumericField
(
"Debug Jacobian for point number"
,
this
.
debugPoint
,
0
,
5
,
"(-1 - none)"
);
gd
.
addNumericField
(
"Debug Jacobian for parameter number"
,
this
.
debugParameter
,
0
,
5
,
"(-1 - none)"
);
gd
.
addCheckbox
(
"Keep current correction parameters (do not reset)"
,
this
.
keepCorrectionParameters
);
// gd.addNumericField("Iteration number to start (0.."+(numSeries-1)+")", this.seriesNumber, 0);
gd
.
addNumericField
(
"Initial LMA Lambda "
,
this
.
lambda
,
5
);
// gd.addCheckbox("Keep current correction parameters (do not reset)", this.keepCorrectionParameters);
gd
.
addNumericField
(
"Initial LMA Lambda "
,
0.0
,
5
,
8
,
"0 - keep, last was "
+
this
.
lambda
);
gd
.
addNumericField
(
"Multiply lambda on success"
,
this
.
lambdaStepDown
,
5
);
gd
.
addNumericField
(
"Threshold RMS to exit LMA"
,
this
.
thresholdFinish
,
7
,
9
,
"pix"
);
gd
.
addNumericField
(
"Multiply lambda on failure"
,
this
.
lambdaStepUp
,
5
);
...
...
@@ -2037,48 +2187,44 @@ public boolean selectLMAParameters(){
gd
.
addNumericField
(
"Maximal number of iterations"
,
this
.
numIterations
,
0
);
gd
.
addCheckbox
(
"Dialog after each iteration step"
,
this
.
stopEachStep
);
//
gd.addCheckbox("Dialog after each iteration series", this.stopEachSeries);
gd
.
addCheckbox
(
"Dialog after each iteration series"
,
this
.
stopEachSeries
);
gd
.
addCheckbox
(
"Dialog after each failure"
,
this
.
stopOnFailure
);
// gd.addCheckbox("Ask for weight function filter", this.askFilter);
gd
.
addCheckbox
(
"Show modified parameters"
,
this
.
showParams
);
gd
.
addCheckbox
(
"Show disabled parameters"
,
this
.
showDisabledParams
);
gd
.
addCheckbox
(
"Show per-sample correction parameters"
,
this
.
showCorrectionParams
);
// gd.addCheckbox("Reset all per-sample corrections to zero", resetCorrections);
// gd.addCheckbox("Reset all per-sample corrections to zero", resetCorrections);
// gd.addCheckbox("Show debug images before correction",this.showThisImages);
// gd.addCheckbox("Show debug images after correction", this.showNextImages);
// gd.addNumericField("Maximal number of threads", this.threadsMax, 0);
// gd.addCheckbox("Use memory-saving/multithreaded version", this.threadedLMA);
// gd.addCheckbox("Show debug images before correction",this.showThisImages);
// gd.addCheckbox("Show debug images after correction", this.showNextImages);
// gd.addNumericField("Maximal number of threads", this.threadsMax, 0);
// gd.addCheckbox("Use memory-saving/multithreaded version", this.threadedLMA);
gd
.
showDialog
();
if
(
gd
.
wasCanceled
())
return
false
;
this
.
currentStrategyStep
=
gd
.
getNextChoiceIndex
()-
1
;
//(int) gd.getNextNumber();
if
(
this
.
currentStrategyStep
>=
0
){
getStrategy
(
this
.
currentStrategyStep
);
}
this
.
debugDerivativesFxDxDy
=
gd
.
getNextBoolean
();
debugPoint
=
(
int
)
gd
.
getNextNumber
();
debugParameter
=
(
int
)
gd
.
getNextNumber
();
this
.
keepCorrectionParameters
=
gd
.
getNextBoolean
();
// this.seriesNumber= (int)
gd.getNextNumber();
this
.
lambda
=
gd
.
getNextNumber
()
;
//
this.keepCorrectionParameters = gd.getNextBoolean();
double
preLambda
=
gd
.
getNextNumber
();
if
(
preLambda
>
0.0
)
this
.
lambda
=
preLambda
;
this
.
lambdaStepDown
=
gd
.
getNextNumber
();
this
.
thresholdFinish
=
gd
.
getNextNumber
();
this
.
lambdaStepUp
=
gd
.
getNextNumber
();
this
.
maxLambda
=
gd
.
getNextNumber
();
this
.
numIterations
=
(
int
)
gd
.
getNextNumber
();
this
.
stopEachStep
=
gd
.
getNextBoolean
();
//
this.stopEachSeries= gd.getNextBoolean();
this
.
stopEachSeries
=
gd
.
getNextBoolean
();
this
.
stopOnFailure
=
gd
.
getNextBoolean
();
// this.askFilter= gd.getNextBoolean();
this
.
showParams
=
gd
.
getNextBoolean
();
this
.
showDisabledParams
=
gd
.
getNextBoolean
();
this
.
showCorrectionParams
=
gd
.
getNextBoolean
();
// this.showThisImages= gd.getNextBoolean();
// this.showNextImages= gd.getNextBoolean();
// this.threadsMax= (int) gd.getNextNumber();
// this.threadedLMA= gd.getNextBoolean();
// resetCorrections= gd.getNextBoolean();
if
(!
keepCorrectionParameters
)
fieldFitting
.
resetSampleCorr
();
// if (!keepCorrectionParameters) fieldFitting.resetSampleCorr();
return
true
;
}
...
...
@@ -2778,7 +2924,7 @@ public void listScanQB(){
k_red
,
k_blue
,
false
);
double
[]
best_qb_corr
=
fieldFitting
.
getBestQualB
(
double
[]
best_qb_corr
=
fieldFitting
.
getBestQualB
(
//best_qb_corr[0] - distance (motorZ)
k_red
,
k_blue
,
true
);
...
...
@@ -2908,6 +3054,7 @@ public boolean dialogLMAStep(boolean [] state){
GenericDialog
gd
=
new
GenericDialog
(
"Levenberg-Marquardt algorithm step"
);
// String [][] parameterDescriptions=fittingStrategy.distortionCalibrationData.parameterDescriptions;
gd
.
addMessage
(
"Current state="
+
states
[
iState
]);
gd
.
addMessage
(
"Current series="
+
this
.
currentStrategyStep
);
gd
.
addMessage
(
"Iteration step="
+
this
.
iterationStepNumber
);
gd
.
addMessage
(
"Initial RMS="
+
IJ
.
d2s
(
this
.
firstRMS
,
6
)+
", Current RMS="
+
IJ
.
d2s
(
this
.
currentRMS
,
6
)+
", new RMS="
+
IJ
.
d2s
(
this
.
nextRMS
,
6
));
...
...
@@ -2930,7 +3077,7 @@ public boolean dialogLMAStep(boolean [] state){
gd
.
addNumericField
(
"Maximal number of iterations"
,
this
.
numIterations
,
0
);
gd
.
addCheckbox
(
"Dialog after each iteration step"
,
this
.
stopEachStep
);
//
gd.addCheckbox("Dialog after each iteration series", this.stopEachSeries);
gd
.
addCheckbox
(
"Dialog after each iteration series"
,
this
.
stopEachSeries
);
gd
.
addCheckbox
(
"Dialog after each failure"
,
this
.
stopOnFailure
);
gd
.
addCheckbox
(
"Show modified parameters"
,
this
.
showParams
);
gd
.
addCheckbox
(
"Show disabled parameters"
,
this
.
showDisabledParams
);
...
...
@@ -2954,7 +3101,7 @@ public boolean dialogLMAStep(boolean [] state){
this
.
maxLambda
=
gd
.
getNextNumber
();
this
.
numIterations
=
(
int
)
gd
.
getNextNumber
();
this
.
stopEachStep
=
gd
.
getNextBoolean
();
//
this.stopEachSeries= gd.getNextBoolean();
this
.
stopEachSeries
=
gd
.
getNextBoolean
();
this
.
stopOnFailure
=
gd
.
getNextBoolean
();
this
.
showParams
=
gd
.
getNextBoolean
();
this
.
showDisabledParams
=
gd
.
getNextBoolean
();
...
...
@@ -2965,28 +3112,147 @@ public boolean dialogLMAStep(boolean [] state){
this
.
saveSeries
=
true
;
return
gd
.
wasOKed
();
}
public
double
getAdjustRMS
(
FocusingFieldMeasurement
measurement
,
boolean
filterZ
,
double
z
,
double
tx
,
double
ty
){
fieldFitting
.
selectZTilt
();
fieldFitting
.
mechanicalFocusingModel
.
setZTxTy
(
z
,
tx
,
ty
);
double
[]
sv
=
fieldFitting
.
createParameterVector
(
sagittalMaster
);
setDataVector
(
false
,
// calibrate mode
createDataVector
(
measurement
));
if
(
filterZ
)
{
boolean
[]
en
=
dataWeightsToBoolean
();
en
=
filterByZRanges
(
zRanges
,
en
);
maskDataWeights
(
en
);
prevEnable
=
en
;
int
numEn
=
getNumEnabledSamples
(
en
);
if
(
numEn
<
minLeftSamples
)
return
Double
.
NaN
;
}
double
[]
focusing_fx
=
createFXandJacobian
(
sv
,
false
);
double
rms_pure
=
calcErrorDiffY
(
focusing_fx
,
true
);
// System.out.println("rms_pure="+rms_pure);
return
rms_pure
;
}
public
double
findAdjustZ
(
FocusingFieldMeasurement
measurement
,
boolean
filterZ
,
double
zMin
,
double
zMax
,
double
zStep
,
double
tx
,
double
ty
){
double
zBest
=
Double
.
NaN
;
double
bestRMS
=
Double
.
NaN
;
for
(
double
z
=
zMin
;
z
<=
zMax
;
z
+=
zStep
){
double
rms
=
getAdjustRMS
(
measurement
,
filterZ
,
z
,
tx
,
ty
);
if
(((
Double
.
isNaN
(
bestRMS
)
||
(
bestRMS
>=
rms
))
&&
!
Double
.
isNaN
(
rms
)
&&
(
rms
>
0.0
))){
zBest
=
z
;
bestRMS
=
rms
;
}
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"findAdjustZ(): z="
+
z
+
" rms="
+
rms
);
}
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"findAdjustZ()->"
+
zBest
+
" (best RMS = "
+
bestRMS
+
")"
);
return
zBest
;
}
public
boolean
LevenbergMarquardt
(
boolean
openDialog
,
int
debugLevel
){
public
boolean
LevenbergMarquardt
(
FocusingFieldMeasurement
measurement
,
// null in calibrate mode
boolean
openDialog
,
boolean
filterZ
,
// for adjust mode
int
debugLevel
){
boolean
calibrate
=
measurement
==
null
;
double
savedLambda
=
this
.
lambda
;
this
.
debugLevel
=
debugLevel
;
if
(
openDialog
&&
!
selectLMAParameters
())
return
false
;
this
.
startTime
=
System
.
nanoTime
();
// create savedVector (it depends on parameter masks), restore from it if aborted
// create savedVector (it depends on parameter masks), restore from it if aborted
// fieldFitting.initSampleCorrVector(
// flattenSampleCoord(), //double [][] sampleCoordinates,
// getSeriesWeights()); //double [][] sampleSeriesWeights);
// fieldFitting.setEstimatedZ0( z0_estimates, false); // boolean force)
// this.savedVector=this.fieldFitting.createParameterVector(sagittalMaster);
// if (debugDerivativesFxDxDy){
// compareDrDerivatives(this.savedVector);
// }
if
(!
calibrate
)
{
this
.
currentStrategyStep
=-
1
;
fieldFitting
.
selectZTilt
();
keepCorrectionParameters
=
true
;
resetCenter
=
false
;
if
(!
openDialog
)
stopEachStep
=
false
;
}
this
.
iterationStepNumber
=
0
;
this
.
firstRMS
=-
1
;
//undefined
while
(
true
)
{
// loop for all series
if
(
this
.
currentStrategyStep
>=
0
){
if
(!
getStrategy
(
this
.
currentStrategyStep
))
break
;
//invalid strategy
}
if
(!
keepCorrectionParameters
)
fieldFitting
.
resetSampleCorr
();
if
(
resetCenter
){
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Resetting center: X "
+
IJ
.
d2s
(
currentPX0
,
2
)+
" -> "
+
IJ
.
d2s
(
pX0_distortions
,
2
));
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Resetting center: Y "
+
IJ
.
d2s
(
currentPY0
,
2
)+
" -> "
+
IJ
.
d2s
(
pY0_distortions
,
2
));
currentPX0
=
pX0_distortions
;
currentPY0
=
pY0_distortions
;
fieldFitting
.
setCenterXY
(
currentPX0
,
currentPY0
);
}
// setDataVector(createDataVector()); //new
fieldFitting
.
initSampleCorrChnParIndex
(
flattenSampleCoord
());
if
(
calibrate
)
{
setDataVector
(
true
,
// calibrate mode
createDataVector
());
// Make it different for adjustment mode
fieldFitting
.
initSampleCorrVector
(
flattenSampleCoord
(),
//double [][] sampleCoordinates,
getSeriesWeights
());
//double [][] sampleSeriesWeights);
fieldFitting
.
setEstimatedZ0
(
z0_estimates
,
false
);
// boolean force)
}
else
{
setDataVector
(
false
,
// calibrate mode
createDataVector
(
measurement
));
// Make it different for adjustment mode
if
(
filterZ
)
{
boolean
[]
en
=
dataWeightsToBoolean
();
en
=
filterByZRanges
(
zRanges
,
en
);
maskDataWeights
(
en
);
prevEnable
=
en
;
int
numEn
=
getNumEnabledSamples
(
en
);
if
(
numEn
<
minLeftSamples
)
return
false
;
}
fieldFitting
.
initSampleCorrVector
(
flattenSampleCoord
(),
//double [][] sampleCoordinates,
null
);
//getSeriesWeights()); //double [][] sampleSeriesWeights);
// fieldFitting.setEstimatedZ0( z0_estimates, false); // boolean force)
}
this
.
savedVector
=
this
.
fieldFitting
.
createParameterVector
(
sagittalMaster
);
if
(
debugDerivativesFxDxDy
){
compareDrDerivatives
(
this
.
savedVector
);
}
this
.
iterationStepNumber
=
0
;
this
.
firstRMS
=-
1
;
//undefined
// while (this.fittingStrategy.isSeriesValid(this.seriesNumber)){ // TODO: Add "stop" tag to series
// while (this.fittingStrategy.isSeriesValid(this.seriesNumber)){ // TODO: Add "stop" tag to series
this
.
currentVector
=
null
;
// invalidate for the new series
// boolean wasLastSeries=false;
// boolean wasLastSeries=false;
while
(
true
)
{
// loop for the same series
boolean
[]
state
=
stepLevenbergMarquardtFirst
(
debugLevel
);
...
...
@@ -2999,7 +3265,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
return
false
;
}
if
(
debugLevel
>
1
)
System
.
out
.
println
(
":"
+
this
.
iterationStepNumber
+
": stepLevenbergMarquardtFirst("
+
debugLevel
+
")==>"
+
state
[
1
]+
":"
+
state
[
0
]);
if
(
debugLevel
>
1
)
System
.
out
.
println
(
this
.
currentStrategyStep
+
":"
+
this
.
iterationStepNumber
+
": stepLevenbergMarquardtFirst("
+
debugLevel
+
")==>"
+
state
[
1
]+
":"
+
state
[
0
]);
boolean
cont
=
true
;
// Make it success if this.currentRMS<this.firstRMS even if LMA failed to converge
if
(
state
[
1
]
&&
!
state
[
0
]
&&
(
this
.
firstRMS
>
this
.
currentRMS
)){
...
...
@@ -3010,12 +3276,12 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
if
(
(
this
.
stopRequested
.
get
()>
0
)
||
// graceful stop requested
(
this
.
stopEachStep
)
||
//
(this.stopEachSeries && state[1]) ||
(
this
.
stopEachSeries
&&
state
[
1
])
||
(
this
.
stopOnFailure
&&
state
[
1
]
&&
!
state
[
0
])){
if
(
debugLevel
>
0
){
if
(
this
.
stopRequested
.
get
()>
0
)
System
.
out
.
println
(
"User requested stop"
);
System
.
out
.
println
(
"LevenbergMarquardt(): step =
"
+
this
.
iterationStepNumber
+
System
.
out
.
println
(
"LevenbergMarquardt(): step ="
+
this
.
currentStrategyStep
+
":
"
+
this
.
iterationStepNumber
+
", RMS="
+
IJ
.
d2s
(
this
.
currentRMS
,
8
)+
" ("
+
IJ
.
d2s
(
this
.
firstRMS
,
8
)+
") "
+
") at "
+
IJ
.
d2s
(
0.000000001
*(
System
.
nanoTime
()-
this
.
startTime
),
3
));
...
...
@@ -3024,12 +3290,12 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
cont
=
dialogLMAStep
(
state
);
this
.
stopRequested
.
set
(
0
);
// Will not stop each run
this
.
startTime
+=(
System
.
nanoTime
()-
startDialogTime
);
// do not count time used by the User.
// if (this.showThisImages) showDiff (this.currentfX, "fit-"+this.iterationStepNumber);
// if (this.showNextImages) showDiff (this.nextfX, "fit-"+(this.iterationStepNumber+1));
// if (this.showThisImages) showDiff (this.currentfX, "fit-"+this.iterationStepNumber);
// if (this.showNextImages) showDiff (this.nextfX, "fit-"+(this.iterationStepNumber+1));
}
stepLevenbergMarquardtAction
(
debugLevel
);
// apply step - in any case?
if
(
this
.
updateStatus
){
IJ
.
showStatus
(
"Step #
"
+
this
.
iterationStepNumber
+
IJ
.
showStatus
(
"Step #"
+
this
.
currentStrategyStep
+
":
"
+
this
.
iterationStepNumber
+
" RMS="
+
IJ
.
d2s
(
this
.
currentRMS
,
8
)+
" ("
+
IJ
.
d2s
(
this
.
firstRMS
,
8
)+
")"
+
" RMSPure="
+
IJ
.
d2s
(
this
.
currentRMSPure
,
8
)+
...
...
@@ -3041,16 +3307,16 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
savedLambda
=
this
.
lambda
;
this
.
savedVector
=
this
.
currentVector
.
clone
();
// saveFittingSeries(); // will save series even if it ended in failure, vector will be only updated
// updateCameraParametersFromCalculated(true); // update camera parameters from all (even disabled) images
// updateCameraParametersFromCalculated(false); // update camera parameters from enabled only images (may overwrite some of the above)
// saveFittingSeries(); // will save series even if it ended in failure, vector will be only updated
// updateCameraParametersFromCalculated(true); // update camera parameters from all (even disabled) images
// updateCameraParametersFromCalculated(false); // update camera parameters from enabled only images (may overwrite some of the above)
}
// if RMS was decreased. this.saveSeries==false after dialogLMAStep(state) only if "cancel" was pressed
commitParameterVector
(
this
.
savedVector
);
// either new or original
this
.
lambda
=
savedLambda
;
return
this
.
saveSeries
;
// TODO: Maybe change result?
}
//stepLevenbergMarquardtAction();
//stepLevenbergMarquardtAction();
if
(
state
[
1
])
{
if
(!
state
[
0
])
{
commitParameterVector
(
this
.
savedVector
);
...
...
@@ -3058,23 +3324,31 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
return
false
;
// sequence failed
}
this
.
savedVector
=
this
.
currentVector
.
clone
();
// saveFittingSeries();
// updateCameraParametersFromCalculated(true); // update camera parameters from all (even disabled) images
// updateCameraParametersFromCalculated(false); // update camera parameters from enabled only images (may overwrite some of the above)
// wasLastSeries=this.fittingStrategy.isLastSeries(this.seriesNumber);
// this.seriesNumber++;
// saveFittingSeries();
// updateCameraParametersFromCalculated(true); // update camera parameters from all (even disabled) images
// updateCameraParametersFromCalculated(false); // update camera parameters from enabled only images (may overwrite some of the above)
// wasLastSeries=this.fittingStrategy.isLastSeries(this.seriesNumber);
// this.seriesNumber++;
break
;
// while (true), proceed to the next series
}
}
// if (wasLastSeries) break;
// } // while (this.fittingStrategy.isSeriesValid(this.seriesNumber)){ // TODO: Add "stop" tag to series
}
// while true - same series
// if (wasLastSeries) break;
// } // while (this.fittingStrategy.isSeriesValid(this.seriesNumber)){ // TODO: Add "stop" tag to series
if
(
fieldFitting
.
fieldStrategies
.
isLast
(
this
.
currentStrategyStep
))
break
;
String
msg
=
"LMA series="
+
this
.
currentStrategyStep
+
" RMS="
+
this
.
currentRMS
+
" ("
+
this
.
firstRMS
+
") "
+
", pure RMS="
+
this
.
currentRMSPure
+
" ("
+
this
.
firstRMSPure
+
") "
+
" at "
+
IJ
.
d2s
(
0.000000001
*(
System
.
nanoTime
()-
this
.
startTime
),
3
);
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"stepLevenbergMarquardtAction() "
+
msg
);
this
.
currentStrategyStep
++;
this
.
iterationStepNumber
=
0
;
}
// for all series
String
msg
=
"RMS="
+
this
.
currentRMS
+
" ("
+
this
.
firstRMS
+
") "
+
", pure RMS="
+
this
.
currentRMSPure
+
" ("
+
this
.
firstRMSPure
+
") "
+
" at "
+
IJ
.
d2s
(
0.000000001
*(
System
.
nanoTime
()-
this
.
startTime
),
3
);
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"stepLevenbergMarquardtAction() "
+
msg
);
// if (this.updateStatus) IJ.showStatus(msg);
if
(
this
.
updateStatus
){
IJ
.
showStatus
(
"Done: Step #
"
+
this
.
iterationStepNumber
+
IJ
.
showStatus
(
"Done: Step #"
+
this
.
currentStrategyStep
+
":
"
+
this
.
iterationStepNumber
+
" RMS="
+
IJ
.
d2s
(
this
.
currentRMS
,
8
)+
" ("
+
IJ
.
d2s
(
this
.
firstRMS
,
8
)+
")"
+
" RMSPure="
+
IJ
.
d2s
(
this
.
currentRMSPure
,
8
)+
...
...
@@ -3083,8 +3357,9 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
}
this
.
savedVector
=
this
.
currentVector
.
clone
();
commitParameterVector
(
this
.
savedVector
);
if
(
calibrate
)
zRanges
=
calcZRanges
(
dataWeightsToBoolean
());
return
true
;
// all series done
}
}
public
class
FocusingFieldMeasurement
{
public
String
timestamp
;
...
...
@@ -3327,6 +3602,157 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
e
.
printStackTrace
();
}
}
public
void
testMeasurement
(){
GenericDialog
gd
=
new
GenericDialog
(
"Select measurement"
);
int
nMeas
=
measurements
.
size
()/
2
;
double
zMin
=-
40.0
;
double
zMax
=
40.0
;
double
zStep
=
2.0
;
filterZ
=
true
;
// (adjustment mode)filter samples by Z
minLeftSamples
=
10
;
// minimal number of samples (channel/dir/location) for adjustment
gd
.
addNumericField
(
"Measurement number"
,
nMeas
,
0
,
5
,
"0.."
+(
measurements
.
size
()-
1
));
gd
.
addCheckbox
(
"Filter samples/channels by Z"
,
filterZ
);
gd
.
addNumericField
(
"Minimal required number of channels/samples"
,
minLeftSamples
,
0
,
3
,
"samples"
);
gd
.
addNumericField
(
"Z min"
,
zMin
,
2
,
5
,
"um"
);
gd
.
addNumericField
(
"Z max"
,
zMax
,
2
,
5
,
"um"
);
gd
.
addNumericField
(
"Z step"
,
zStep
,
2
,
5
,
"um"
);
gd
.
showDialog
();
if
(
gd
.
wasCanceled
())
return
;
nMeas
=(
int
)
gd
.
getNextNumber
();
filterZ
=
gd
.
getNextBoolean
();
minLeftSamples
=(
int
)
gd
.
getNextNumber
();
zMin
=
gd
.
getNextNumber
();
zMax
=
gd
.
getNextNumber
();
zStep
=
gd
.
getNextNumber
();
boolean
OK
;
if
(
nMeas
>=
0
){
OK
=
testMeasurement
(
measurements
.
get
(
nMeas
),
// nMeas,
zMin
,
zMax
,
zStep
);
if
(!
OK
){
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"testMeasurement("
+
nMeas
+
") failed"
);
}
else
{
if
(
debugLevel
>
0
)
System
.
out
.
print
(
"======== testMeasurement("
+
nMeas
+
") ========"
);
for
(
int
i
=
0
;
i
<
fieldFitting
.
mechanicalFocusingModel
.
paramValues
.
length
;
i
++){
if
((
fieldFitting
.
mechanicalSelect
==
null
)
||
fieldFitting
.
mechanicalSelect
[
i
]
)
{
System
.
out
.
println
(
fieldFitting
.
mechanicalFocusingModel
.
getDescription
(
i
)+
": "
+
IJ
.
d2s
(
fieldFitting
.
mechanicalFocusingModel
.
paramValues
[
i
],
3
)+
" "
+
fieldFitting
.
mechanicalFocusingModel
.
getUnits
(
i
));
}
}
}
}
else
{
for
(
nMeas
=
0
;
nMeas
<
measurements
.
size
();
nMeas
++){
if
(
debugLevel
>
0
)
System
.
out
.
print
(
"======== testMeasurement("
+
nMeas
+
") ======== "
);
OK
=
testMeasurement
(
measurements
.
get
(
nMeas
),
// nMeas,
zMin
,
zMax
,
zStep
);
if
(!
OK
){
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"testMeasurement("
+
nMeas
+
") failed"
);
}
else
{
// if (debugLevel>0) System.out.println("======== testMeasurement("+nMeas+") ========");
for
(
int
i
=
0
;
i
<
fieldFitting
.
mechanicalFocusingModel
.
paramValues
.
length
;
i
++){
if
((
fieldFitting
.
mechanicalSelect
==
null
)
||
fieldFitting
.
mechanicalSelect
[
i
]
)
{
System
.
out
.
println
(
fieldFitting
.
mechanicalFocusingModel
.
getDescription
(
i
)+
": "
+
IJ
.
d2s
(
fieldFitting
.
mechanicalFocusingModel
.
paramValues
[
i
],
3
)+
" "
+
fieldFitting
.
mechanicalFocusingModel
.
getUnits
(
i
));
}
}
}
}
}
}
public
boolean
testMeasurement
(
FocusingFieldMeasurement
measurement
,
// null in calibrate mode
// int nMeas,
double
zMin
,
double
zMax
,
double
zStep
){
int
retryLimit
=
20
;
setDataVector
(
false
,
createDataVector
(
measurement
));
//measurements.get(nMeas)));
// System.out.println("testMeasurement("+nMeas+")");
double
z
=
findAdjustZ
(
// measurements.get(nMeas),
measurement
,
filterZ
,
//boolean filterZ,
zMin
,
zMax
,
zStep
,
0.0
,
//double tx,
0.0
);
// double ty);
fieldFitting
.
mechanicalFocusingModel
.
setZTxTy
(
z
,
0.0
,
0.0
);
// z,tx,ty
boolean
[]
wasPrevEnable
=
null
;
for
(
int
n
=
0
;
n
<
retryLimit
;
n
++)
{
// TODO: Watch for the mask remain stable
z
=
fieldFitting
.
mechanicalFocusingModel
.
getValue
(
MECH_PAR
.
z0
);
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"testMeasurement(), run "
+
n
+
" (z="
+
z
+
")"
);
boolean
[]
was2PrevEnable
=(
wasPrevEnable
==
null
)?
null
:
wasPrevEnable
.
clone
();
wasPrevEnable
=(
prevEnable
==
null
)?
null
:
prevEnable
.
clone
();
boolean
OK
=
LevenbergMarquardt
(
measurement
,
false
,
// true, // open dialog
filterZ
,
// filterZ
debugLevel
);
if
(!
OK
){
// if (debugLevel>0) System.out.println("testMeasurement("+nMeas+") failed");
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"testMeasurement() failed"
);
return
false
;
}
/*
for (int i=0;i<fieldFitting.mechanicalFocusingModel.paramValues.length;i++){
if ((fieldFitting.mechanicalSelect==null) || fieldFitting.mechanicalSelect[i] ) {
System.out.println(
fieldFitting.mechanicalFocusingModel.getDescription(i)+": "+
IJ.d2s(fieldFitting.mechanicalFocusingModel.paramValues[i],3)+" "+
fieldFitting.mechanicalFocusingModel.getUnits(i));
}
}
*/
if
((
wasPrevEnable
!=
null
)
&&
(
prevEnable
!=
null
)
&&
(
wasPrevEnable
.
length
==
prevEnable
.
length
)){
boolean
changedEnable
=
false
;
for
(
int
i
=
0
;
i
<
prevEnable
.
length
;
i
++)
if
(
prevEnable
[
i
]!=
wasPrevEnable
[
i
]){
changedEnable
=
true
;
break
;
}
if
(!
changedEnable
)
{
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"No filter chnage, finished in "
+(
n
+
1
)+
" steps"
);
return
true
;
}
else
{
if
((
was2PrevEnable
!=
null
)
&&
(
prevEnable
!=
null
)
&&
(
was2PrevEnable
.
length
==
prevEnable
.
length
)){
changedEnable
=
false
;
for
(
int
i
=
0
;
i
<
prevEnable
.
length
;
i
++)
if
(
prevEnable
[
i
]!=
was2PrevEnable
[
i
]){
changedEnable
=
true
;
break
;
}
if
(!
changedEnable
)
{
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Filter repeats one before previous, finished in "
+(
n
+
1
)+
" steps"
);
return
true
;
}
}
}
}
}
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Maximal retries exceeded in "
+
retryLimit
+
" steps"
);
return
true
;
//?
}
public
class
FieldFitting
{
// private Properties savedProperties=null;
private
double
[]
pXY
=
null
;
...
...
@@ -3342,6 +3768,11 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
private
double
[][]
sampleCorrCost
=
new
double
[
6
][];
// equivalent cost of one unit of parameter value (in result units, um)
private
double
[][]
sampleCorrSigma
=
new
double
[
6
][];
// sigma (in mm) for neighbors influence
private
double
[][]
sampleCorrPullZero
=
new
double
[
6
][];
// 1.0 - only difference from neighbors matters, 0.0 - only difference from 0
// private String strategyComment="";
// private boolean lastInSeries=true;
// private double lambda=0.001; // synchronize with top?
public
FieldStrategies
fieldStrategies
;
// private double [] sampleCorrRadius=null;
private
double
[][]
sampleCoordinates
=
null
;
private
double
[][][][]
sampleCorrCrossWeights
=
new
double
[
6
][][][];
...
...
@@ -3359,7 +3790,8 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
// private double [] dflt_sampleCorrCost= {0.1,0.5,2.0,1.0};
// private double [] dflt_sampleCorrCost= {0.1,1.0,1.0,0.5};
// private double [] dflt_sampleCorrCost= {0.2,2.0,2.0,1.0,1.0};
private
double
[]
dflt_sampleCorrCost
=
{
0.1
,
1.0
,
1.0
,
1.0
,
1.0
};
// private double [] dflt_sampleCorrCost= {0.1,1.0,1.0,1.0,1.0};
private
double
[]
dflt_sampleCorrCost
=
{
0.01
,
1.0
,
1.0
,
1.0
,
1.0
};
private
double
dflt_sampleCorrSigma
=
2.0
;
// mm
private
double
dflt_sampleCorrPullZero
=
0.75
;
// fraction
public
final
String
[]
channelDescriptions
={
...
...
@@ -3411,6 +3843,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
}
}
}
fieldStrategies
.
setProperties
(
prefix
+
"fieldStrategies."
,
properties
);
}
public
void
getProperties
(
String
prefix
,
Properties
properties
){
if
(
properties
.
getProperty
(
prefix
+
"numberOfLocations"
)!=
null
)
...
...
@@ -3536,8 +3969,8 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"numberOfLocations==0, can not restore"
);
}
fieldStrategies
=
new
FieldStrategies
();
// reset old
fieldStrategies
.
getProperties
(
prefix
+
"fieldStrategies."
,
properties
);
}
// public double [] getSampleRadiuses(){ // distance from the current center to each each sample
...
...
@@ -4179,7 +4612,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
public
void
initSampleCorrVector
(
double
[][]
sampleCoordinates
,
double
[][]
sampleSeriesWeights
){
System
.
out
.
println
(
"initSampleCorrVector()"
);
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"initSampleCorrVector()"
);
numberOfLocations
=
sampleCoordinates
.
length
;
this
.
sampleCoordinates
=
new
double
[
sampleCoordinates
.
length
][];
for
(
int
i
=
0
;
i
<
sampleCoordinates
.
length
;
i
++)
this
.
sampleCoordinates
[
i
]=
sampleCoordinates
[
i
].
clone
();
...
...
@@ -4250,7 +4683,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
sampleCorrChnParIndex
[
nChn
]=
null
;
}
}
System
.
out
.
println
(
"initSampleCorrChnParIndex()"
);
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"initSampleCorrChnParIndex()"
);
// currently all correction parameters are initialized as zeros.
getCorrVector
();
}
...
...
@@ -4297,6 +4730,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
int
distanceParametersNumber
,
int
radialParametersNumber
)
{
fieldStrategies
=
new
FieldStrategies
();
pXY
=
new
double
[
2
];
pXY
[
0
]=
pX0
;
pXY
[
1
]=
pY0
;
...
...
@@ -4327,7 +4761,12 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
}
}
public
boolean
maskSetDialog
(
String
title
){
public
boolean
maskSetDialog
(
String
title
//,
// String strategyComment,
// double lambda,
// boolean lastInSeries
){
GenericDialog
gd
=
new
GenericDialog
(
title
);
boolean
editMechMask
=
false
;
boolean
editCurvMask
=
false
;
...
...
@@ -4352,7 +4791,13 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
gd
.
addCheckbox
(
"Setup per-sample correction"
,
setupCorrectionPars
);
gd
.
addCheckbox
(
"Apply same per-sample corrections to all channels"
,
commonCorrectionPars
);
gd
.
addCheckbox
(
"Setup correction parameters when the parameter itself is disabled"
,
disabledCorrectionPars
);
gd
.
addMessage
(
"---"
);
gd
.
addStringField
(
"Strategy comment"
,
strategyComment
,
60
);
gd
.
addNumericField
(
"Initial LMA lambda"
,
lambda
,
3
,
5
,
""
);
gd
.
addCheckbox
(
"Reset optical center to distortions center"
,
resetCenter
);
gd
.
addCheckbox
(
"Reset correction parameters before this LMA step"
,
!
keepCorrectionParameters
);
gd
.
addCheckbox
(
"Stop after this LMA step"
,
lastInSeries
);
// gd.enableYesNoCancel("Keep","Apply"); // default OK (on enter) - "Keep"
gd
.
showDialog
();
...
...
@@ -4369,6 +4814,12 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
setupCorrectionPars
=
gd
.
getNextBoolean
();
commonCorrectionPars
=
gd
.
getNextBoolean
();
disabledCorrectionPars
=
gd
.
getNextBoolean
();
strategyComment
=
gd
.
getNextString
();
lambda
=
gd
.
getNextNumber
();
resetCenter
=
gd
.
getNextBoolean
();
keepCorrectionParameters
=!
gd
.
getNextBoolean
();
lastInSeries
=
gd
.
getNextBoolean
();
// boolean OK;
if
(
editMechMask
){
boolean
[]
mask
=
mechanicalFocusingModel
.
maskSetDialog
(
"Focusing mechanical parameters mask"
,
mechanicalSelect
);
...
...
@@ -4418,6 +4869,21 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
return
true
;
}
public
void
selectZTilt
(){
mechanicalSelect
=
mechanicalFocusingModel
.
maskSetZTxTy
();
// enable z0, tx, ty
// enable all color/dir channels (add separate selection dialog?)
for
(
int
i
=
0
;
i
<
channelSelect
.
length
;
i
++)
{
channelSelect
[
i
]=
true
;
curvatureSelect
[
i
]=
curvatureModel
[
0
].
maskAllDisabled
();
}
if
(
sampleCorrSelect
!=
null
){
for
(
int
i
=
0
;
i
<
sampleCorrSelect
.
length
;
i
++)
if
(
sampleCorrSelect
[
i
]!=
null
)
{
for
(
int
j
=
0
;
j
<
sampleCorrSelect
[
i
].
length
;
j
++)
sampleCorrSelect
[
i
][
j
]=
false
;
}
}
initSampleCorrChnParIndex
(
flattenSampleCoord
());
}
ArrayList
<
String
>
getParameterValueStrings
(
boolean
showDisabled
,
boolean
showCorrection
){
ArrayList
<
String
>
parList
=
new
ArrayList
<
String
>();
parList
.
add
(
"\t ===== Aberrations center =====\t\t"
);
...
...
@@ -4824,49 +5290,9 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
}
return
chnValues
;
}
/*
public double [] getValsDerivativesOld(
boolean sagittalMaster,
int [] motors, // 3 motor coordinates
double px, // pixel x
double py, // pixel y
double [][] deriv // array of (1..6[][], matching getNumberOfChannels) or null if derivatives are not required
){
double [] motorDerivs=(deriv==null)? null:(new double [mechanicalFocusingModel.getNumPars()]);
double [] chnValues=new double [getNumberOfChannels()];
double mot_z=mechanicalFocusingModel.calc_ZdZ(
motors,
px,
py,
motorDerivs);
int nChn=0;
for (int c=0;c<channelSelect.length;c++) if (channelSelect[c]){
double [] deriv_curv=(deriv==null)?null:(new double [curvatureModel[c].getSize()]);
chnValues[nChn]=curvatureModel[c].getFdF(
null, // param_corr
px,
py,
mot_z,
deriv_curv);
if (deriv!=null){
deriv[nChn]=new double [getNumberOfParameters(sagittalMaster)];
int np=0;
for (int i=0;i<mechanicalFocusingModel.paramValues.length;i++){
if ((mechanicalSelect==null) || mechanicalSelect[i] ) deriv[nChn][np++]=-motorDerivs[i]*deriv_curv[0]; // minus d/dz0 const part
}
for (int n=0;n<channelSelect.length;n++) if (channelSelect[n]){
for (int i=0;i<curvatureSelect[n].length; i++) if (curvatureSelect[n][i] ){
deriv[nChn][np++]=(n==c)?(deriv_curv[i]):0.0;
}
}
}
nChn++;
}
return chnValues;
}
*/
}
...
...
@@ -4891,7 +5317,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
{
"tx"
,
"horizontal tilt"
,
"um/mm"
,
"0.0"
},
{
"ty"
,
"vertical tilt"
,
"um/mm"
,
"0.0"
}};
public
double
PERIOD
=
3584.0
;
// steps/revolution
// public double PIXEL_SIZE=0.0022; // mm
// public double PIXEL_SIZE=0.0022; // mm
public
double
[]
paramValues
=
new
double
[
descriptions
.
length
];
public
MechanicalFocusingModel
(){
// add arguments?
...
...
@@ -4921,6 +5347,11 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
paramValues
=
new
double
[
descriptions
.
length
];
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
paramValues
[
i
]=
vector
[
i
];
}
public
void
setZTxTy
(
double
z
,
double
tx
,
double
ty
){
paramValues
[
getIndex
(
MECH_PAR
.
z0
)]=
z
;
paramValues
[
getIndex
(
MECH_PAR
.
tx
)]=
tx
;
paramValues
[
getIndex
(
MECH_PAR
.
ty
)]=
ty
;
}
public
void
setVector
(
double
[]
vector
,
boolean
[]
mask
){
for
(
int
i
=
0
;
i
<
vector
.
length
;
i
++)
if
(
mask
[
i
])
paramValues
[
i
]=
vector
[
i
];
...
...
@@ -5035,7 +5466,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
d2Z/dY/dm3= 0
*/
// double [] deriv=new double [paramValues.length];
// double [] deriv=new double [paramValues.length];
double
kM1
=
getValue
(
MECH_PAR
.
K0
)+
getValue
(
MECH_PAR
.
KD1
)-
getValue
(
MECH_PAR
.
KD3
);
double
kM2
=
getValue
(
MECH_PAR
.
K0
)-
getValue
(
MECH_PAR
.
KD1
)-
getValue
(
MECH_PAR
.
KD3
);
double
kM3
=
getValue
(
MECH_PAR
.
K0
)+
getValue
(
MECH_PAR
.
KD3
);
...
...
@@ -5052,7 +5483,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double
dx
=
PIXEL_SIZE
*(
px
-
getValue
(
MECH_PAR
.
mpX0
));
double
dy
=
PIXEL_SIZE
*(
py
-
getValue
(
MECH_PAR
.
mpY0
));
double
zx
=
dx
*(
getValue
(
MECH_PAR
.
tx
)+(
2
*
zM3
-
zM1
-
zM2
)/(
4
*
getValue
(
MECH_PAR
.
Lx
)))
;
// double zy=dy*(getValue(MECH_PAR.ty)+(zM1-zM2)/(2*getValue(MECH_PAR.Ly)));
// double zy=dy*(getValue(MECH_PAR.ty)+(zM1-zM2)/(2*getValue(MECH_PAR.Ly)));
double
zy
=
dy
*(
getValue
(
MECH_PAR
.
ty
)+(
zM2
-
zM1
)/(
2
*
getValue
(
MECH_PAR
.
Ly
)));
double
z
=
zc
+
zx
+
zy
;
if
(
dbg
)
if
((
Math
.
abs
(
m1
)==
debugMot
)&&
(
Math
.
abs
(
m2
)==
debugMot
)){
...
...
@@ -5077,8 +5508,8 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double
zM2_KD1
=-
aM2
;
double
zM2_KD3
=-
aM2
;
double
zM3_K0
=
aM3
;
// double zM3_KD1=-aM3;
// double zM3_KD3= 0.0;
// double zM3_KD1=-aM3;
// double zM3_KD3= 0.0;
double
zM3_KD1
=
0.0
;
double
zM3_KD3
=
aM3
;
double
zM1_sM1
=
kM1
*
p2pi
*
Math
.
sin
(
m1
/
p2pi
);
...
...
@@ -5098,7 +5529,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double
zc_sM3
=
0.5
*
zM3_sM3
;
double
zc_cM3
=
0.5
*
zM3_cM3
;
// double zx_K0=(2*zM3-zM1-zM2)* dx/(4*getValue(MECH_PAR.Lx));
// double zx_K0=(2*zM3-zM1-zM2)* dx/(4*getValue(MECH_PAR.Lx));
double
zx_a
=
dx
/(
4
*
getValue
(
MECH_PAR
.
Lx
));
double
zx_K0
=
(
2
*
zM3_K0
-
zM1_K0
-
zM2_K0
)*
zx_a
;
double
zx_KD1
=(
2
*
zM3_KD1
-
zM1_KD1
-
zM2_KD1
)*
zx_a
;
...
...
@@ -5112,7 +5543,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double
zx_mpX0
=
dx_mpX0
*(
getValue
(
MECH_PAR
.
tx
)+(
2
*
zM3
-
zM1
-
zM2
)/(
4
*
getValue
(
MECH_PAR
.
Lx
)));
// double zx_mpX0=dx_mpX0/(4*getValue(MECH_PAR.Lx));
double
zx_tx
=
dx
;
double
zx_Lx
=
-
dx
*(
2
*
zM3
-
zM1
-
zM2
)/(
4
*
getValue
(
MECH_PAR
.
Lx
)*
getValue
(
MECH_PAR
.
Lx
));
// double zy=dy*(getValue(MECH_PAR.ty)+(zM2-zM1)/(2*getValue(MECH_PAR.Ly)));
// double zy=dy*(getValue(MECH_PAR.ty)+(zM2-zM1)/(2*getValue(MECH_PAR.Ly)));
double
zy_a
=
dy
/(
2
*
getValue
(
MECH_PAR
.
Ly
));
double
zy_K0
=
(
zM2_K0
-
zM1_K0
)
*
zy_a
;
double
zy_KD1
=
(
zM2_KD1
-
zM1_KD1
)*
zy_a
;
...
...
@@ -5125,7 +5556,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double
zy_cM3
=
0.0
;
double
zy_mpY0
=
dy_mpY0
*(
getValue
(
MECH_PAR
.
ty
)+(
zM2
-
zM1
)/(
2
*
getValue
(
MECH_PAR
.
Ly
)));
// double zy_mpY0=dy_mpY0/(2*getValue(MECH_PAR.Ly));
double
zy_ty
=
dy
;
// double zy_Ly= -dy*(zM1-zM2)/(2*getValue(MECH_PAR.Ly)*getValue(MECH_PAR.Ly));
// double zy_Ly= -dy*(zM1-zM2)/(2*getValue(MECH_PAR.Ly)*getValue(MECH_PAR.Ly));
double
zy_Ly
=
-
dy
*(
zM2
-
zM1
)/(
2
*
getValue
(
MECH_PAR
.
Ly
)*
getValue
(
MECH_PAR
.
Ly
));
deriv
[
getIndex
(
MECH_PAR
.
K0
)]=
zc_K0
+
zx_K0
+
zy_K0
;
...
...
@@ -5201,13 +5632,21 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
}
return
mask
;
}
public
boolean
[]
maskSetZTxTy
(){
boolean
[]
mask
=
new
boolean
[
this
.
paramValues
.
length
];
for
(
int
i
=
0
;
i
<
mask
.
length
;
i
++)
mask
[
i
]=
false
;
mask
[
getIndex
(
MECH_PAR
.
z0
)]=
true
;
mask
[
getIndex
(
MECH_PAR
.
tx
)]=
true
;
mask
[
getIndex
(
MECH_PAR
.
ty
)]=
true
;
return
mask
;
}
public
boolean
showModifyParameterValues
(
String
title
,
boolean
showDisabled
,
boolean
[]
mask
){
GenericDialog
gd
=
new
GenericDialog
(
title
);
for
(
int
i
=
0
;
i
<
this
.
paramValues
.
length
;
i
++){
if
((
mask
==
null
)
||
mask
[
i
]
)
{
gd
.
addNumericField
(
getDescription
(
i
),
this
.
paramValues
[
i
],
5
,
8
,
getUnits
(
i
));
}
else
if
(
showDisabled
){
// gd.addMessage(getDescription(i) +": "+this.paramValues[i]+" ("+getUnits(i)+")");
// gd.addMessage(getDescription(i) +": "+this.paramValues[i]+" ("+getUnits(i)+")");
gd
.
addNumericField
(
"(disabled) "
+
getDescription
(
i
),
this
.
paramValues
[
i
],
5
,
8
,
getUnits
(
i
));
}
}
...
...
@@ -5615,6 +6054,11 @@ f_corr: d_fcorr/d_zcorr=0, other: a, reff, kx -> ar[1], ar[2], ar[3], ar[4]
}
return
mask
;
}
public
boolean
[]
maskAllDisabled
(){
boolean
[]
mask
=
new
boolean
[
this
.
modelParams
.
length
*
this
.
modelParams
[
0
].
length
];
for
(
int
i
=
0
;
i
<
mask
.
length
;
i
++)
mask
[
i
]=
false
;
return
mask
;
}
public
boolean
[]
maskSetDialog
(
String
title
,
boolean
detailed
,
boolean
[]
currentMask
){
GenericDialog
gd
=
new
GenericDialog
(
title
);
boolean
[]
mask
=
new
boolean
[
this
.
modelParams
.
length
*
this
.
modelParams
[
0
].
length
];
...
...
@@ -5710,6 +6154,608 @@ f_corr: d_fcorr/d_zcorr=0, other: a, reff, kx -> ar[1], ar[2], ar[3], ar[4]
return
true
;
}
}
public
boolean
getStrategy
(
int
strategyIndex
){
FieldStrategies
fs
=
fieldFitting
.
fieldStrategies
;
if
((
strategyIndex
>=
0
)
&&
(
strategyIndex
<
fs
.
getNumStrategies
()))
{
fs
.
getFromStrategy
(
strategyIndex
,
fieldFitting
);
this
.
strategyComment
=
fs
.
getComment
(
strategyIndex
);
this
.
lambda
=
fs
.
getInitialLambda
(
strategyIndex
);
this
.
lastInSeries
=
fs
.
isStopAfterThis
(
strategyIndex
);
this
.
keepCorrectionParameters
=!
fs
.
isResetCorrection
(
strategyIndex
);
this
.
resetCenter
=
fs
.
isResetCenter
(
strategyIndex
);
return
true
;
}
else
return
false
;
}
public
int
organizeStrategies
(
String
title
){
String
[]
actions
={
"<select action>"
,
// 0
"Restore strategy"
,
// 1
"Save (replace) strategy"
,
// 2
"Save (insert before/append) strategy"
,
// 3
"Remove strategy"
,
// 4
"Edit strategy (restore-edit-save)"
};
// 5
FieldStrategies
fs
=
fieldFitting
.
fieldStrategies
;
int
selectedActionIndex
=
0
;
int
selectedStrategyIndex
=
fs
.
getNumStrategies
();
boolean
editStrategy
=
false
;
GenericDialog
gd
=
new
GenericDialog
(
title
);
gd
.
addMessage
(
"Current strategies:"
);
String
[]
indices
=
new
String
[
fs
.
getNumStrategies
()+
1
];
for
(
int
i
=
0
;
i
<
fs
.
getNumStrategies
();
i
++)
{
indices
[
i
]=
i
+
": "
+
fs
.
getComment
(
i
)+
" ("
+(
fs
.
isStopAfterThis
(
i
)?
"STOP"
:
"CONTINUE"
)+
(
fs
.
isResetCenter
(
i
)?
", RESET CENTER"
:
""
)+
(
fs
.
isResetCorrection
(
i
)?
", RESET CORRECTIONS"
:
""
)+
")"
;
}
indices
[
fs
.
getNumStrategies
()]=
"very end"
;
for
(
int
i
=
0
;
i
<
fs
.
getNumStrategies
();
i
++){
gd
.
addMessage
(
i
+
": "
+
fs
.
getComment
(
i
)+
" ("
+(
fs
.
isStopAfterThis
(
i
)?
"STOP"
:
"CONTINUE"
)+
(
fs
.
isResetCenter
(
i
)?
", RESET CENTER"
:
""
)+
(
fs
.
isResetCorrection
(
i
)?
", RESET CORRECTIONS"
:
""
)+
")"
);
}
gd
.
addMessage
(
"======================="
);
gd
.
addChoice
(
"Action"
,
actions
,
actions
[
selectedActionIndex
]);
gd
.
addChoice
(
"Index"
,
indices
,
indices
[
selectedStrategyIndex
]);
gd
.
addMessage
(
"======================="
);
gd
.
addCheckbox
(
"Edit strategy"
,
editStrategy
);
gd
.
enableYesNoCancel
(
"OK"
,
"Done"
);
WindowTools
.
addScrollBars
(
gd
);
gd
.
showDialog
();
if
(
gd
.
wasCanceled
())
return
-
1
;
selectedActionIndex
=
gd
.
getNextChoiceIndex
();
selectedStrategyIndex
=
gd
.
getNextChoiceIndex
();
editStrategy
=
gd
.
getNextBoolean
();
if
((
selectedActionIndex
!=
3
)
&&
(
selectedStrategyIndex
>=
fs
.
getNumStrategies
())){
selectedStrategyIndex
=
fs
.
getNumStrategies
()-
1
;
// last
}
if
(
selectedStrategyIndex
>=
0
){
switch
(
selectedActionIndex
){
case
1
:
getStrategy
(
selectedStrategyIndex
);
if
(
editStrategy
){
if
(!
fieldFitting
.
maskSetDialog
(
"Setup restored strategy "
+
selectedStrategyIndex
))
break
;
}
break
;
case
3
:
if
(
editStrategy
){
if
(!
fieldFitting
.
maskSetDialog
(
"Setup strategy "
+
selectedStrategyIndex
))
break
;
}
if
(
selectedStrategyIndex
>=
fs
.
getNumStrategies
())
fs
.
addStrategy
();
else
fs
.
insertStrategy
(
selectedStrategyIndex
);
// fall through to the next case
case
2
:
if
((
selectedActionIndex
!=
3
)
&&
editStrategy
){
if
(!
fieldFitting
.
maskSetDialog
(
"Setup strategy "
+
selectedStrategyIndex
))
break
;
}
fs
.
setStrategy
(
selectedStrategyIndex
,
fieldFitting
);
fs
.
setComment
(
selectedStrategyIndex
,
this
.
strategyComment
);
fs
.
setInitialLambda
(
selectedStrategyIndex
,
this
.
lambda
);
fs
.
setStopAfterThis
(
selectedStrategyIndex
,
this
.
lastInSeries
);
fs
.
setResetCorrection
(
selectedStrategyIndex
,!
this
.
keepCorrectionParameters
);
fs
.
setResetCenter
(
selectedStrategyIndex
,
this
.
resetCenter
);
break
;
case
4
:
fs
.
removeStrategy
(
selectedStrategyIndex
);
break
;
case
0
:
if
(
editStrategy
){
if
(!
fieldFitting
.
maskSetDialog
(
"Setup current strategy"
))
break
;
}
break
;
case
5
:
getStrategy
(
selectedStrategyIndex
);
if
(!
fieldFitting
.
maskSetDialog
(
"Edit strategy "
+
selectedStrategyIndex
))
break
;
fs
.
setStrategy
(
selectedStrategyIndex
,
fieldFitting
);
fs
.
setComment
(
selectedStrategyIndex
,
this
.
strategyComment
);
fs
.
setInitialLambda
(
selectedStrategyIndex
,
this
.
lambda
);
fs
.
setStopAfterThis
(
selectedStrategyIndex
,
this
.
lastInSeries
);
fs
.
setResetCorrection
(
selectedStrategyIndex
,!
this
.
keepCorrectionParameters
);
fs
.
setResetCenter
(
selectedStrategyIndex
,
this
.
resetCenter
);
break
;
}
}
if
(
gd
.
wasOKed
())
return
0
;
return
1
;
// "Done" selected
}
public
class
FieldStrategies
{
ArrayList
<
FieldSrategy
>
strategies
=
new
ArrayList
<
FieldSrategy
>();
public
void
setProperties
(
String
prefix
,
Properties
properties
){
properties
.
setProperty
(
prefix
+
"strategies_length"
,
strategies
.
size
()+
""
);
for
(
int
i
=
0
;
i
<
strategies
.
size
();
i
++){
FieldSrategy
strategy
=
strategies
.
get
(
i
);
if
(
strategy
!=
null
)
strategy
.
setProperties
(
prefix
+
"strategy_"
+
i
+
"_"
,
properties
);
}
}
public
void
getProperties
(
String
prefix
,
Properties
properties
){
strategies
=
new
ArrayList
<
FieldSrategy
>();
String
s
=
properties
.
getProperty
(
prefix
+
"strategies_length"
);
if
(
s
!=
null
)
{
int
len
=
Integer
.
parseInt
(
s
);
for
(
int
i
=
0
;
i
<
len
;
i
++){
FieldSrategy
strategy
=
new
FieldSrategy
();
// compatibility with old version
if
(
properties
.
getProperty
(
prefix
+
"strategy_"
+
i
+
"_"
+
"centerSelect"
)!=
null
){
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Restoring new format strategy #"
+
i
);
strategy
.
getProperties
(
prefix
+
"strategy_"
+
i
+
"_"
,
properties
);
}
else
if
(
properties
.
getProperty
(
prefix
+
"_"
+
i
+
"_"
+
"centerSelect"
)!=
null
){
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Restoring old format strategy #"
+
i
);
strategy
.
getProperties
(
prefix
+
"_"
+
i
+
"_"
,
properties
);
}
else
{
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"No info for the field LMA strategy #"
+
i
);
}
strategies
.
add
(
strategy
);
}
}
}
public
int
getNumStrategies
(){
return
strategies
.
size
();
}
public
void
getFromStrategy
(
// any of the arguments can be null - do not set this array
int
strategyIndex
,
FieldFitting
fieldFitting
){
strategies
.
get
(
strategyIndex
).
getFromStrategy
(
// any of the arguments can be null - do not set this array
fieldFitting
.
centerSelect
,
fieldFitting
.
channelSelect
,
fieldFitting
.
mechanicalSelect
,
fieldFitting
.
curvatureSelect
,
fieldFitting
.
sampleCorrSelect
,
fieldFitting
.
sampleCorrCost
,
fieldFitting
.
sampleCorrSigma
,
fieldFitting
.
sampleCorrPullZero
);
}
public
void
setStrategy
(
// any of the arguments can be null - do not set this array
int
strategyIndex
,
FieldFitting
fieldFitting
){
strategies
.
get
(
strategyIndex
).
setStrategy
(
// any of the arguments can be null - do not set this array
fieldFitting
.
centerSelect
,
fieldFitting
.
channelSelect
,
fieldFitting
.
mechanicalSelect
,
fieldFitting
.
curvatureSelect
,
fieldFitting
.
sampleCorrSelect
,
fieldFitting
.
sampleCorrCost
,
fieldFitting
.
sampleCorrSigma
,
fieldFitting
.
sampleCorrPullZero
);
}
public
double
getInitialLambda
(
int
strategyIndex
)
{
return
strategies
.
get
(
strategyIndex
).
getInitialLambda
();
}
public
void
setInitialLambda
(
int
strategyIndex
,
double
initialLambda
)
{
strategies
.
get
(
strategyIndex
).
setInitialLambda
(
initialLambda
);
}
public
boolean
isStopAfterThis
(
int
strategyIndex
)
{
return
strategies
.
get
(
strategyIndex
).
isStopAfterThis
();
}
public
boolean
isResetCorrection
(
int
strategyIndex
)
{
return
strategies
.
get
(
strategyIndex
).
isResetCorrection
();
}
public
boolean
isResetCenter
(
int
strategyIndex
)
{
return
strategies
.
get
(
strategyIndex
).
isResetCenter
();
}
public
boolean
isLast
(
int
strategyIndex
)
{
if
(
strategyIndex
<
0
)
return
true
;
if
(
strategyIndex
>=(
getNumStrategies
()-
1
))
return
true
;
// last
return
isStopAfterThis
(
strategyIndex
);
}
public
void
setStopAfterThis
(
int
strategyIndex
,
boolean
stopAfterThis
)
{
strategies
.
get
(
strategyIndex
).
setStopAfterThis
(
stopAfterThis
);
}
public
void
setResetCorrection
(
int
strategyIndex
,
boolean
resetCorrection
)
{
strategies
.
get
(
strategyIndex
).
setResetCorrection
(
resetCorrection
);
}
public
void
setResetCenter
(
int
strategyIndex
,
boolean
resetCenter
)
{
strategies
.
get
(
strategyIndex
).
setResetCenter
(
resetCenter
);
}
public
String
getComment
(
int
strategyIndex
){
return
strategies
.
get
(
strategyIndex
).
getComment
();
}
public
void
setComment
(
int
strategyIndex
,
String
comment
){
strategies
.
get
(
strategyIndex
).
setComment
(
comment
);
}
public
void
insertStrategy
(
int
strategyIndex
){
strategies
.
add
(
strategyIndex
,
new
FieldSrategy
());
}
public
void
removeStrategy
(
int
strategyIndex
){
strategies
.
remove
(
strategyIndex
);
}
public
void
addStrategy
(){
strategies
.
add
(
new
FieldSrategy
());
}
public
void
saveStrategies
(
String
path
,
// full path w/o extension or null
String
directory
){
String
[]
patterns
=
{
".fstg-xml"
,
".xml"
};
if
(
path
==
null
)
{
path
=
CalibrationFileManagement
.
selectFile
(
true
,
// save
"Save Field LMA Strategy selection"
,
// title
"Select Field LMA Strategy file"
,
// button
new
CalibrationFileManagement
.
MultipleExtensionsFileFilter
(
patterns
,
"Strategy files (*.fstg-xml)"
),
// filter
directory
);
// may be ""
}
else
path
+=
patterns
[
0
];
if
(
path
==
null
)
return
;
Properties
properties
=
new
Properties
();
setProperties
(
""
,
properties
);
// no prefix
OutputStream
os
;
try
{
os
=
new
FileOutputStream
(
path
);
}
catch
(
FileNotFoundException
e1
)
{
IJ
.
showMessage
(
"Error"
,
"Failed to open field LMA strategy file for writing: "
+
path
);
return
;
}
try
{
properties
.
storeToXML
(
os
,
"last updated "
+
new
java
.
util
.
Date
(),
"UTF8"
);
}
catch
(
IOException
e
)
{
IJ
.
showMessage
(
"Error"
,
"Failed to write XML configuration file: "
+
path
);
return
;
}
try
{
os
.
close
();
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Field LMA strategy parameters are saved to "
+
path
);
}
public
void
loadStrategies
(
String
path
,
// full path w/o extension or null
String
directory
){
String
[]
patterns
=
{
".fstg-xml"
,
".xml"
};
if
(
path
==
null
)
{
path
=
CalibrationFileManagement
.
selectFile
(
false
,
// save
"Field LMA Strategy selection"
,
// title
"Select Field LMA Strategy file"
,
// button
new
CalibrationFileManagement
.
MultipleExtensionsFileFilter
(
patterns
,
"Strategy files (*.fstg-xml)"
),
// filter
directory
);
// may be ""
}
else
{
// do not add extension if it already exists
if
((
path
.
length
()<
patterns
[
0
].
length
())
||
(!
path
.
substring
(
path
.
length
()-
patterns
[
0
].
length
()).
equals
(
patterns
[
0
]))){
path
+=
patterns
[
0
];
}
}
if
(
path
==
null
)
return
;
InputStream
is
;
try
{
is
=
new
FileInputStream
(
path
);
}
catch
(
FileNotFoundException
e
)
{
IJ
.
showMessage
(
"Error"
,
"Failed to open field LMA strategy file: "
+
path
);
return
;
}
Properties
properties
=
new
Properties
();
try
{
properties
.
loadFromXML
(
is
);
}
catch
(
IOException
e
)
{
IJ
.
showMessage
(
"Error"
,
"Failed to read field LMA strategy file: "
+
path
);
return
;
}
try
{
is
.
close
();
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
getProperties
(
""
,
properties
);
// no prefix
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Field LMA strategy parameters are restored from "
+
path
);
}
class
FieldSrategy
{
private
boolean
[]
centerSelect
=
null
;
private
boolean
[]
channelSelect
=
null
;
private
boolean
[]
mechanicalSelect
=
null
;
private
boolean
[][]
curvatureSelect
=
new
boolean
[
6
][];
private
boolean
[][]
sampleCorrSelect
=
new
boolean
[
6
][];
// enable individual (per sample coordinates) correction of parameters
private
double
[][]
sampleCorrCost
=
new
double
[
6
][];
// equivalent cost of one unit of parameter value (in result units, um)
private
double
[][]
sampleCorrSigma
=
new
double
[
6
][];
// sigma (in mm) for neighbors influence
private
double
[][]
sampleCorrPullZero
=
new
double
[
6
][];
// 1.0 - only difference from neighbors matters, 0.0 - only difference from 0
// TODO: add LMA-specific (initial lambda, stop after this
private
double
initialLambda
=
0.001
;
private
boolean
stopAfterThis
=
true
;
private
boolean
resetCorrection
=
false
;
private
boolean
resetCenter
=
false
;
private
String
strategyComment
=
""
;
private
Properties
properties
=
null
;
private
String
prefix
=
null
;
public
FieldSrategy
(){
setDefaults
();
}
public
FieldSrategy
(
String
strategyComment
,
double
lambda
,
boolean
lastInSeries
,
boolean
resetCorrection
,
boolean
resetCenter
){
this
.
strategyComment
=
strategyComment
;
initialLambda
=
lambda
;
stopAfterThis
=
lastInSeries
;
this
.
resetCorrection
=
resetCorrection
;
this
.
resetCenter
=
resetCenter
;
setDefaults
();
}
private
void
setDefaults
(){
boolean
[][]
booleanNull6
={
null
,
null
,
null
,
null
,
null
,
null
};
double
[][]
doubleNull6
=
{
null
,
null
,
null
,
null
,
null
,
null
};
curvatureSelect
=
booleanNull6
.
clone
();
sampleCorrSelect
=
booleanNull6
.
clone
();
sampleCorrCost
=
doubleNull6
.
clone
();
sampleCorrSigma
=
doubleNull6
.
clone
();
sampleCorrPullZero
=
doubleNull6
.
clone
();
}
private
String
boolToStr
(
boolean
[]
ba
){
if
(
ba
==
null
)
return
""
;
String
result
=
""
;
for
(
boolean
b
:
ba
)
result
+=
b
?
"+"
:
"-"
;
return
result
;
}
private
void
setPropBool
(
boolean
[]
arr
,
String
name
){
if
(
arr
!=
null
)
properties
.
setProperty
(
prefix
+
name
,
boolToStr
(
arr
));
}
private
void
setPropBool
(
boolean
[][]
arr
,
String
name
){
if
(
arr
!=
null
)
{
properties
.
setProperty
(
prefix
+
name
+
"_length"
,
arr
.
length
+
""
);
for
(
int
i
=
0
;
i
<
arr
.
length
;
i
++)
{
setPropBool
(
arr
[
i
],
name
+
"_"
+
i
);
}
}
}
private
void
setPropDouble
(
double
[]
arr
,
String
name
){
if
(
arr
!=
null
)
properties
.
setProperty
(
prefix
+
name
,
doubleToStr
(
arr
));
}
private
void
setPropDouble
(
double
[][]
arr
,
String
name
){
if
(
arr
!=
null
)
{
properties
.
setProperty
(
prefix
+
name
+
"_length"
,
arr
.
length
+
""
);
for
(
int
i
=
0
;
i
<
arr
.
length
;
i
++)
{
setPropDouble
(
arr
[
i
],
name
+
"_"
+
i
);
}
}
}
private
boolean
[]
strToBool
(
String
s
){
if
(
s
==
null
)
return
new
boolean
[
0
];
boolean
[]
result
=
new
boolean
[
s
.
length
()];
for
(
int
i
=
0
;
i
<
result
.
length
;
i
++)
result
[
i
]=(
s
.
charAt
(
i
)==
'+'
);
return
result
;
}
private
String
doubleToStr
(
double
[]
da
){
if
(
da
==
null
)
return
""
;
String
result
=
""
;
for
(
double
d
:
da
)
result
+=
","
+
d
;
if
(
result
.
length
()>
0
)
result
=
result
.
substring
(
1
);
return
result
;
}
private
double
[]
strToDouble
(
String
s
){
if
(
s
==
null
)
return
new
double
[
0
];
String
[]
sa
=
s
.
split
(
","
);
double
[]
result
=
new
double
[
sa
.
length
];
for
(
int
i
=
0
;
i
<
result
.
length
;
i
++)
result
[
i
]=
Double
.
parseDouble
(
sa
[
i
]);
return
result
;
}
private
boolean
[]
getPropBool
(
boolean
[]
arr
,
String
name
){
String
s
=
properties
.
getProperty
(
prefix
+
name
);
if
(
s
!=
null
)
return
strToBool
(
s
);
else
return
arr
;
}
private
boolean
[][]
getPropBool
(
boolean
[][]
arr
,
String
name
){
if
(
arr
==
null
){
String
s
=
properties
.
getProperty
(
prefix
+
name
+
"_length"
);
if
(
s
==
null
)
return
null
;
arr
=
new
boolean
[
Integer
.
parseInt
(
s
)][];
for
(
int
i
=
0
;
i
<
arr
.
length
;
i
++)
arr
[
i
]=
null
;
}
for
(
int
i
=
0
;
i
<
arr
.
length
;
i
++){
boolean
[]
a
=
getPropBool
((
boolean
[])
null
,
name
+
"_"
+
i
);
if
(
a
!=
null
)
arr
[
i
]=
a
;
}
return
arr
;
}
private
double
[]
getPropDouble
(
double
[]
arr
,
String
name
){
String
s
=
properties
.
getProperty
(
prefix
+
name
);
if
(
s
!=
null
)
return
strToDouble
(
s
);
else
return
arr
;
}
private
double
[][]
getPropDouble
(
double
[][]
arr
,
String
name
){
if
(
arr
==
null
){
String
s
=
properties
.
getProperty
(
prefix
+
name
+
"_length"
);
if
(
s
==
null
)
return
null
;
arr
=
new
double
[
Integer
.
parseInt
(
s
)][];
for
(
int
i
=
0
;
i
<
arr
.
length
;
i
++)
arr
[
i
]=
null
;
}
for
(
int
i
=
0
;
i
<
arr
.
length
;
i
++){
double
[]
a
=
getPropDouble
((
double
[])
null
,
name
+
"_"
+
i
);
if
(
a
!=
null
)
arr
[
i
]=
a
;
}
return
arr
;
}
public
String
getComment
(){
return
strategyComment
;
}
public
void
setComment
(
String
comment
){
strategyComment
=
comment
;
}
public
double
getInitialLambda
()
{
return
initialLambda
;
}
public
void
setInitialLambda
(
double
initialLambda
)
{
this
.
initialLambda
=
initialLambda
;
}
public
boolean
isStopAfterThis
()
{
return
stopAfterThis
;
}
public
void
setStopAfterThis
(
boolean
stopAfterThis
)
{
this
.
stopAfterThis
=
stopAfterThis
;
}
public
boolean
isResetCorrection
()
{
return
resetCorrection
;
}
public
void
setResetCorrection
(
boolean
resetCorrection
)
{
this
.
resetCorrection
=
resetCorrection
;
}
public
boolean
isResetCenter
()
{
return
resetCenter
;
}
public
void
setResetCenter
(
boolean
resetCenter
)
{
this
.
resetCenter
=
resetCenter
;
}
public
void
setStrategy
(
// any of the arguments can be null - do not set this array
boolean
[]
centerSelect
,
boolean
[]
channelSelect
,
boolean
[]
mechanicalSelect
,
boolean
[][]
curvatureSelect
,
boolean
[][]
sampleCorrSelect
,
double
[][]
sampleCorrCost
,
double
[][]
sampleCorrSigma
,
double
[][]
sampleCorrPullZero
){
if
(
centerSelect
!=
null
)
this
.
centerSelect
=
centerSelect
.
clone
();
if
(
channelSelect
!=
null
)
this
.
channelSelect
=
channelSelect
.
clone
();
if
(
mechanicalSelect
!=
null
)
this
.
mechanicalSelect
=
mechanicalSelect
.
clone
();
if
(
curvatureSelect
!=
null
)
{
this
.
curvatureSelect
=
new
boolean
[
curvatureSelect
.
length
][];
for
(
int
i
=
0
;
i
<
curvatureSelect
.
length
;
i
++)
this
.
curvatureSelect
[
i
]=
curvatureSelect
[
i
].
clone
();
}
if
(
sampleCorrSelect
!=
null
)
{
this
.
sampleCorrSelect
=
new
boolean
[
sampleCorrSelect
.
length
][];
for
(
int
i
=
0
;
i
<
sampleCorrSelect
.
length
;
i
++)
this
.
sampleCorrSelect
[
i
]=
sampleCorrSelect
[
i
].
clone
();
}
if
(
sampleCorrCost
!=
null
)
{
this
.
sampleCorrCost
=
new
double
[
sampleCorrCost
.
length
][];
for
(
int
i
=
0
;
i
<
sampleCorrCost
.
length
;
i
++)
this
.
sampleCorrCost
[
i
]=
sampleCorrCost
[
i
].
clone
();
}
if
(
sampleCorrSigma
!=
null
)
{
this
.
sampleCorrSigma
=
new
double
[
sampleCorrSigma
.
length
][];
for
(
int
i
=
0
;
i
<
sampleCorrSigma
.
length
;
i
++)
this
.
sampleCorrSigma
[
i
]=
sampleCorrSigma
[
i
].
clone
();
}
if
(
sampleCorrPullZero
!=
null
)
{
this
.
sampleCorrPullZero
=
new
double
[
sampleCorrPullZero
.
length
][];
for
(
int
i
=
0
;
i
<
sampleCorrPullZero
.
length
;
i
++)
this
.
sampleCorrPullZero
[
i
]=
sampleCorrPullZero
[
i
].
clone
();
}
}
public
void
getFromStrategy
(
// any of the arguments can be null - do not set this array
boolean
[]
centerSelect
,
boolean
[]
channelSelect
,
boolean
[]
mechanicalSelect
,
boolean
[][]
curvatureSelect
,
boolean
[][]
sampleCorrSelect
,
double
[][]
sampleCorrCost
,
double
[][]
sampleCorrSigma
,
double
[][]
sampleCorrPullZero
){
if
(
centerSelect
!=
null
)
for
(
int
i
=
0
;
i
<
centerSelect
.
length
;
i
++)
centerSelect
[
i
]=
this
.
centerSelect
[
i
];
if
(
channelSelect
!=
null
)
for
(
int
i
=
0
;
i
<
channelSelect
.
length
;
i
++)
channelSelect
[
i
]=
this
.
channelSelect
[
i
];
if
(
mechanicalSelect
!=
null
)
for
(
int
i
=
0
;
i
<
mechanicalSelect
.
length
;
i
++)
mechanicalSelect
[
i
]=
this
.
mechanicalSelect
[
i
];
if
(
curvatureSelect
!=
null
)
{
for
(
int
i
=
0
;
i
<
curvatureSelect
.
length
;
i
++)
curvatureSelect
[
i
]=
this
.
curvatureSelect
[
i
].
clone
();
}
if
(
sampleCorrSelect
!=
null
)
{
for
(
int
i
=
0
;
i
<
sampleCorrSelect
.
length
;
i
++)
sampleCorrSelect
[
i
]=
this
.
sampleCorrSelect
[
i
].
clone
();
}
if
(
sampleCorrCost
!=
null
)
{
for
(
int
i
=
0
;
i
<
sampleCorrCost
.
length
;
i
++)
sampleCorrCost
[
i
]=
this
.
sampleCorrCost
[
i
].
clone
();
}
if
(
sampleCorrSigma
!=
null
)
{
for
(
int
i
=
0
;
i
<
sampleCorrSigma
.
length
;
i
++)
sampleCorrSigma
[
i
]=
this
.
sampleCorrSigma
[
i
].
clone
();
}
if
(
sampleCorrPullZero
!=
null
)
{
for
(
int
i
=
0
;
i
<
sampleCorrPullZero
.
length
;
i
++)
sampleCorrPullZero
[
i
]=
this
.
sampleCorrPullZero
[
i
].
clone
();
}
}
public
void
setProperties
(
String
prefix
,
Properties
properties
){
this
.
prefix
=
prefix
;
this
.
properties
=
properties
;
setPropBool
(
centerSelect
,
"centerSelect"
);
setPropBool
(
channelSelect
,
"channelSelect"
);
setPropBool
(
mechanicalSelect
,
"mechanicalSelect"
);
setPropBool
(
curvatureSelect
,
"curvatureSelect"
);
setPropBool
(
sampleCorrSelect
,
"sampleCorrSelect"
);
setPropDouble
(
sampleCorrCost
,
"sampleCorrCost"
);
setPropDouble
(
sampleCorrSigma
,
"sampleCorrSigma"
);
setPropDouble
(
sampleCorrPullZero
,
"sampleCorrPullZero"
);
properties
.
setProperty
(
prefix
+
"initialLambda"
,
getInitialLambda
()+
""
);
properties
.
setProperty
(
prefix
+
"stopAfterThis"
,
isStopAfterThis
()+
""
);
properties
.
setProperty
(
prefix
+
"resetCorrection"
,
isResetCorrection
()+
""
);
properties
.
setProperty
(
prefix
+
"resetCenter"
,
isResetCenter
()+
""
);
properties
.
setProperty
(
prefix
+
"strategyComment"
,
"<![CDATA["
+
strategyComment
+
"]]>"
);
}
public
void
getProperties
(
String
prefix
,
Properties
properties
){
this
.
prefix
=
prefix
;
this
.
properties
=
properties
;
centerSelect
=
getPropBool
(
centerSelect
,
"centerSelect"
);
channelSelect
=
getPropBool
(
channelSelect
,
"channelSelect"
);
mechanicalSelect
=
getPropBool
(
mechanicalSelect
,
"mechanicalSelect"
);
curvatureSelect
=
getPropBool
(
curvatureSelect
,
"curvatureSelect"
);
sampleCorrSelect
=
getPropBool
(
sampleCorrSelect
,
"sampleCorrSelect"
);
sampleCorrCost
=
getPropDouble
(
sampleCorrCost
,
"sampleCorrCost"
);
sampleCorrSigma
=
getPropDouble
(
sampleCorrSigma
,
"sampleCorrSigma"
);
sampleCorrPullZero
=
getPropDouble
(
sampleCorrPullZero
,
"sampleCorrPullZero"
);
String
s
=
properties
.
getProperty
(
prefix
+
"initialLambda"
);
if
(
s
!=
null
)
initialLambda
=
Double
.
parseDouble
(
s
);
s
=
properties
.
getProperty
(
prefix
+
"stopAfterThis"
);
if
(
s
!=
null
)
stopAfterThis
=
Boolean
.
parseBoolean
(
s
);
s
=
properties
.
getProperty
(
prefix
+
"resetCorrection"
);
if
(
s
!=
null
)
resetCorrection
=
Boolean
.
parseBoolean
(
s
);
s
=
properties
.
getProperty
(
prefix
+
"resetCenter"
);
if
(
s
!=
null
)
resetCenter
=
Boolean
.
parseBoolean
(
s
);
s
=
properties
.
getProperty
(
prefix
+
"strategyComment"
);
if
(
s
!=
null
){
strategyComment
=
s
;
if
((
strategyComment
.
length
()>
10
)
&&
strategyComment
.
substring
(
0
,
9
).
equals
(
"<![CDATA["
))
{
strategyComment
=
strategyComment
.
substring
(
9
,
strategyComment
.
length
()-
3
);
}
}
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment