aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2023-07-11 12:19:57 +0200
committerThomas White <taw@physics.org>2023-07-28 13:22:05 +0200
commita9b02587f2381c2168745f4074b57f87b8abd26c (patch)
tree792a5633cc4c6cd45c0a10ac7519271aebd211d7 /libcrystfel/src
parente2fe7137e7994b11bfce1f3a74af8f5ec9025b48 (diff)
Fix iterate() for prediction refinement
I was confused when I wrote acd0de4e4a21, and completely broke the maths. To fix it, I copied the guts of iterate() back from the old version and re-created the intermediate steps - switching x/y to fs/ss, calculating fs/ss gradients together and the hooks for Minv.
Diffstat (limited to 'libcrystfel/src')
-rw-r--r--libcrystfel/src/predict-refine.c90
1 files changed, 67 insertions, 23 deletions
diff --git a/libcrystfel/src/predict-refine.c b/libcrystfel/src/predict-refine.c
index b87173b7..d5838e06 100644
--- a/libcrystfel/src/predict-refine.c
+++ b/libcrystfel/src/predict-refine.c
@@ -592,9 +592,7 @@ static int iterate(struct reflpeak *rps, int n, UnitCell *cell,
double asx, asy, asz;
double bsx, bsy, bsz;
double csx, csy, csz;
-
- const enum gparam rv[] =
- {
+ const enum gparam rv[] = {
GPARAM_ASX,
GPARAM_ASY,
GPARAM_ASZ,
@@ -605,7 +603,7 @@ static int iterate(struct reflpeak *rps, int n, UnitCell *cell,
GPARAM_CSY,
GPARAM_CSZ,
};
- int num_params = 9;
+ const int num_params = 9;
/* Number of parameters to refine */
M = gsl_matrix_calloc(num_params, num_params);
@@ -614,25 +612,48 @@ static int iterate(struct reflpeak *rps, int n, UnitCell *cell,
for ( i=0; i<n; i++ ) {
int k;
- double r_gradients[num_params];
float fs_gradients[num_params];
float ss_gradients[num_params];
+ float r_gradients[num_params];
double w;
- w = rps[i].Ih;
+ /* Calculate all gradients for this parameter */
+ for ( k=0; k<num_params; k++ ) {
+ int pn = rps[i].peak->pn;
+ r_gradients[k] = r_gradient(rv[k], rps[i].refl, cell, image->lambda);
+ fs_ss_gradient(rv[k], rps[i].refl, cell, &image->detgeom->panels[pn],
+ Minvs[pn], 0, 0, 0, &fs_gradients[k], &ss_gradients[k]);
+ }
- /* Calculate the gradients w.r.t. all parameters, for the
- * three measurements (r, fs, ss) of this reflpeak */
+ /* Excitation error terms */
+ w = EXC_WEIGHT * rps[i].Ih;
for ( k=0; k<num_params; k++ ) {
- r_gradients[k] = r_gradient(rv[k], rps[i].refl, cell,
- image->lambda);
- fs_ss_gradient(rv[k], rps[i].refl, cell,
- &image->detgeom->panels[rps[i].peak->pn],
- Minvs[rps[i].peak->pn], 0, 0, 0,
- &fs_gradients[k], &ss_gradients[k]);
+
+ int g;
+ double v_c, v_curr;
+
+ for ( g=0; g<num_params; g++ ) {
+
+ double M_c, M_curr;
+
+ /* Matrix is symmetric */
+ if ( g > k ) continue;
+
+ M_c = w * r_gradients[g] * r_gradients[k];
+ M_curr = gsl_matrix_get(M, k, g);
+ gsl_matrix_set(M, k, g, M_curr + M_c);
+ gsl_matrix_set(M, g, k, M_curr + M_c);
+
+ }
+
+ v_c = w * r_dev(&rps[i]);
+ v_c *= -r_gradients[k];
+ v_curr = gsl_vector_get(v, k);
+ gsl_vector_set(v, k, v_curr + v_c);
}
+ /* Positional fs terms */
for ( k=0; k<num_params; k++ ) {
int g;
@@ -645,18 +666,42 @@ static int iterate(struct reflpeak *rps, int n, UnitCell *cell,
/* Matrix is symmetric */
if ( g > k ) continue;
- M_c = w * r_gradients[g] * r_gradients[k];
- M_c += w * fs_gradients[g] * fs_gradients[k];
- M_c += w * ss_gradients[g] * ss_gradients[k];
+ M_c = fs_gradients[g] * fs_gradients[k];
+ M_curr = gsl_matrix_get(M, k, g);
+ gsl_matrix_set(M, k, g, M_curr + M_c);
+ gsl_matrix_set(M, g, k, M_curr + M_c);
+
+ }
+
+ v_c = fs_dev(&rps[i], image->detgeom);
+ v_c *= -fs_gradients[k];
+ v_curr = gsl_vector_get(v, k);
+ gsl_vector_set(v, k, v_curr + v_c);
+
+ }
+
+ /* Positional ss terms */
+ for ( k=0; k<num_params; k++ ) {
+
+ int g;
+ double v_c, v_curr;
+
+ for ( g=0; g<num_params; g++ ) {
+
+ double M_c, M_curr;
+
+ /* Matrix is symmetric */
+ if ( g > k ) continue;
+
+ M_c = ss_gradients[g] * ss_gradients[k];
M_curr = gsl_matrix_get(M, k, g);
gsl_matrix_set(M, k, g, M_curr + M_c);
gsl_matrix_set(M, g, k, M_curr + M_c);
}
- v_c = -w * r_dev(&rps[i]) * r_gradients[k];
- v_c += -fs_dev(&rps[i], image->detgeom) * fs_gradients[k];
- v_c += -ss_dev(&rps[i], image->detgeom) * ss_gradients[k];
+ v_c = ss_dev(&rps[i], image->detgeom);
+ v_c *= -ss_gradients[k];
v_curr = gsl_vector_get(v, k);
gsl_vector_set(v, k, v_curr + v_c);
@@ -666,9 +711,8 @@ static int iterate(struct reflpeak *rps, int n, UnitCell *cell,
int k;
for ( k=0; k<num_params; k++ ) {
- double M_curr;
- M_curr = gsl_matrix_get(M, k, k);
- gsl_matrix_set(M, k, k, M_curr);
+ double M_curr = gsl_matrix_get(M, k, k);
+ gsl_matrix_set(M, k, k, M_curr+1e-18);
}
//show_matrix_eqn(M, v);