Commit 1893ac24 authored by Andrey Filippov's avatar Andrey Filippov

Working, before adding low-elevation*alpha losses

parent 9a499c0a
......@@ -31,6 +31,7 @@ import java.util.StringTokenizer;
import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.orthomosaic.ComboMatch;
import com.elphel.imagej.vegetation.VegetationLMA;
public class IntersceneMatchParameters {
public static String [] MODES3D = {"RAW", "INF", "FG", "BG"}; // RAW:-1
......@@ -755,6 +756,8 @@ min_str_neib_fpn 0.35
public boolean terr_fit_alpha = true; // adjust vegetation alpha pixels
public boolean terr_fit_scenes = true; // adjust scene offsets (start from 0 always?)
public boolean terr_fit_elevations = false; // adjust elevation pixels (not yet implemented)
public boolean [] terr_fit_disable = new boolean [VegetationLMA.TVAO_TYPES];
public double terr_max_warp = 1.8;
public int terr_max_elevation = 22; // maximal offset to consider when looking for vegetation influence
......@@ -807,12 +810,21 @@ min_str_neib_fpn 0.35
public double terr_hifreq_weight = 10.0; // 22.5; // 0 - do not use high-freq. Relative weight of laplacian components differfences to the DC ones
public double terr_terr_corr = 1.0; // relative weight of average mismatch between images and model (terrain corrections)
public double terr_reg_weights = 0.25; // fraction of the total weight used for regularization
public double terr_lambda = 5.0; //
public double terr_lambda_scale_good = 0.5;
public double terr_lambda_scale_bad = 8.0;
public double terr_lambda_max = 1000;
public double terr_rms_diff = 1e-8; // 0.0001; virtually forever
public int terr_num_iter = 25; // 100;
// second run
public boolean terr_recalc_weights = false; // recalculate weight depending on terrain visibility
public double terr_recalc_opaque = 0.9; // above is opaque
public double terr_recalc_pedestal = 0.05; // weight of opaque tiles
public double terr_recalc_frac = 0.5; // discard transparency below this fraction of the maximal one
public double terr_recalc_dist = 1.0; // increase weight for far pixels (double if scale differece == this)
public boolean terr_recalc_average = false; // apply transparency to average mismatch
// combine parameters
public int terr_border_width = 6;
......@@ -2048,8 +2060,10 @@ min_str_neib_fpn 0.35
gd.addCheckbox ("Adjust vegetation", terr_fit_veget, "Adjust vegetation pixels.");
gd.addCheckbox ("Adjust alpha", terr_fit_alpha, "Adjust vegetation alpha pixels.");
gd.addCheckbox ("Adjust scene offsets", terr_fit_scenes, "Adjust scene offsets (start from 0 always?).");
gd.addCheckbox ("Adjust elevation", terr_fit_elevations,"Adjust elevation pixels (not yet implemented).");
gd.addCheckbox ("Adjust elevation", terr_fit_elevations,"Adjust elevation pixels.");
for (int i = 0; i < terr_fit_disable.length; i++) {
gd.addCheckbox ("Skip "+VegetationLMA.TVAO_NAMES[i], terr_fit_disable[i],"Skip adjustment of "+VegetationLMA.TVAO_NAMES[i]+".");
}
gd.addNumericField("Maximal warp", terr_max_warp, 5,7,"pix", "(1.8) Do not use scenes where distance between vegetation projection exceeds this.");
gd.addNumericField("Min elevation/offset", terr_max_elevation, 0,3,"pix","Maximal offset to consider when looking for vegetation influence.");
......@@ -2100,7 +2114,16 @@ min_str_neib_fpn 0.35
gd.addNumericField("Lambda scale on bad", terr_lambda_scale_bad, 5,7,"","Scale lambda if RMSE worsened.");
gd.addNumericField("Lambda max to fail", terr_lambda_max, 5,7,"", "Fail if lambda gets larger than that.");
gd.addNumericField("RMSE difference", terr_rms_diff, 10,12,"", "Exit if RMSE improvement is lower.");
gd.addNumericField("(Maximal) iterations", terr_num_iter, 0,3,"", "Maximal number of LMA iterations.");
gd.addNumericField("Maximal iterations", terr_num_iter, 0,3,"", "Maximal number of LMA iterations.");
gd.addMessage ("Second LMA run");
gd.addCheckbox ("Recalculate weighths", terr_recalc_weights, "Recalculate weights depending on terrain visibility.");
gd.addNumericField("Opaque alpha", terr_recalc_opaque, 5,7,"", "Alpha above his means opaque.");
gd.addNumericField("Opaque weight", terr_recalc_pedestal, 5,7,"","Relative weight of opaque tiles.");
gd.addNumericField("Transparency fraction",terr_recalc_frac, 5,7,"","Discard transparency below this fraction of the maximal one.");
gd.addNumericField("Transparency distance",terr_recalc_dist, 5,7,"","Increase weight for far pixels (double if scale differece == this).");
gd.addCheckbox ("Transparency average", terr_recalc_average, "Apply transparency to average mismatch.");
gd.addMessage ("Combining LMA results segments");
gd.addNumericField("Overlap width", terr_border_width, 0,3,"","Width of the inter-tile oiverlap border.");
......@@ -2774,6 +2797,10 @@ min_str_neib_fpn 0.35
terr_fit_scenes = gd.getNextBoolean();// boolean
terr_fit_elevations = gd.getNextBoolean();// boolean
for (int i = 0; i < terr_fit_disable.length; i++) {
terr_fit_disable[i] = gd.getNextBoolean();// boolean
}
terr_max_warp = gd.getNextNumber();// double
terr_max_elevation = (int) gd.getNextNumber();// int
......@@ -2820,15 +2847,22 @@ min_str_neib_fpn 0.35
terr_rms_diff = gd.getNextNumber();// double
terr_num_iter = (int) gd.getNextNumber();// int
terr_border_width = (int) gd.getNextNumber();// int
terr_recalc_weights = gd.getNextBoolean();// boolean
terr_recalc_opaque = gd.getNextNumber(); // double
terr_recalc_pedestal = gd.getNextNumber(); // double
terr_recalc_frac = gd.getNextNumber(); // double
terr_recalc_dist = gd.getNextNumber(); // double
terr_recalc_average = gd.getNextBoolean();// boolean
terr_border_width = (int) gd.getNextNumber(); // int
terr_render_open = gd.getNextBoolean();// boolean
terr_render_no_alpha = gd.getNextBoolean();// boolean
terr_alpha_min = gd.getNextNumber();// double
terr_alpha_max = gd.getNextNumber();// double
terr_weight_opaque = gd.getNextNumber();// double
terr_boost_render = gd.getNextNumber();// double
terr_max_render = gd.getNextNumber();// double
terr_num_exaggerate = (int)gd.getNextNumber();// int
terr_alpha_min = gd.getNextNumber(); // double
terr_alpha_max = gd.getNextNumber(); // double
terr_weight_opaque = gd.getNextNumber(); // double
terr_boost_render = gd.getNextNumber(); // double
terr_max_render = gd.getNextNumber(); // double
terr_num_exaggerate = (int)gd.getNextNumber(); // int
terr_threshold_terrain = gd.getNextNumber();// double
terr_min_max_terrain = gd.getNextNumber();// double
......@@ -3463,7 +3497,10 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"terr_fit_alpha", terr_fit_alpha+""); // boolean
properties.setProperty(prefix+"terr_fit_scenes", terr_fit_scenes+""); // boolean
properties.setProperty(prefix+"terr_fit_elevations", terr_fit_elevations+""); // boolean
for (int i = 0; i < terr_fit_disable.length; i++) {
String prop_name = prefix+"terr_fit_disable_"+VegetationLMA.TVAO_NAMES[i];
properties.setProperty(prop_name, terr_fit_disable[i]+""); // boolean
}
properties.setProperty(prefix+"terr_max_warp", terr_max_warp+""); // double
properties.setProperty(prefix+"terr_max_elevation", terr_max_elevation+""); // int
properties.setProperty(prefix+"terr_min_scenes", terr_min_scenes+""); // int
......@@ -3509,6 +3546,13 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"terr_rms_diff", terr_rms_diff+""); // double
properties.setProperty(prefix+"terr_num_iter", terr_num_iter+""); // int
properties.setProperty(prefix+"terr_recalc_weights", terr_recalc_weights+""); // boolean
properties.setProperty(prefix+"terr_recalc_opaque", terr_recalc_opaque+""); // double
properties.setProperty(prefix+"terr_recalc_pedestal", terr_recalc_pedestal+""); // double
properties.setProperty(prefix+"terr_recalc_frac", terr_recalc_frac+""); // double
properties.setProperty(prefix+"terr_recalc_dist", terr_recalc_dist+""); // double
properties.setProperty(prefix+"terr_recalc_average", terr_recalc_average+""); // boolean
properties.setProperty(prefix+"terr_border_width", terr_border_width+""); // int
properties.setProperty(prefix+"terr_render_open", terr_render_open+""); // boolean
properties.setProperty(prefix+"terr_render_no_alpha", terr_render_no_alpha+""); // boolean
......@@ -4170,7 +4214,10 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"terr_fit_alpha")!= null) terr_fit_alpha=Boolean.parseBoolean(properties.getProperty(prefix+"terr_fit_alpha"));
if (properties.getProperty(prefix+"terr_fit_scenes")!= null) terr_fit_scenes=Boolean.parseBoolean(properties.getProperty(prefix+"terr_fit_scenes"));
if (properties.getProperty(prefix+"terr_fit_elevations")!= null) terr_fit_elevations=Boolean.parseBoolean(properties.getProperty(prefix+"terr_fit_elevations"));
for (int i = 0; i < terr_fit_disable.length; i++) {
String prop_name = prefix+"terr_fit_disable_"+VegetationLMA.TVAO_NAMES[i];
if (properties.getProperty(prop_name)!= null) terr_fit_disable[i]=Boolean.parseBoolean(properties.getProperty(prop_name));
}
if (properties.getProperty(prefix+"terr_max_warp")!= null) terr_max_warp=Double.parseDouble(properties.getProperty(prefix+"terr_max_warp"));
if (properties.getProperty(prefix+"terr_max_elevation")!= null) terr_max_elevation=Integer.parseInt(properties.getProperty(prefix+"terr_max_elevation"));
if (properties.getProperty(prefix+"terr_min_scenes")!= null) terr_min_scenes=Integer.parseInt(properties.getProperty(prefix+"terr_min_scenes"));
......@@ -4217,6 +4264,13 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"terr_rms_diff")!= null) terr_rms_diff=Double.parseDouble(properties.getProperty(prefix+"terr_rms_diff"));
if (properties.getProperty(prefix+"terr_num_iter")!= null) terr_num_iter=Integer.parseInt(properties.getProperty(prefix+"terr_num_iter"));
if (properties.getProperty(prefix+"terr_recalc_weights")!= null) terr_recalc_weights=Boolean.parseBoolean(properties.getProperty(prefix+"terr_recalc_weights"));
if (properties.getProperty(prefix+"terr_recalc_opaque")!= null) terr_recalc_opaque=Double.parseDouble(properties.getProperty(prefix+"terr_recalc_opaque"));
if (properties.getProperty(prefix+"terr_recalc_pedestal")!= null) terr_recalc_pedestal=Double.parseDouble(properties.getProperty(prefix+"terr_recalc_pedestal"));
if (properties.getProperty(prefix+"terr_recalc_frac")!= null) terr_recalc_frac=Double.parseDouble(properties.getProperty(prefix+"terr_recalc_frac"));
if (properties.getProperty(prefix+"terr_recalc_dist")!= null) terr_recalc_dist=Double.parseDouble(properties.getProperty(prefix+"terr_recalc_dist"));
if (properties.getProperty(prefix+"terr_recalc_average")!= null) terr_recalc_average=Boolean.parseBoolean(properties.getProperty(prefix+"terr_recalc_average"));
if (properties.getProperty(prefix+"terr_border_width")!= null) terr_border_width=Integer.parseInt(properties.getProperty(prefix+"terr_border_width"));
if (properties.getProperty(prefix+"terr_render_open")!= null) terr_render_open=Boolean.parseBoolean(properties.getProperty(prefix+"terr_render_open"));
if (properties.getProperty(prefix+"terr_render_no_alpha")!= null) terr_render_no_alpha=Boolean.parseBoolean(properties.getProperty(prefix+"terr_render_no_alpha"));
......@@ -4847,7 +4901,7 @@ min_str_neib_fpn 0.35
imp.terr_fit_alpha = this.terr_fit_alpha;
imp.terr_fit_scenes = this.terr_fit_scenes;
imp.terr_fit_elevations = this.terr_fit_elevations;
imp.terr_fit_disable = this.terr_fit_disable.clone();
imp.terr_max_warp = this.terr_max_warp;
imp.terr_max_elevation = this.terr_max_elevation;
imp.terr_min_scenes = this.terr_min_scenes;
......@@ -4893,6 +4947,13 @@ min_str_neib_fpn 0.35
imp.terr_rms_diff = this.terr_rms_diff;
imp.terr_num_iter = this.terr_num_iter;
imp.terr_recalc_weights = this.terr_recalc_weights;
imp.terr_recalc_opaque = this.terr_recalc_opaque;
imp.terr_recalc_pedestal = this.terr_recalc_pedestal;
imp.terr_recalc_frac = this.terr_recalc_frac;
imp.terr_recalc_dist = this.terr_recalc_dist;
imp.terr_recalc_average = this.terr_recalc_average;
imp.terr_border_width = this.terr_border_width;
imp.terr_render_open = this.terr_render_open;
imp.terr_render_no_alpha = this.terr_render_no_alpha;
......
......@@ -29,6 +29,7 @@ import ij.io.FileSaver;
public class VegetationLMA {
public static final String PAR_EXT = ".par-tiff";
public static final String [] TVAO_NAMES = {"TERRAIN","VEGETATION","ALPHA","ELEVATION","SCENE_OFFSET"};
public static final int TVAO_TERRAIN = 0;
public static final int TVAO_VEGETATION = 1;
public static final int TVAO_ALPHA = 2;
......@@ -75,23 +76,31 @@ public class VegetationLMA {
private VegetationModel vegetationModel = null;
private int [][] par_index; // indices - [0..4][full_pixel] - same as for tvao, value - parameter index
private int [][] par_rindex; // parameter -> pair of type (0..4) and full window pixel index
private int num_pars_terrain;
private int num_pars_vegetation;
private int num_pars_alpha; //== num_pars_vegetation
private int num_pars_elevation; //== num_pars_vegetation
private int num_pars_scenes;
private int ind_pars_terrain = 0; // index of the first terrain parameter
private int ind_pars_vegetation; // index of the first vegetation parameter
private int ind_pars_alpha; // index of the first alpha parameter
private int ind_pars_elevation; // index of the first elevation parameter
private int ind_pars_scenes; // index of the first scene parameter
private int [] num_pars = new int [TVAO_TYPES];
private int [] ind_pars = new int [TVAO_TYPES]; // should be in increasing order?
/*
private int num_pars[TVAO_TERRAIN];
private int num_pars[TVAO_VEGETATION];
private int num_pars[TVAO_ALPHA]; //== num_pars[TVAO_VEGETATION]
private int num_pars[TVAO_ELEVATION]; //== num_pars[TVAO_VEGETATION]
private int num_pars[TVAO_SCENE_OFFSET];
private int ind_pars[TVAO_TERRAIN] = 0; // index of the first terrain parameter
private int ind_pars[TVAO_VEGETATION]; // index of the first vegetation parameter
private int ind_pars[TVAO_ALPHA]; // index of the first alpha parameter
private int ind_pars[TVAO_ELEVATION]; // index of the first elevation parameter
private int ind_pars[TVAO_SCENE_OFFSET]; // index of the first scene parameter
*/
private int [][] y_src; // data pointers for y-vector
private int [][] y_src_hf; // subset of pointers that have all 4 neighbors
private int [][] y_src_scene; // [scene]{start_y_src, end_y_src+1} pointers to y_src per scene
private int [][] y_wsrc; // [scene][windex] ysrc index for scene, windex [num_scenes][woi_length]
// private double [] y_wavg; // [woi_length] - weighted average of y-values over woi
private double terrain_correction;// weight of y_wavg
private double terrain_correction_weight = 1.0;
private double weight_to_scene_weight = 1;
private boolean recalc_average = false; //apply transparency to average mismatch
private int [][] samples_pointers; // {start,length} for each samples section, for extra 3-rd is ind_pars_*
......@@ -131,6 +140,7 @@ public class VegetationLMA {
// @Deprecated
// private double terr_pull_cold = 0; // pull vegetations to warm, terrain to cold
private boolean [] fits_disable; //
// Parameters saved/resored in a file
private final int num_scenes; // (+)
......@@ -165,9 +175,11 @@ public class VegetationLMA {
private double scale_scenes_pull = 0; // (*) used in getFxDerivs to scale scene offsets as their weight will be reg_weights / extra_samples
public double boost_parallax = 1; // (+)
// data used to calculate lpf pull of the alpha pixel to average of four neighbors. Below similar (weaker pull) for terrain and vegetation
// to smooth areas where there is no data from available images.
public int [][] alpha_neibs; // corresponds to parameters for alpha (num_pars_vegetation_alpha), each has 4 ortho neibs, -1 - border, >= 0
public int [][] alpha_neibs; // corresponds to parameters for alpha (num_pars[TVAO_VEGETATION]_alpha), each has 4 ortho neibs, -1 - border, >= 0
public int [][] terr_neibs; // corresponds to parameters for terrain, for smoothing undefined terrain, similar to alpha_neibs
public int [][] veget_neibs; // corresponds to parameters for vegetation, for smoothing undefined vegetation, similar to alpha_neibs
public int [][] elevation_neibs; // corresponds to parameters for elevation, for smoothing undefined elevations, similar to alpha_neibs
......@@ -399,7 +411,7 @@ public class VegetationLMA {
final boolean fit_alpha,
final boolean fit_scenes,
final boolean fit_elevations,
final boolean [] fits_disable,
final double reg_weights, // fraction of the total weight used for regularization
final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0
final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0
......@@ -433,7 +445,7 @@ public class VegetationLMA {
fits[TVAO_ALPHA] = fit_alpha;
fits[TVAO_SCENE_OFFSET] =fit_scenes;
fits[TVAO_ELEVATION] = fit_elevations;
this.fits_disable = fits_disable.clone();
this.reg_weights = reg_weights; // fraction of the total weight used for regularization
this.alpha_loss = alpha_loss;
this.alpha_offset = alpha_offset;
......@@ -594,49 +606,56 @@ public class VegetationLMA {
}
final double [] scene_weights = setupSceneWeights(
// final double [] scene_weights = //sets this.scene_weights too
double [] scene_weights0 = //sets this.scene_weights too
setupSceneWeights(
boost_parallax, // double boost_parallax)
woi, // Rectangle woi)
max_parallax); // final double ceil_parallax)
System.arraycopy( // this.scene_weights is final, so copy
scene_weights0,
0,
this.scene_weights,
0,
num_scenes);
setupParametersIndices(
fits, // boolean [] fits,
debugLevel); // final int debugLevel)
alpha_neibs = getNeighbors(
TVAO_ALPHA, // final int tvao, // TVAO_VEGETATION_ALPHA
ind_pars_alpha, // final int ind_samples, // ind_pars_vegetation_alpha
num_pars_alpha); // final int num_samples); // num_pars_vegetation_alpha
ind_pars[TVAO_ALPHA], // final int ind_samples, // ind_pars[TVAO_VEGETATION]_alpha
num_pars[TVAO_ALPHA]); // final int num_samples); // num_pars[TVAO_VEGETATION]_alpha
terr_neibs = getNeighbors(
TVAO_TERRAIN, // final int tvao, // TVAO_VEGETATION_ALPHA
ind_pars_terrain, // final int ind_samples, // ind_pars_vegetation_alpha
num_pars_terrain); // final int num_samples); // num_pars_vegetation_alpha
ind_pars[TVAO_TERRAIN], // final int ind_samples, // ind_pars[TVAO_VEGETATION]_alpha
num_pars[TVAO_TERRAIN]); // final int num_samples); // num_pars[TVAO_VEGETATION]_alpha
veget_neibs = getNeighbors(
TVAO_VEGETATION, // final int tvao, // TVAO_VEGETATION_ALPHA
ind_pars_vegetation, // final int ind_samples, // ind_pars_vegetation_alpha
num_pars_vegetation); // final int num_samples); // num_pars_vegetation_alpha
ind_pars[TVAO_VEGETATION], // final int ind_samples, // ind_pars[TVAO_VEGETATION]_alpha
num_pars[TVAO_VEGETATION]); // final int num_samples); // num_pars[TVAO_VEGETATION]_alpha
elevation_neibs = getNeighbors(
TVAO_ELEVATION, // final int tvao, // TVAO_VEGETATION_ALPHA
ind_pars_elevation, // final int ind_samples, // ind_pars_vegetation_alpha
num_pars_elevation); // final int num_samples); // num_pars_vegetation_alpha
ind_pars[TVAO_ELEVATION], // final int ind_samples, // ind_pars[TVAO_VEGETATION]_alpha
num_pars[TVAO_ELEVATION]); // final int num_samples); // num_pars[TVAO_VEGETATION]_alpha
neibs_neibs = new int [par_rindex.length][];
addSecondNeighbors(
neibs_neibs, // final int [][] second_neibs,
terr_neibs, // final int [][] par_neibs,
ind_pars_terrain); // final int start_index)
ind_pars[TVAO_TERRAIN]); // final int start_index)
addSecondNeighbors(
neibs_neibs, // final int [][] second_neibs,
alpha_neibs, // final int [][] par_neibs,
ind_pars_alpha); // final int start_index)
ind_pars[TVAO_ALPHA]); // final int start_index)
addSecondNeighbors(
neibs_neibs, // final int [][] second_neibs,
veget_neibs, // final int [][] par_neibs,
ind_pars_vegetation); // final int start_index)
ind_pars[TVAO_VEGETATION]); // final int start_index)
addSecondNeighbors(
neibs_neibs, // final int [][] second_neibs,
elevation_neibs, // final int [][] par_neibs,
ind_pars_elevation); // final int start_index)
ind_pars[TVAO_ELEVATION]); // final int start_index)
if (debugLevel > 4) {
showPivot(
......@@ -672,7 +691,11 @@ public class VegetationLMA {
setupWeights( // after setupParametersIndices
scene_weights,
reg_weights, // final double reg_weights,
hifreq_weight ); // final double hifreq_weight );
hifreq_weight); // final double hifreq_weight );
// false, // final boolean apply_transparency,
// 1.0, // final double alpha_opaque,
// 0.0); // final double alpha_pedestal) {
last_jt = new double [parameters_vector.length][];
return weights.length;
}
......@@ -971,14 +994,24 @@ public class VegetationLMA {
"parameters.vector-"+debug_index);
}
boolean decimate = disabledParams(); // at least one parameter is
int [][] par_map = decimate ? getParsAllDecimatedAllIndices() : null;
double [][] last_jt_decimated = decimateJt( // will not decimate if par_map == null
par_map, // final int [][] par_map, // // only [1] used
this.last_jt); // final double [][] jt_full)
Matrix y_minus_fx_weighted = new Matrix(this.last_ymfx, this.last_ymfx.length);
boolean debug_jtj = debug_level>4;
Matrix wjtjlambda = new Matrix(getWJtJlambda(
lambda, // *10, // temporary
this.last_jt, // double [][] jt) // null
lambda, //
last_jt_decimated, // this.last_jt, // double [][] jt) // null
param_pivot, // final boolean [][] pivot)));
par_map, //final int [][] par_map, // jt already remapped, apply par_map to pivot only
debug_jtj)); // final boolean debug));
if (debug_level > -2) { // 1) {
System.out.println((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime()))+
" getWJtJlambda() DONE, starting matrix inversion");
}
if (debug_level>4) {
System.out.println("JtJ + lambda*diag(JtJ");
wjtjlambda.print(18, 6);
......@@ -999,7 +1032,8 @@ public class VegetationLMA {
jtjl_inv.print(18, 6);
}
//last_jt has NaNs
Matrix jty = (new Matrix(this.last_jt)).times(y_minus_fx_weighted);
// Matrix jty = (new Matrix(this.last_jt)).times(y_minus_fx_weighted);
Matrix jty = (new Matrix(last_jt_decimated)).times(y_minus_fx_weighted);
if (debug_level>2) {
System.out.println("Jt * (y-fx)");
jty.print(18, 6);
......@@ -1013,7 +1047,11 @@ public class VegetationLMA {
}
double scale = 1.0;
double [] delta = mdelta.getColumnPackedCopy();
double [] delta_decim= mdelta.getColumnPackedCopy();
double [] delta = expandDecimated(
par_map, //final int [][] par_map, // only [0] used
delta_decim); // final double [] data_decimated)
double [] new_vector = parameters_vector.clone();
for (int i = 0; i < parameters_vector.length; i++) {
new_vector[i] += scale * delta[i];
......@@ -1206,12 +1244,14 @@ public class VegetationLMA {
private double [][] getWJtJlambdaDebug(
final double lambda,
final double [][] jt,
final boolean [][] pivot) {
final boolean [][] pivot,
final int [][] par_map) {
long startTime = System.nanoTime();
double [][] jtj_full = getWJtJlambda(
lambda, // final double lambda,
jt, // final double [][] jt,
null, // final boolean [][] pivot,
par_map, // final int [][] par_map,
false);
long fullTime = System.nanoTime();
double full_run_time = (fullTime - startTime) * 1E-9;
......@@ -1221,6 +1261,7 @@ public class VegetationLMA {
lambda, // final double lambda,
jt, // final double [][] jt,
pivot, // final boolean [][] pivot,
par_map, // final int [][] par_map,
false);
long endTime = System.nanoTime();
double pivot_run_time = (endTime - fullTime) * 1E-9;
......@@ -1252,13 +1293,16 @@ public class VegetationLMA {
final double lambda,
final double [][] jt,
final boolean [][] pivot,
final int [][] par_map, // jt already remapped, apply par_map to pivot only
final boolean debug)
{
if (debug && (pivot != null)) {
return getWJtJlambdaDebug(
lambda, // final double lambda,
jt, // final double [][] jt,
pivot); // final boolean [][] pivot,
pivot, // final boolean [][] pivot,
par_map); // final int [][] par_map,
}
final int num_pars = jt.length;
final int num_pars2 = num_pars * num_pars;
......@@ -1272,8 +1316,10 @@ public class VegetationLMA {
for (int indx = ai.getAndIncrement(); indx < num_pars2; indx = ai.getAndIncrement()) {
int i = indx / num_pars;
int j = indx % num_pars;
int pi = (par_map==null)? i : par_map[1][i];
int pj = (par_map==null)? j : par_map[1][j];
// diagonals are set true in pivot[i][i] = true;
if ((j >= i) && ((pivot == null) || pivot[i][j])) {
if ((j >= i) && ((pivot == null) || pivot[pi][pj])) { // pivot[i][j])) {
double d = 0.0;
for (int k = 0; k < nup_points; k++) {
if (jt[i][k] != 0) {
......@@ -1536,7 +1582,7 @@ public class VegetationLMA {
final double [] vector,
final boolean calc_derivatives,
final int debugLevel) {
final boolean elevation_parameters = (num_pars_elevation > 0);
final boolean elevation_parameters = (num_pars[TVAO_ELEVATION] > 0);
final boolean need_derivs = elevation_parameters && calc_derivatives;
if (!need_derivs && (elev_sum_weights != null)) {
return; // nothing to do
......@@ -1550,13 +1596,13 @@ public class VegetationLMA {
if (need_derivs) {
elev_dweights4 = new double [num_scenes][][];
elev_dsum_weights = new double [num_scenes][][];
// elev_dsum_pivot = new boolean [num_pars_elevation][num_pars_elevation];
// elev_dsum_pivot = new boolean [num_pars[TVAO_ELEVATION]][num_pars[TVAO_ELEVATION]];
}
//elev_radius[num_pixels];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger ati = new AtomicInteger(0);
// final boolean [][][] pivot_thread = new boolean[threads.length][woi_veg_length][num_pars_elevation];
// final boolean [][][] pivot_thread = new boolean[threads.length][woi_veg_length][num_pars[TVAO_ELEVATION]];
final ArrayList<ArrayList<HashSet<Integer>>> contrib_threads = new ArrayList<ArrayList<HashSet<Integer>>>(threads.length);
if (need_derivs) {
for (int nthread = 0; nthread < threads.length; nthread++) {
......@@ -1587,7 +1633,7 @@ public class VegetationLMA {
elev_sum_weights[nScene] = new double [woi_length];
if (need_derivs) {
elev_dweights4[nScene] = new double [woi_veg_length][];
elev_dsum_weights[nScene] = new double [num_pars_elevation][woi_length];
elev_dsum_weights[nScene] = new double [num_pars[TVAO_ELEVATION]][woi_length];
}
for (int wvindex = 0; wvindex < woi_veg_length; wvindex++) if (valid_vegetation[wvindex]) {
int wvx = wvindex % woi_veg.width; // relative to woi_veg
......@@ -1679,7 +1725,7 @@ public class VegetationLMA {
double dww = wnd_y * dwnd_x[dx] + dwnd_y*wnd_x[dx];
elev_dweights4[nScene][wvindex][dindx] = dww;
int par_indx_elev = par_index[TVAO_ELEVATION][npix]; // ipx+ipy*full.width];
elev_dsum_weights[nScene][par_indx_elev-ind_pars_elevation][wpindex] += dww;
elev_dsum_weights[nScene][par_indx_elev-ind_pars[TVAO_ELEVATION]][wpindex] += dww;
contrib_thread.get(wpindex).add(par_indx_elev); // full parameter index
// pivot_thread[nthread][wvindex][par_indx_elev] = true;
}
......@@ -1695,7 +1741,7 @@ public class VegetationLMA {
if (need_derivs) {
// combine pivots
// final boolean [][] pivot_combo = new boolean[woi_veg_length][num_pars_elevation];
// final boolean [][] pivot_combo = new boolean[woi_veg_length][num_pars[TVAO_ELEVATION]];
final ArrayList<HashSet<Integer>> contrib_combo = new ArrayList<HashSet<Integer>>(woi_length);
for (int i = 0; i < woi_length; i++) {
contrib_combo.add(new HashSet<Integer>());
......@@ -1718,8 +1764,8 @@ public class VegetationLMA {
elev_contribs = contrib_combo; // for each of the woi pixels - set of full elevation parameter indices that influence it
/*
elev_dsum_pivot = getPivotFromSets(
ind_pars_elevation, // final int par_index,
num_pars_elevation, // final int par_number,
ind_pars[TVAO_ELEVATION], // final int par_index,
num_pars[TVAO_ELEVATION], // final int par_number,
contrib_combo); // final ArrayList<HashSet<Integer>> sets)
*/
......@@ -2042,7 +2088,7 @@ public class VegetationLMA {
private double [] getFxDerivs(
final double [] vector,
final double [][] jt, // should be null or initialized with [vector.length][]
final double [][] debug_data, // {elev* alpha shifted, terrain *(1-alpha) shifted, elev_sum_weights}
final double [][] extra_data, // {elev* alpha shifted, terrain *(1-alpha) shifted, elev_sum_weights}
final int debug_level) {
final boolean dbg1 = (debug_level > 4);
// final int dbg_y_indx = 900; // and multiples ?
......@@ -2057,11 +2103,11 @@ public class VegetationLMA {
final int num_pixels = full.width * full.height;
final boolean need_derivs = (jt != null);
final boolean elevation_parameters = (num_pars_elevation > 0);
final boolean vegetation_parameters = (num_pars_vegetation > 0);
final boolean alpha_parameters = (num_pars_alpha > 0);
final boolean terrain_parameters = (num_pars_terrain > 0);
final boolean scenes_parameters = (num_pars_scenes > 0);
final boolean elevation_parameters = (num_pars[TVAO_ELEVATION] > 0);
final boolean vegetation_parameters = (num_pars[TVAO_VEGETATION] > 0);
final boolean alpha_parameters = (num_pars[TVAO_ALPHA] > 0);
final boolean terrain_parameters = (num_pars[TVAO_TERRAIN] > 0);
final boolean scenes_parameters = (num_pars[TVAO_SCENE_OFFSET] > 0);
final AtomicInteger anum_elev_err = new AtomicInteger(0);
// final boolean use_hf = samples_pointers[SAMPLES_Y_HF][1]>0;
// using 0.5*(1-cos(alpha/2pi) instead of alpha. alpha < 0 -> 0, alpha > 1 -> 1. Depends on other terms for stability
......@@ -2071,9 +2117,17 @@ public class VegetationLMA {
jt[i] = new double [weights.length]; // weights.length];
}
}
if (debug_data != null) {
for (int i = 0; i < debug_data.length; i++) {
debug_data[i] = new double [weights.length];
if (extra_data != null) {
for (int i = 0; i < extra_data.length; i++) {
extra_data[i] = new double [weights.length];
}
if (extra_data.length > 5) {
System.arraycopy(
weights,
0,
extra_data[5],
0,
weights.length);
}
}
final Thread[] threads = ImageDtt.newThreadArray();
......@@ -2109,8 +2163,8 @@ public class VegetationLMA {
for (int i = 0; i < woi_length; i++) {
contrib_thread.add(new HashSet<Integer>());
}
dalpha_woi = new double [num_pars_alpha][woi_length]; // first index is 0 if not adjusted
dveget_woi = new double [num_pars_vegetation][woi_length]; // first index is 0 if not adjusted
dalpha_woi = new double [num_pars[TVAO_ALPHA]][woi_length]; // first index is 0 if not adjusted
dveget_woi = new double [num_pars[TVAO_VEGETATION]][woi_length]; // first index is 0 if not adjusted
}
for (int nScene = ai.getAndIncrement(); nScene < num_scenes; nScene = ai.getAndIncrement()) if (valid_scenes[nScene]){
Arrays.fill(alpha_woi,0);
......@@ -2180,11 +2234,11 @@ public class VegetationLMA {
if (need_derivs) {
if (nvpar >= 0) {
contrib_thread.get(windx).add(nvpar); // full parameter index
dveget_woi[nvpar-ind_pars_vegetation][windx] += w;
dveget_woi[nvpar-ind_pars[TVAO_VEGETATION]][windx] += w;
}
if (napar >= 0) {
contrib_thread.get(windx).add(napar); // full parameter index
dalpha_woi[napar-ind_pars_alpha][windx] += w;
dalpha_woi[napar-ind_pars[TVAO_ALPHA]][windx] += w;
}
}
}
......@@ -2224,7 +2278,7 @@ public class VegetationLMA {
double sw = elev_sum_weights[nScene][windx];
if (sw == 0) {
anum_elev_err.getAndIncrement();
if ((debug_level > -2) && (debug_data == null)){
if ((debug_level > -2) && (extra_data == null)){
System.out.println("getFxDerivs(): BUG: elev_sum_weights["+nScene+"]["+windx+"]=0");
}
} else { // OK, non-zero
......@@ -2237,12 +2291,18 @@ public class VegetationLMA {
k = (avg_alpha < 0)? 0: ((avg_alpha > 1) ? 1.0: 0.5 * (1.0 - Math.cos(avg_alpha*Math.PI)));
}
d = terrain * (1.0 - k) + avg_veget * k;
if (debug_data != null) {
debug_data[0][y_indx] = k;
debug_data[1][y_indx] = terrain;
debug_data[2][y_indx] = terrain * (1.0 - k) + scene_offset;
debug_data[3][y_indx] = avg_veget * k + scene_offset;
debug_data[4][y_indx] = sw;
if (extra_data != null) {
if (extra_data.length > 0) {
extra_data[0][y_indx] = k;
if (extra_data.length > 1) {
extra_data[1][y_indx] = terrain;
if (extra_data.length > 2) {
extra_data[2][y_indx] = terrain * (1.0 - k) + scene_offset;
if (extra_data.length > 3) {
extra_data[3][y_indx] = avg_veget * k + scene_offset;
if (extra_data.length > 4) {
extra_data[4][y_indx] = sw;
}}}}}
}
if (need_derivs) {
......@@ -2252,16 +2312,16 @@ public class VegetationLMA {
if (vegetation_parameters || alpha_parameters) {
HashSet<Integer> pars_set = contrib_thread.get(windx); // may have unrelated (from other scenes) but still a small number
for (int npar: pars_set) {
int nvpar = npar - ind_pars_vegetation; // 0-based index of the vegetation
if((nvpar >= 0) && (nvpar < num_pars_vegetation)) {
int nvpar = npar - ind_pars[TVAO_VEGETATION]; // 0-based index of the vegetation
if((nvpar >= 0) && (nvpar < num_pars[TVAO_VEGETATION])) {
jt[npar][y_indx] = k * dveget_woi[nvpar][windx]/sw ;
contrib_thread.get(windx).add(npar); // full parameter index, vegetation
if (dbg1 && (npar== dbg_npar)) {
System.out.println("nscene="+nScene+" ntherad="+nthread+"y_indx="+y_indx+" windx="+windx+" sw="+sw+" d="+d+" k="+k+" jt="+jt[npar][y_indx]+" dveget_woi="+dveget_woi[nvpar][windx]);
}
} else {
int napar = npar - ind_pars_alpha;
if ((napar >= 0) && (napar < num_pars_alpha)) {
int napar = npar - ind_pars[TVAO_ALPHA];
if ((napar >= 0) && (napar < num_pars[TVAO_ALPHA])) {
if ((avg_alpha >= 0) && (avg_alpha <= 1.0)) {
if (alpha_piece_linear) {
jt[npar][y_indx] = dalpha_woi[napar][windx]/sw * (avg_veget - terrain);
......@@ -2279,8 +2339,8 @@ public class VegetationLMA {
// we have dsw_delevations (for all elevation parameters) - ,
HashSet<Integer> epars_set = elev_contribs.get(windx); // may have unrelated (from other scenes) but still a small number
for (int npar: epars_set) { // elevation parameters - full
int nepar = npar-ind_pars_elevation;
if ((nepar >=0 ) && (nepar < num_pars_elevation)) {
int nepar = npar-ind_pars[TVAO_ELEVATION];
if ((nepar >=0 ) && (nepar < num_pars[TVAO_ELEVATION])) {
int findx = par_rindex[npar][1]; // full image pixel;
double veget_src = tvao[TVAO_VEGETATION][findx];
if (vegetation_parameters) {
......@@ -2319,7 +2379,7 @@ public class VegetationLMA {
// add to the set of parameters
contrib_thread.get(windx).add(npar); // full parameter index, elevation
} else { // bug
System.out.println("getFxDerivs(): BUG: npar="+npar+" -> nepar="+nepar+" >= num_pars_elevation="+num_pars_elevation);
System.out.println("getFxDerivs(): BUG: npar="+npar+" -> nepar="+nepar+" >= num_pars[TVAO_ELEVATION]="+num_pars[TVAO_ELEVATION]);
}
}
}
......@@ -2330,8 +2390,8 @@ public class VegetationLMA {
if (need_derivs && (ntpar >= 0)) {
jt[ntpar][y_indx] = 1.0;
}
if (debug_data != null) {
debug_data[0][y_indx] = terrain + scene_offset;
if (extra_data != null) {
extra_data[0][y_indx] = terrain + scene_offset;
}
}
fX[y_indx] = d + scene_offset;
......@@ -2485,8 +2545,8 @@ public class VegetationLMA {
if (samples_pointers[SAMPLES_SCENES][1]>0) { // use_scenes_pull0) { // single sample after differences
int ind_scenes = samples_pointers[SAMPLES_SCENES][0];
fX[ind_scenes] = 0.0; // ind_next] =0.0;
for (int n = 0; n < num_pars_scenes; n++) { // only count adjustable scene offsets
int np = ind_pars_scenes + n; // index of the alpha parameter
for (int n = 0; n < num_pars[TVAO_SCENE_OFFSET]; n++) { // only count adjustable scene offsets
int np = ind_pars[TVAO_SCENE_OFFSET] + n; // index of the alpha parameter
int nscene = par_rindex[np][1];
double sw=scene_weights[nscene] * scale_scenes_pull;
fX[ind_scenes] += sw * vector[np];
......@@ -2514,7 +2574,8 @@ public class VegetationLMA {
if (debug_print && (windx == 0)) {
System.out.println("yIndx="+yIndx+", nscene="+nscene+", indx="+indx+", windx="+windx);
}
double w = scene_weights[nscene]; // norm_scene_weights[nscene];
double w = recalc_average ? weights[yIndx]/weight_to_scene_weight: scene_weights[nscene]; // norm_scene_weights[nscene];
w *= terrain_correction;
fX_avg_thread[nthread][windx] += w * fX[yIndx]; // already calculated
if (jt_avg_thread != null) {
HashSet<Integer> pars_contribs = param_contribs.get(windx); // contributors before laplacians
......@@ -2557,7 +2618,7 @@ public class VegetationLMA {
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_alpha; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < num_pars[TVAO_ALPHA]; n = ai.getAndIncrement()) {
int np = n + samples_pointers[SAMPLES_ALPHA_PULL][2]; // index of the alpha parameter
int nx = n + samples_pointers[SAMPLES_ALPHA_PULL][0]; // y_vector.length; // x - index
if (nx == dbg_nx) {
......@@ -2617,12 +2678,12 @@ public class VegetationLMA {
if (samples_pointers[SAMPLES_ALPHA_LPF][1] > 0) { // fits[TVAO_ALPHA] && (alpha_lpf >= 0)) {
int dbg_nx = -76340;
// final int ind_y_alpha_lpf = samples_pointers[SAMPLES_ALPHA_LPF][0]; // ind_next;
// ind_next += num_pars_alpha;
// ind_next += num_pars[TVAO_ALPHA];
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_alpha; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < num_pars[TVAO_ALPHA]; n = ai.getAndIncrement()) {
int np = n + samples_pointers[SAMPLES_ALPHA_LPF][2]; // index of the alpha parameter
int nx = n + samples_pointers[SAMPLES_ALPHA_LPF][0]; // y_vector.length; // x - index
if (nx == dbg_nx) {
......@@ -2710,7 +2771,7 @@ public class VegetationLMA {
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_terrain; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < num_pars[TVAO_TERRAIN]; n = ai.getAndIncrement()) {
int np = n + samples_pointers[SAMPLES_TERRAIN_PULL][2];
int nx = n + samples_pointers[SAMPLES_TERRAIN_PULL][0];
double d = 0;
......@@ -2734,12 +2795,12 @@ public class VegetationLMA {
if (samples_pointers[SAMPLES_TERRAIN_LPF][1]>0) { // fits[TVAO_TERRAIN] && (terr_lpf >= 0)) {
// final int ind_y_terr = samples_pointers[SAMPLES_TERRAIN_LPF][0]; // ind_next;
// ind_next += num_pars_terrain;
// ind_next += num_pars[TVAO_TERRAIN];
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_terrain; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < num_pars[TVAO_TERRAIN]; n = ai.getAndIncrement()) {
int np = n + samples_pointers[SAMPLES_TERRAIN_LPF][2];
int nx = n + samples_pointers[SAMPLES_TERRAIN_LPF][0];
double d = 0;
......@@ -2780,12 +2841,12 @@ public class VegetationLMA {
if (samples_pointers[SAMPLES_VEGETATION_PULL][1] > 0) { // fits[TVAO_VEGETATION] && (veget_lpf >= 0)) { // should be positive for pull0 and terr_pull_cold (difference between vegetation and terrain)
// final int ind_y_veget = samples_pointers[SAMPLES_VEGETATION_PULL][0]; // ind_next;
// ind_next += num_pars_vegetation;
// ind_next += num_pars[TVAO_VEGETATION];
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_vegetation; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < num_pars[TVAO_VEGETATION]; n = ai.getAndIncrement()) {
int np = n + samples_pointers[SAMPLES_VEGETATION_PULL][2];
int nx = n + samples_pointers[SAMPLES_VEGETATION_PULL][0];
double d = 0;
......@@ -2814,7 +2875,7 @@ public class VegetationLMA {
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_vegetation; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < num_pars[TVAO_VEGETATION]; n = ai.getAndIncrement()) {
int np = n + samples_pointers[SAMPLES_VEGETATION_LPF][2];
int nx = n + samples_pointers[SAMPLES_VEGETATION_LPF][0];
double d = 0;
......@@ -2857,19 +2918,19 @@ public class VegetationLMA {
if (samples_pointers[SAMPLES_VEGETATION_LPF][1] > 0) { // should be positive for pull0 and terr_pull_cold (difference between vegetation and terrain)
if (num_pars_alpha <= 0) {
if (num_pars[TVAO_ALPHA] <= 0) {
System.out.println("getFxDerivs(): BUG: Asjusting SAMPLES_VEGETATION_LPF requires alpha parameters aslo to be fitted");
} else {
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_vegetation; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < num_pars[TVAO_VEGETATION]; n = ai.getAndIncrement()) {
int np = n + samples_pointers[SAMPLES_VEGETATION_LPF][2];
int nx = n + samples_pointers[SAMPLES_VEGETATION_LPF][0];
int findx = par_rindex[np][1];//
int npa = par_index[TVAO_ALPHA][findx]; // parameter for same-pixel alpha
int na = npa - ind_pars_alpha;
int na = npa - ind_pars[TVAO_ALPHA];
if (npa < 0) {
System.out.println("getFxDerivs(): BUG: no alpha for vegetation, n="+n+", np="+np+", nx ="+nx+
" findx="+findx+", npa="+npa);
......@@ -2987,7 +3048,7 @@ public class VegetationLMA {
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_elevation; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < num_pars[TVAO_ELEVATION]; n = ai.getAndIncrement()) {
int np = n + samples_pointers[SAMPLES_ELEVATION_PULL][2];
int nx = n + samples_pointers[SAMPLES_ELEVATION_PULL][0];
double d = 0;
......@@ -3015,7 +3076,7 @@ public class VegetationLMA {
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_elevation; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < num_pars[TVAO_ELEVATION]; n = ai.getAndIncrement()) {
int np = n + samples_pointers[SAMPLES_ELEVATION_LPF][2];
int nx = n + samples_pointers[SAMPLES_ELEVATION_LPF][0];
double d = 0;
......@@ -3346,23 +3407,31 @@ public class VegetationLMA {
vector = parameters_vector;
}
final boolean use_hf = y_vector.length > y_src.length; // twice longer
final int index_combo = num_scenes;
final int index_weighted = num_scenes+1;
final int ext_scenes = index_weighted+1; // number of scenes and averages
String [] top_titles = use_hf? (
new String[]{"Y_lf", "fX_lf", "Ylf-fXlf","Y_hf", "fX_hf", "Yhf-fXhf", "alpha", "terrain", "terr-scaled","veget","sum_w"}):
new String[]{"Y", "fX", "Y-fX","alpha", "terrain", "terr-scaled","veget","sum_w"};
double [][][] img_data = new double [top_titles.length][num_scenes+1][woi.width*woi.height];
new String[]{"Y_lf", "fX_lf", "Ylf-fXlf","Y_hf", "fX_hf", "Yhf-fXhf", "alpha", "terrain", "terr-scaled","veget","sum_w","weights"}):
new String[]{"Y", "fX", "Y-fX","alpha", "terrain", "terr-scaled","veget","sum_w","weights"};
double [][][] img_data = new double [top_titles.length][ext_scenes][woi.width*woi.height];
double [][] extra_data = new double [6][];
int index_alpha = use_hf ? 6:3;
int index_extra_weight = 5;
int index_weight = index_alpha + index_extra_weight;
double scale_weights = 1e6; // to make easy-to-set image windows
for (int n = 0; n < img_data.length; n++) {
for (int nscene = 0; nscene < num_scenes; nscene++) {
int num_nan_scenes = ( n== index_alpha) ? ext_scenes : num_scenes;
// for (int nscene = 0; nscene < img_data[n].length; nscene++) {
for (int nscene = 0; nscene < num_nan_scenes; nscene++) {
Arrays.fill(img_data[n][nscene], Double.NaN);
}
}
double [][] debug_data = new double [5][];
int index_alpha = use_hf ? 6:3;
double [] fX = getFxDerivs( // longer than y_vector
vector, // final double [] vector,
null, // final double [][] jt, // should be null or initialized with [vector.length][]
debug_data, // final double [][] debug_data, // {elev* alpha shifted, terrain *(1-alpha) shifted, elev_sum_weights}
extra_data, // final double [][] debug_data, // {elev* alpha shifted, terrain *(1-alpha) shifted, elev_sum_weights}
-1); // final int debug_level)
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
......@@ -3379,8 +3448,9 @@ public class VegetationLMA {
img_data[0][nscene][windx] = y_vector[n_lf];
img_data[1][nscene][windx] = fX[n_lf];
img_data[2][nscene][windx] = y_vector[n_lf]-fX[n_lf];
for (int i = 0; i < debug_data.length; i++) {
img_data[index_alpha + i][nscene][windx] = debug_data[i][n_lf];
for (int i = 0; i < extra_data.length; i++) {
double k = (i == index_extra_weight) ? scale_weights : 1.0;
img_data[index_alpha + i][nscene][windx] = k* extra_data[i][n_lf];
}
}
}
......@@ -3412,29 +3482,62 @@ public class VegetationLMA {
double [][] sw = new double [img_data.length][img_data[0][0].length];
for (int slice=0; slice < img_data.length; slice++) {
if (slice == index_alpha) { // min alpha instead of the average
for (int nscene = 0; nscene < num_scenes; nscene++) {
for (int npix = 0; npix < img_data[slice][nscene].length; npix++) if (!Double.isNaN(img_data[slice][nscene][npix])){
double w = scene_weights[nscene];
double d = img_data[slice][nscene][npix];
if (!(img_data[slice][index_combo][npix] <= d)) {
img_data[slice][index_combo][npix] = d;
}
}
}
} else {
for (int nscene = 0; nscene < num_scenes; nscene++) {
double w = (slice == index_weight)? 1.0: scene_weights[nscene];
for (int npix = 0; npix < img_data[slice][nscene].length; npix++) if (!Double.isNaN(img_data[slice][nscene][npix])){
sw[slice][npix] += w;
img_data[slice][index_combo][npix] += w * img_data[slice][nscene][npix];
}
}
for (int npix = 0; npix < sw[slice].length; npix++) {
double w = sw[slice][npix];
if (w > 0) {
img_data[slice][index_combo][npix] /= w;
} else {
img_data[slice][index_combo][npix] = Double.NaN;
}
}
}
}
sw = new double [img_data.length][img_data[0][0].length]; // reset to all 0-s
for (int slice=0; slice < img_data.length; slice++) {
for (int nscene = 0; nscene < num_scenes; nscene++) {
// double w = (slice == index_weight)? 1.0: scene_weights[nscene];
for (int npix = 0; npix < img_data[slice][nscene].length; npix++) if (!Double.isNaN(img_data[slice][nscene][npix])){
double w = (slice == index_weight)? 1.0: extra_data[index_extra_weight][npix];
if (!Double.isNaN(w)) {
sw[slice][npix] += w;
img_data[slice][num_scenes][npix] += w * img_data[slice][nscene][npix];
img_data[slice][index_weighted][npix] += w * img_data[slice][nscene][npix];
}
}
}
for (int npix = 0; npix < sw[slice].length; npix++) {
double w = sw[slice][npix];
if (w > 0) {
img_data[slice][num_scenes][npix] /= w;
img_data[slice][index_weighted][npix] /= w;
} else {
img_data[slice][num_scenes][npix] = Double.NaN;
img_data[slice][index_weighted][npix] = Double.NaN;
}
}
}
String [] scene_titles = new String[num_scenes+1];
String [] scene_titles = new String[ext_scenes];
for (int i = 0; i < num_scenes; i++) {
scene_titles[i] = ""+i;
}
scene_titles[num_scenes] = "average";
scene_titles[index_combo] = "combo";
scene_titles[index_weighted] = "weighted";
ShowDoubleFloatArrays.showArraysHyperstack(
img_data, // double[][][] pixels,
woi.width, // int width,
......@@ -3641,16 +3744,16 @@ public class VegetationLMA {
imp.setProperty("SCALE_SCENES_PULL", ""+scale_scenes_pull);
imp.setProperty("BOOST_PARALLAX", ""+boost_parallax);
imp.setProperty("NUM_PARS_TERRAIN", ""+num_pars_terrain);
imp.setProperty("NUM_PARS_VEGETATION", ""+num_pars_vegetation);
imp.setProperty("NUM_PARS_ALPHA", ""+num_pars_alpha);
imp.setProperty("NUM_PARS_ELEVATION", ""+num_pars_elevation);
imp.setProperty("NUM_PARS_SCENES", ""+num_pars_scenes);
imp.setProperty("IND_PARS_TERRAIN", ""+ind_pars_terrain);
imp.setProperty("IND_PARS_VEGETATION", ""+ind_pars_vegetation);
imp.setProperty("IND_PARS_ALPHA", ""+ind_pars_alpha);
imp.setProperty("IND_PARS_ELEVATION", ""+ind_pars_elevation);
imp.setProperty("IND_PARS_SCENES", ""+ind_pars_scenes);
imp.setProperty("NUM_PARS_TERRAIN", ""+num_pars[TVAO_TERRAIN]);
imp.setProperty("NUM_PARS_VEGETATION", ""+num_pars[TVAO_VEGETATION]);
imp.setProperty("NUM_PARS_ALPHA", ""+num_pars[TVAO_ALPHA]);
imp.setProperty("NUM_PARS_ELEVATION", ""+num_pars[TVAO_ELEVATION]);
imp.setProperty("NUM_PARS_SCENES", ""+num_pars[TVAO_SCENE_OFFSET]);
imp.setProperty("IND_PARS_TERRAIN", ""+ind_pars[TVAO_TERRAIN]);
imp.setProperty("IND_PARS_VEGETATION", ""+ind_pars[TVAO_VEGETATION]);
imp.setProperty("IND_PARS_ALPHA", ""+ind_pars[TVAO_ALPHA]);
imp.setProperty("IND_PARS_ELEVATION", ""+ind_pars[TVAO_ELEVATION]);
imp.setProperty("IND_PARS_SCENES", ""+ind_pars[TVAO_SCENE_OFFSET]);
// samples_pointers
for (int nsp = 0; nsp < SAMPLES_SIZE; nsp++) {
......@@ -3803,16 +3906,16 @@ public class VegetationLMA {
scale_scenes_pull = Double.parseDouble((String) imp_pars.getProperty("SCALE_SCENES_PULL"));
boost_parallax = Double.parseDouble((String) imp_pars.getProperty("BOOST_PARALLAX"));
}
num_pars_terrain = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_TERRAIN"));
num_pars_vegetation = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_VEGETATION"));
num_pars_alpha = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_ALPHA"));
num_pars_elevation = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_ELEVATION"));
num_pars_scenes = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_SCENES"));
ind_pars_terrain = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_TERRAIN"));
ind_pars_vegetation = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_VEGETATION"));
ind_pars_alpha = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_ALPHA"));
ind_pars_elevation = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_ELEVATION"));
ind_pars_scenes = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_SCENES"));
num_pars[TVAO_TERRAIN] = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_TERRAIN"));
num_pars[TVAO_VEGETATION] = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_VEGETATION"));
num_pars[TVAO_ALPHA] = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_ALPHA"));
num_pars[TVAO_ELEVATION] = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_ELEVATION"));
num_pars[TVAO_SCENE_OFFSET] = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_SCENES"));
ind_pars[TVAO_TERRAIN] = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_TERRAIN"));
ind_pars[TVAO_VEGETATION] = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_VEGETATION"));
ind_pars[TVAO_ALPHA] = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_ALPHA"));
ind_pars[TVAO_ELEVATION] = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_ELEVATION"));
ind_pars[TVAO_SCENE_OFFSET] = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_SCENES"));
par_index = new int[TVAO_TYPES][];
for (int n = 0; n < par_index.length; n++) {
......@@ -3826,20 +3929,20 @@ public class VegetationLMA {
// private int [][] par_index; // indices - [0..4][full_pixel] - same as for tvao, value - parameter index
// private int [][] par_rindex; // parameter -> pair of type (0..4) and full window pixel index
int [] par_nums = {
num_pars_terrain,
num_pars_vegetation,
num_pars_alpha,
num_pars_elevation,
num_pars_scenes};
num_pars[TVAO_TERRAIN],
num_pars[TVAO_VEGETATION],
num_pars[TVAO_ALPHA],
num_pars[TVAO_ELEVATION],
num_pars[TVAO_SCENE_OFFSET]};
/*
par_index[TVAO_TERRAIN] = new int [num_pars_terrain];
par_index[TVAO_VEGETATION] = new int [num_pars_vegetation];
par_index[TVAO_ALPHA] = new int [num_pars_alpha];
par_index[TVAO_ELEVATION] = new int [num_pars_elevation];
par_index[TVAO_SCENE_OFFSET] = new int [num_pars_scenes];
par_index[TVAO_TERRAIN] = new int [num_pars[TVAO_TERRAIN]];
par_index[TVAO_VEGETATION] = new int [num_pars[TVAO_VEGETATION]];
par_index[TVAO_ALPHA] = new int [num_pars[TVAO_ALPHA]];
par_index[TVAO_ELEVATION] = new int [num_pars[TVAO_ELEVATION]];
par_index[TVAO_SCENE_OFFSET] = new int [num_pars[TVAO_SCENE_OFFSET]];
*/
samples_pointers = new int [SAMPLES_SIZE][3];
for (int nsp = 0; nsp < SAMPLES_SIZE; nsp++) {
......@@ -4498,11 +4601,10 @@ public class VegetationLMA {
final double [] scene_weights_in,
final double reg_weights,
final double hifreq_weight) {
// double terrain_correction_weight = 1.0;
boolean use_hf = (y_src_hf != null);
int y_avg_len = y_vector.length - (y_src.length + ((y_src_hf != null) ? y_src_hf.length : 0));
// boolean use_terr_corr = y_vector.length > y_lf_hf_len;
boolean use_scenes_pull0 = (scenes_pull0 >=0);
// using >=0 no use 0 as NOP but reserve space, <0 - do not reserve space
samples_pointers = new int [SAMPLES_SIZE][3]; // {start, length}
......@@ -4517,50 +4619,42 @@ public class VegetationLMA {
samples_pointers[SAMPLES_SCENES][1] = 1;
}
if (fits[TVAO_ALPHA] && ((alpha_loss > 0) || (alpha_push > 0))) {
samples_pointers[SAMPLES_ALPHA_PULL][1] = num_pars_alpha;
samples_pointers[SAMPLES_ALPHA_PULL][2] = ind_pars_alpha;
samples_pointers[SAMPLES_ALPHA_PULL][1] = num_pars[TVAO_ALPHA];
samples_pointers[SAMPLES_ALPHA_PULL][2] = ind_pars[TVAO_ALPHA];
}
if (fits[TVAO_ALPHA] && (alpha_lpf >= 0)) {
samples_pointers[SAMPLES_ALPHA_LPF][1] = num_pars_alpha;
samples_pointers[SAMPLES_ALPHA_LPF][2] = ind_pars_alpha;
samples_pointers[SAMPLES_ALPHA_LPF][1] = num_pars[TVAO_ALPHA];
samples_pointers[SAMPLES_ALPHA_LPF][2] = ind_pars[TVAO_ALPHA];
}
if (fits[TVAO_TERRAIN] && (terr_pull0 >= 0)) {
samples_pointers[SAMPLES_TERRAIN_PULL][1] = num_pars_terrain;
samples_pointers[SAMPLES_TERRAIN_PULL][2] = ind_pars_terrain;
samples_pointers[SAMPLES_TERRAIN_PULL][1] = num_pars[TVAO_TERRAIN];
samples_pointers[SAMPLES_TERRAIN_PULL][2] = ind_pars[TVAO_TERRAIN];
}
if (fits[TVAO_TERRAIN] && (terr_lpf >= 0)) {
samples_pointers[SAMPLES_TERRAIN_LPF][1] = num_pars_terrain;
samples_pointers[SAMPLES_TERRAIN_LPF][2] = ind_pars_terrain;
samples_pointers[SAMPLES_TERRAIN_LPF][1] = num_pars[TVAO_TERRAIN];
samples_pointers[SAMPLES_TERRAIN_LPF][2] = ind_pars[TVAO_TERRAIN];
}
if (fits[TVAO_VEGETATION] && (veget_pull0 >= 0)) {
samples_pointers[SAMPLES_VEGETATION_PULL][1] = num_pars_vegetation;
samples_pointers[SAMPLES_VEGETATION_PULL][2] = ind_pars_vegetation;
samples_pointers[SAMPLES_VEGETATION_PULL][1] = num_pars[TVAO_VEGETATION];
samples_pointers[SAMPLES_VEGETATION_PULL][2] = ind_pars[TVAO_VEGETATION];
}
if (fits[TVAO_VEGETATION] && (veget_lpf >= 0)) {
samples_pointers[SAMPLES_VEGETATION_LPF][1] = num_pars_vegetation;
samples_pointers[SAMPLES_VEGETATION_LPF][2] = ind_pars_vegetation;
samples_pointers[SAMPLES_VEGETATION_LPF][1] = num_pars[TVAO_VEGETATION];
samples_pointers[SAMPLES_VEGETATION_LPF][2] = ind_pars[TVAO_VEGETATION];
}
if (fits[TVAO_ELEVATION] && (veget_pull0 >= 0)) {
samples_pointers[SAMPLES_ELEVATION_PULL][1] = num_pars_elevation;
samples_pointers[SAMPLES_ELEVATION_PULL][2] = ind_pars_elevation;
samples_pointers[SAMPLES_ELEVATION_PULL][1] = num_pars[TVAO_ELEVATION];
samples_pointers[SAMPLES_ELEVATION_PULL][2] = ind_pars[TVAO_ELEVATION];
}
if (fits[TVAO_ELEVATION] && (veget_lpf >= 0)) {
samples_pointers[SAMPLES_ELEVATION_LPF][1] = num_pars_elevation;
samples_pointers[SAMPLES_ELEVATION_LPF][2] = ind_pars_elevation;
samples_pointers[SAMPLES_ELEVATION_LPF][1] = num_pars[TVAO_ELEVATION];
samples_pointers[SAMPLES_ELEVATION_LPF][2] = ind_pars[TVAO_ELEVATION];
}
for (int i = 1; i < samples_pointers.length; i++) {
samples_pointers[i][0] = samples_pointers[i-1][0] + samples_pointers[i-1][1];
}
samples_pointers[SAMPLES_TOTAL][1] = samples_pointers[SAMPLES_TOTAL][0] - samples_pointers[SAMPLES_EXTRA][0];
/*
//(alpha_loss > 0)
if (use_scenes_pull0) extra_samples += 1;
if ((alpha_loss > 0) || (alpha_push > 0)) extra_samples+= num_pars_alpha; // need to split loss (always positive) from alpha_lpf
if (alpha_lpf >= 0) extra_samples+= num_pars_alpha;
if (terr_lpf >= 0) extra_samples+= num_pars_terrain;
if (veget_lpf >= 0) extra_samples+= num_pars_vegetation;
if (elevation_lpf >= 0) extra_samples+= num_pars_elevation;
*/
int extra_samples = samples_pointers[SAMPLES_TOTAL][1];
double reg_sample_weight = reg_weights/extra_samples; // weight of each regularization sample
......@@ -4590,7 +4684,7 @@ public class VegetationLMA {
if (y_avg_len > 0) {
for (int ny = 0; ny < y_avg_len; ny++) {
s += terrain_correction; // scene_weights[nscene] is included in y_wavg and fX, jt
s += terrain_correction_weight; // scene_weights[nscene] is included in y_wavg and fX, jt
}
}
......@@ -4601,7 +4695,6 @@ public class VegetationLMA {
final double k = 1.0/s;
weight_pure = s0/s;
scale_scenes_pull = scenes_pull0 * extra_samples / s_scenes; // or use extra_samples instead of woi.width*woi.height ?
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
......@@ -4620,7 +4713,7 @@ public class VegetationLMA {
System.out.println("weights["+nw+"]=NaN - 2");
}
} else if (nw < samples_pointers[SAMPLES_EXTRA][0]) { // y_wavg if exists
weights[nw] = k * terrain_correction;
weights[nw] = k * terrain_correction_weight;
if (Double.isNaN(weights[nw])) {
System.out.println("weights["+nw+"]=NaN - 3");
}
......@@ -4639,6 +4732,231 @@ public class VegetationLMA {
return;
}
public double [][] getTransparency(// [scene][windx]
final double [] vector){
final int woi_length = woi.width*woi.height;
final double [][] transparency = new double [num_scenes][woi_length];
for (int nscene = 0; nscene < num_scenes; nscene++) {
Arrays.fill(transparency[nscene], Double.NaN);
}
double [][] extra_data = new double [1][]; // [0] will be alpha mapped to elevation offsets
getFxDerivs(
vector, // final double [] vector,
null, // final double [][] jt, // should be null or initialized with [vector.length][]
extra_data, // final double [][] debug_data, // {elev* alpha shifted, terrain *(1-alpha) shifted, elev_sum_weights}
-1); // final int debug_level)
double [] alpha = extra_data[0];
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int ny = ai.getAndIncrement(); ny < y_src.length; ny = ai.getAndIncrement()) {
int nscene = y_src[ny][YSRC_SCENE];
int findx = y_src[ny][YSRC_FINDEX];
int windx = getWindexFromFindex(findx);
double t = 1.0 - alpha[ny];
transparency[nscene][windx] = t;
}
}
};
}
ImageDtt.startAndJoin(threads);
return transparency;
}
public double [][] getTransparenctWeights(
final double [][] transparency,
final double transparency_opaque,
final double transparency_pedestal,
final double transparency_frac,
final double transparency_dist){ //0 - do not apply
final int dbg_windx = 113;
final int woi_length = woi.width*woi.height;
final double [][] transparency_weights = new double [num_scenes][woi_length];
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int nscene = 0; nscene < num_scenes; nscene++) {
Arrays.fill(transparency_weights[nscene], Double.NaN);
}
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [] transp = new double [num_scenes];
for (int wPix = ai.getAndIncrement(); wPix < woi_length; wPix = ai.getAndIncrement()) {
if (wPix == dbg_windx) {
System.out.println("getTransparenctWeights(): wPix="+wPix);
}
Arrays.fill(transp, Double.NaN);
double t_max = Double.NaN;
int n_max = -1;
for (int nscene = 0; nscene < transp.length; nscene++) {
double t = transparency[nscene][wPix];
transp[nscene] = t;
if (!Double.isNaN(t) && !(t_max >= t)) {
t_max = t;
n_max = nscene;
}
}
if (!Double.isNaN(t_max)) {
double t_max_offs = t_max - transparency_opaque;
if (t_max_offs > 0) {
int fpix = getFindexFromWindex(wPix);
double [] scale_xy_max = scales_xy[n_max][fpix];
for (int nscene = 0; nscene < transp.length; nscene++) if (!Double.isNaN(transp[nscene])){
double tf = (transp[nscene] - transparency_opaque) / t_max_offs;
if (tf >= transparency_frac) {
if (transparency_dist > 0) {
double scale_dist = 0;
double [] scale_xy = scales_xy[nscene][fpix];
if ((scale_xy_max != null) && (scale_xy != null)) {
double dx = scale_xy[0] - scale_xy_max[0];
double dy = scale_xy[1] - scale_xy_max[1];
scale_dist = Math.sqrt(dx*dx+dy*dy);
}
tf *= (scale_dist + transparency_dist)/transparency_dist;
}
} else {
tf = 0;
}
transparency_weights[nscene][wPix] = tf + transparency_pedestal; // all those that were not NaN will be at least transparency_pedestal
}
} else {
for (int nscene = 0; nscene < transp.length; nscene++) if (!Double.isNaN(transp[nscene])){
transparency_weights[nscene][wPix] = transparency_pedestal;
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return transparency_weights;
}
public void applyTransparency(
final double [] vector,
final double transparency_opaque,
final double transparency_pedestal,
final double transparency_frac,
final double transparency_dist,
final boolean recalc_average) {
this.recalc_average = recalc_average;
final int woi_length = woi.width*woi.height;
boolean use_hf = (y_src_hf != null);
int y_avg_len = y_vector.length - (y_src.length + ((y_src_hf != null) ? y_src_hf.length : 0));
double [][] transparency = getTransparency((vector==null)? parameters_vector:vector);
double [][] transparency_weights = getTransparenctWeights(
transparency, // final double [][] transparency,
transparency_opaque, // final double transparency_opaque,
transparency_pedestal, // final double transparency_pedestal,
transparency_frac, // final double transparency_frac,
transparency_dist); // final double transparency_dist); //0 - do not apply
double s = 0, ss=0;
for (int ny = 0; ny < y_src.length; ny++) {
int nscene = y_src[ny][YSRC_SCENE];
int findx = y_src[ny][YSRC_FINDEX];
int windx = getWindexFromFindex(findx);
double w = transparency_weights[nscene][windx];
if (Double.isNaN(w)) {
System.out.println("applyTransparency() 1: ny="+ny+", nscene="+nscene+", findx="+findx+", windx="+windx+", w="+w);
} else {
s += w;
}
ss += scene_weights[nscene];
}
// double s_scenes = s; // sum of all scene weight. Maybe skip scenes that do not exist?
double s_to_ss = s/ss;
if (use_hf) { // second pass, repeating for possible future modifications
for (int ny = 0; ny < y_src_hf.length; ny++) {
int nscene = y_src_hf[ny][YSRC_SCENE];
int findx = y_src_hf[ny][YSRC_FINDEX];
int windx = getWindexFromFindex(findx);
double w = transparency_weights[nscene][windx] * hifreq_weight ;
if (Double.isNaN(w)) {
System.out.println("applyTransparency() 2: ny="+ny+", nscene="+nscene+", findx="+findx+", windx="+windx+", w="+w);
} else {
s += w;
}
}
}
// double s_y_yhf = s; //
// TODO: If using transparency_weights (in setupYVectorTransparency and getFxDerivs),
// then calculate following weights differently to keep ~ the same sum
// use recalc_average / this.recalc_average to change weights
if (y_avg_len > 0) {
for (int ny = 0; ny < y_avg_len; ny++) {
s += terrain_correction_weight; // scene_weights[nscene] is included in y_wavg and fX, jt
}
}
/// final double s0 = s;
s *= (1+ reg_weights);
final double k = 1.0/s; //corr_transp 10.85811847216958
weight_to_scene_weight = k * s_to_ss;
/// weight_pure = s0/s;
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nw = ai.getAndIncrement(); nw < weights.length; nw = ai.getAndIncrement()) {
if (nw < samples_pointers[SAMPLES_Y_HF][0]) { // DC differences
int ny = nw;
int nscene = y_src[ny][YSRC_SCENE];
int findx = y_src[ny][YSRC_FINDEX];
int windx = getWindexFromFindex(findx);
double w = transparency_weights[nscene][windx] * k;
if (!Double.isNaN(w)) {
weights[nw] = w;
} else {
System.out.println("weights["+nw+"]=NaN - 1");
}
} else if (nw < samples_pointers[SAMPLES_Y_AVG][0]) { // HF differences if exist
int ny = nw-y_src.length;
int nscene = y_src_hf[ny][YSRC_SCENE];
int findx = y_src_hf[ny][YSRC_FINDEX];
int windx = getWindexFromFindex(findx);
double w = transparency_weights[nscene][windx] * k * hifreq_weight; // scene_weights[nscene] * k * hifreq_weight;
if (!Double.isNaN(w)) {
weights[nw] = w;
} else {
System.out.println("weights["+nw+"]=NaN - 2");
}
} else if (nw < samples_pointers[SAMPLES_EXTRA][0]) { // y_wavg if exists
weights[nw] = k * terrain_correction_weight;
if (Double.isNaN(weights[nw])) {
System.out.println("weights["+nw+"]=NaN - 3");
}
/*
} else {
weights[nw] = reg_sample_weight;
if (Double.isNaN(weights[nw])) {
System.out.println("weights["+nw+"]=NaN - 4");
}
*/
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (y_src_hf != null) { // set average offset y - either old way with scene_weights[nscene] or new way with weights[ny]
setupYVectorTransparency();
}
return;
}
private void setupYVector(
boolean use_terr_corr,
double [] scene_weights) {
......@@ -4737,11 +5055,83 @@ public class VegetationLMA {
return;
}
private void setupYVectorTransparency() { // this.recalc_average should be already set
// boolean use_transparency) {
// this.recalc_average = use_transparency;
final int dbg_windx = -142;
final int woi_length = woi.width*woi.height;
final int terr_start = y_src.length + ((y_src_hf != null)? y_src_hf.length : 0);
// final int ds_length = terr_start + (use_terr_corr? woi_length: 0);
// final int ds_length = terr_start + woi_length;
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger ati = new AtomicInteger(0);
final double [][] y_wavg_threads = new double [threads.length][woi_length];
// y_wavg = new double[woi_length];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
int nthread = ati.getAndIncrement();
public void run() {
for (int ny = ai.getAndIncrement(); ny < y_src.length; ny = ai.getAndIncrement()) {
int nscene = y_src[ny][YSRC_SCENE];
int indx = y_src[ny][YSRC_FINDEX];
int windx = getWindexFromFindex(indx);
// double d =y_vector[ny] * scene_weights[nscene];
double w = recalc_average ? (weights[ny] / weight_to_scene_weight): scene_weights[nscene];
w *= terrain_correction;
double d =y_vector[ny] * w;
if (Double.isNaN(d)) {
System.out.println("y_vector["+ny+"]*scene_weights["+nscene+"]=NaN");
}
y_wavg_threads[nthread][windx] += d;
if (windx== dbg_windx) {
System.out.println("setupYVector(): nscene="+nscene+", nthread="+nthread+
" y_vector["+ny+"]="+y_vector[ny]+" scene_weights["+nscene+"]="+scene_weights[nscene]+" d="+d);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int wIndx = ai.getAndIncrement(); wIndx < woi_length; wIndx = ai.getAndIncrement()) {
double swy = 0;
if (wIndx== dbg_windx) {
System.out.println("setupYVector(): wIndx="+wIndx);
}
for (int nthread = 0; nthread < threads.length; nthread++) {
swy +=y_wavg_threads[nthread][wIndx];
}
if (Double.isNaN(swy)) {
System.out.println("y_vector["+(wIndx+terr_start)+"]=NaN");
}
y_vector[wIndx+terr_start] = swy; // /sw; (fX uses the same weights)
}
}
};
}
ImageDtt.startAndJoin(threads);
return;
}
private int getWindexFromFindex(int findex) {
int wx = (findex % full.width) - woi.x;
int wy = (findex / full.width) - woi.y;
return wx + wy*woi.width;
}
private int getFindexFromWindex(int windex) {
int x = (windex % woi.width) + woi.x;
int y = (windex / woi.width) + woi.y;
return x + y*full.width;
}
/*
private void setupYWavg( double [] scene_weights) {
final int woi_length = woi.width*woi.height;
......@@ -4791,8 +5181,8 @@ public class VegetationLMA {
*/
private int [][] getNeighbors(
final int tvao, // TVAO_VEGETATION_ALPHA
final int ind_samples, // ind_pars_vegetation_alpha
final int num_samples // num_pars_vegetation_alpha
final int ind_samples, // ind_pars[TVAO_VEGETATION]_alpha
final int num_samples // num_pars[TVAO_VEGETATION]_alpha
){
final int [][] alpha_neibs = new int[num_samples][4];
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
......@@ -4821,7 +5211,7 @@ public class VegetationLMA {
};
}
ImageDtt.startAndJoin(threads);
//ind_pars_vegetation_alpha
//ind_pars[TVAO_VEGETATION]_alpha
return alpha_neibs;
}
......@@ -4967,7 +5357,7 @@ public class VegetationLMA {
Arrays.fill(par_index[TVAO_ELEVATION], -1);
Arrays.fill(par_index[TVAO_SCENE_OFFSET],-1);
int par_num = 0;
ind_pars_terrain = 0;
ind_pars[TVAO_TERRAIN] = 0;
if (fits[TVAO_TERRAIN]) {
for (int drow = 0; drow < woi.height; drow++) { // use inner woi for terrain
int row = woi.y + drow;
......@@ -4983,8 +5373,8 @@ public class VegetationLMA {
}
}
}
num_pars_terrain = par_num;
ind_pars_vegetation = par_num;
num_pars[TVAO_TERRAIN] = par_num;
ind_pars[TVAO_VEGETATION] = par_num;
if (fits[TVAO_VEGETATION]) {
for (int drow = 0; drow < woi_veg.height; drow++) {
......@@ -5003,8 +5393,8 @@ public class VegetationLMA {
}
}
}
ind_pars_alpha = par_num;
num_pars_vegetation = par_num - ind_pars_vegetation;
ind_pars[TVAO_ALPHA] = par_num;
num_pars[TVAO_VEGETATION] = par_num - ind_pars[TVAO_VEGETATION];
if (fits[TVAO_ALPHA]) {
for (int drow = 0; drow < woi_veg.height; drow++) {
int row = woi_veg.y + drow;
......@@ -5022,8 +5412,8 @@ public class VegetationLMA {
}
}
}
num_pars_alpha = par_num - ind_pars_alpha; // normally should be == num_pars_vegetation
ind_pars_elevation = par_num;
num_pars[TVAO_ALPHA] = par_num - ind_pars[TVAO_ALPHA]; // normally should be == num_pars[TVAO_VEGETATION]
ind_pars[TVAO_ELEVATION] = par_num;
if (fits[TVAO_ELEVATION]) {
for (int drow = 0; drow < woi_veg.height; drow++) {
int row = woi_veg.y + drow;
......@@ -5041,8 +5431,8 @@ public class VegetationLMA {
}
}
}
num_pars_elevation = par_num - ind_pars_elevation; // normally should be == num_pars_vegetation
ind_pars_scenes = par_num;
num_pars[TVAO_ELEVATION] = par_num - ind_pars[TVAO_ELEVATION]; // normally should be == num_pars[TVAO_VEGETATION]
ind_pars[TVAO_SCENE_OFFSET] = par_num;
if (fits[TVAO_SCENE_OFFSET]) {
for (int nscene = 0; nscene < num_scenes; nscene++) {
if (valid_scenes [nscene]) {
......@@ -5052,7 +5442,7 @@ public class VegetationLMA {
}
}
}
num_pars_scenes = par_num - ind_pars_scenes;
num_pars[TVAO_SCENE_OFFSET] = par_num - ind_pars[TVAO_SCENE_OFFSET];
this.par_rindex = new int [par_num][2];
System.arraycopy(par_rindex, 0, this.par_rindex, 0, par_num);
parameters_vector = new double [par_num];
......@@ -5752,8 +6142,86 @@ public class VegetationLMA {
return max_warps;
}
private boolean disabledParams() {
for (boolean dis:fits_disable) if (dis){
return true;
}
return false;
}
/**
* Convert from full parameter index to decimated parameter index (and vice versa)
* @return [0] - decimated parameter index for full parameter index (-1 for missing ones)
* [1] - full parameter index for decimated index
*/
private int [][] getParsAllDecimatedAllIndices() {
int [] num_pars_decim = new int [TVAO_TYPES];
int [] ind_pars_decim = new int [TVAO_TYPES];
int ind_next = 0;
for (int typ = 0; typ < TVAO_TYPES; typ++) {
ind_pars_decim[typ] = ind_next;
int len = fits_disable[typ]? 0 : num_pars[typ];
num_pars_decim[typ] = len;
ind_next += len;
}
int [][] pars_map = new int [2][];
pars_map[0] = new int[par_rindex.length];
Arrays.fill(pars_map[0], -1);
pars_map[1] = new int[ind_next]; // number of parameters after decimation
for (int typ = 0; typ < TVAO_TYPES; typ++) if (num_pars_decim[typ] > 0) {
for (int i = 0; i < num_pars_decim[typ]; i++) {
int indx_all = ind_pars[typ];
int indx_decim = ind_pars_decim[typ];
pars_map[0][indx_all + i] = indx_decim+i;
pars_map[1][indx_decim + i] = indx_all+i;
}
}
return pars_map; // [0] - full parameter index to decimated parameter index (-1 - none), [1] decimated index to full index
}
public static double [][] decimateJt(
final int [][] par_map, // // only [1] used
final double [][] jt_full) {
if (par_map == null) {
return jt_full;
}
final double [][] jt = new double [par_map[1].length][jt_full[0].length];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int indx_decim = ai.getAndIncrement(); indx_decim < jt.length; indx_decim = ai.getAndIncrement()) {
jt[indx_decim] = jt_full[par_map[1][indx_decim]];
}
}
};
}
ImageDtt.startAndJoin(threads);
return jt;
}
public static double [] expandDecimated(
final int [][] par_map, // only [0] used
final double [] data_decimated) {
if (par_map == null) {
return data_decimated;
}
final double [] data_full = new double [par_map[0].length];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int indx_decim = ai.getAndIncrement(); indx_decim < data_decimated.length; indx_decim = ai.getAndIncrement()) {
int indx = par_map[0][indx_decim];
data_full[indx_decim] = (indx >= 0) ? data_decimated[indx] : 0.0;
}
}
};
}
ImageDtt.startAndJoin(threads);
return data_full;
}
}
......@@ -1450,6 +1450,8 @@ public class VegetationModel {
boolean fit_scenes = clt_parameters.imp.terr_fit_scenes; // true; // adjust scene offsets (start from 0 always?)
boolean fit_elevations = clt_parameters.imp.terr_fit_elevations; // false; // adjust elevation pixels (not yet implemented)
boolean [] fit_disable = clt_parameters.imp.terr_fit_disable.clone();
double reg_weights = clt_parameters.imp.terr_reg_weights; // 0.25; // fraction of the total weight used for regularization
double lambda = clt_parameters.imp.terr_lambda; // 5.0; // 0.1;
double lambda_scale_good = clt_parameters.imp.terr_lambda_scale_good; // 0.5;
......@@ -1480,7 +1482,12 @@ public class VegetationModel {
boolean show_final_result = !tile_woi; // true; (maybe make saving results in tiled mode?
boolean recalc_weights = clt_parameters.imp.terr_recalc_weights ; //false; // recalculate weight depending on terrain visibility
double transparency_opaque = 1.0 - clt_parameters.imp.terr_recalc_opaque ; // 0.9; // above is opaque
double transparency_pedestal = clt_parameters.imp.terr_recalc_pedestal ; // 0.05; // weight of opaque tiles
double transparency_frac = clt_parameters.imp.terr_recalc_frac ; // 1.0; // increase weight for far pixels (double if scale differece == this)
double transparency_dist = clt_parameters.imp.terr_recalc_dist ; // 0.05; // weight of opaque tiles
boolean recalc_average = clt_parameters.imp.terr_recalc_average ; //false; // apply transparency to average mismatch
//clt_parameters.imp.; //
......@@ -2005,6 +2012,7 @@ public class VegetationModel {
fit_alpha, // final boolean adjust_alpha,
fit_scenes, // final boolean adjust_scenes,
fit_elevations, // final boolean adjust_elevations,
fit_disable, // final boolean [] fit_disable,
reg_weights, // final double reg_weights, // fraction of the total weight used for regularization
alpha_loss, // final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0
alpha_offset, // final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0
......@@ -2059,6 +2067,15 @@ public class VegetationModel {
par_path, // String path,
true, // boolean keep_settings,
null); // Rectangle [] file_wois); // if not null, should be Rectangle[2] {woi_veg,woi} - will return woi data and not input parameters to this instance
if (recalc_weights) {
vegetationLMA.applyTransparency(
null, // final double [] vector,
transparency_opaque, // final double transparency_opaque,
transparency_pedestal, // final double transparency_pedestal,
transparency_frac, // final double transparency_frac,
transparency_dist, // final double transparency_dist,
recalc_average); // final boolean recalc_average);
}
}
// old
if ("RESTORE".equals(par_path)) {
......@@ -2074,7 +2091,7 @@ public class VegetationModel {
}
}
if ((show_final_result) && (debugLevel > 0)) {
if ((show_final_result) && (debugLevel > -2)) { // 0)) {
String reconstructed_title = reference_scene+"-reconstructed-initial";
vegetationLMA.showYfX(
null, // double [] vector,
......@@ -2127,6 +2144,16 @@ public class VegetationModel {
elev_pull0 *= 0.01;
vegetationLMA.elevation_pull0 = elev_pull0;
if (recalc_weights) {
vegetationLMA.applyTransparency(
null, // final double [] vector,
transparency_opaque, // final double transparency_opaque,
transparency_pedestal, // final double transparency_pedestal,
transparency_frac, // final double transparency_frac,
transparency_dist, // final double transparency_dist,
recalc_average); // final boolean recalc_average); }
}
if (debugLevel > -3) {
lma_rslt= vegetationLMA.runLma( // <0 - failed, >=0 iteration number (1 - immediately)
lambda, // double lambda, // 0.1
......
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