aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt5
-rw-r--r--tests/cellcompare_check.c403
-rw-r--r--tests/transformation_check.c2
3 files changed, 409 insertions, 1 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 192913ce..bd9959ae 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -92,3 +92,8 @@ add_executable(spectrum_check spectrum_check.c)
target_include_directories(spectrum_check PRIVATE ${COMMON_INCLUDES})
target_link_libraries(spectrum_check ${COMMON_LIBRARIES})
add_test(spectrum_check spectrum_check)
+
+add_executable(cellcompare_check cellcompare_check.c)
+target_include_directories(cellcompare_check PRIVATE ${COMMON_INCLUDES})
+target_link_libraries(cellcompare_check ${COMMON_LIBRARIES})
+add_test(cellcompare_check cellcompare_check)
diff --git a/tests/cellcompare_check.c b/tests/cellcompare_check.c
new file mode 100644
index 00000000..f674a7f2
--- /dev/null
+++ b/tests/cellcompare_check.c
@@ -0,0 +1,403 @@
+/*
+ * cellcompare_check.c
+ *
+ * Check that unit cell comparison works
+ *
+ * Copyright © 2019 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2019 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <gsl/gsl_randist.h>
+
+#include <cell.h>
+#include <cell-utils.h>
+#include <utils.h>
+
+
+static void complain(UnitCell *cell, UnitCell *cref, const char *t, const char *c)
+{
+ STATUS("These cells should %sbe the same%s:\n", t, c);
+ STATUS("Transformed: ----------------------------\n");
+ cell_print_full(cell);
+ STATUS("Original: ---------------------------\n");
+ cell_print_full(cref);
+}
+
+
+static RationalMatrix *random_derivative(gsl_rng *rng)
+{
+ int i, j;
+ RationalMatrix *tr;
+
+ tr = rtnl_mtx_new(3, 3);
+ if ( tr == NULL ) return NULL;
+
+ do {
+ for ( i=0; i<3; i++ ) {
+ for ( j=0; j<3; j++ ) {
+ /* 0..6 inclusive -> -3..3 inclusive */
+ signed int a = gsl_rng_uniform_int(rng, 7) - 3;
+ /* 0..2 inclusive */
+ signed int b = gsl_rng_uniform_int(rng, 3);
+ if ( b == 0 ) {
+ a = 0;
+ b = 1;
+ }
+ rtnl_mtx_set(tr, i, j, rtnl(a, b));
+ }
+ }
+
+ } while ( rtnl_cmp(rtnl_mtx_det(tr), rtnl_zero()) == 0 );
+
+ return tr;
+}
+
+
+static IntegerMatrix *random_permutation(gsl_rng *rng)
+{
+ int i;
+ IntegerMatrix *tr;
+ int v[] = {0, 1, 2};
+
+ tr = intmat_new(3, 3);
+ if ( tr == NULL ) return NULL;
+
+ gsl_ran_shuffle(rng, v, 3, sizeof(int));
+ for ( i=0; i<3; i++ ) {
+ intmat_set(tr, i, v[i], 1);
+ }
+
+ return tr;
+}
+
+
+static int check_ccp(UnitCell *cell, UnitCell *cref, double *tols,
+ int should_match)
+{
+ const char *a;
+ const char *b;
+
+ a = should_match ? "" : "NOT ";
+ b = " with compare_cell_parameters";
+
+ if ( compare_cell_parameters(cell, cref, tols) != should_match )
+ {
+ complain(cell, cref, a, b);
+ return 1;
+ }
+ return 0;
+}
+
+
+static int check_ccpao(UnitCell *cell, UnitCell *cref, double *tols,
+ int should_match)
+{
+ const char *a;
+ const char *b;
+
+ a = should_match ? "" : "NOT ";
+ b = " with compare_cell_parameters_and_orientation";
+
+ if ( compare_cell_parameters_and_orientation(cell, cref,
+ tols) != should_match )
+ {
+ complain(cell, cref, a, b);
+ return 1;
+ }
+ return 0;
+}
+
+
+static int check_cpcpao(UnitCell *cell, UnitCell *cref, double *tols,
+ int should_match)
+{
+ IntegerMatrix *m = NULL;
+ const char *a;
+ const char *b;
+
+ a = should_match ? "" : "NOT ";
+ b = " with compare_permuted_cell_parameters_and_orientation";
+
+ if ( compare_permuted_cell_parameters_and_orientation(cell, cref, tols, &m)
+ != should_match )
+ {
+ complain(cell, cref, a, b);
+ intmat_free(m);
+ return 1;
+ }
+ intmat_free(m);
+ return 0;
+}
+
+
+static int check_cdcp(UnitCell *cell, UnitCell *cref, double *tols,
+ RationalMatrix *tr, int should_match)
+{
+ RationalMatrix *m = NULL;
+ const char *a;
+ const char *b;
+
+ a = should_match ? "" : "NOT ";
+ b = " with compare_derivative_cell_parameters";
+
+ if ( compare_derivative_cell_parameters(cref, cell, tols, 1, &m) != should_match )
+ {
+ complain(cell, cref, a, b);
+ STATUS("The transformation matrix to create the cell was:\n");
+ rtnl_mtx_print(tr);
+ STATUS("Cell comparison says do this to the reference to "
+ "create the cell:\n");
+ rtnl_mtx_print(m);
+ rtnl_mtx_free(m);
+ return 1;
+ }
+ rtnl_mtx_free(m);
+ return 0;
+}
+
+
+static int check_crcp(UnitCell *cell, UnitCell *cref, double *tols,
+ RationalMatrix *tr, int should_match)
+{
+ RationalMatrix *m = NULL;
+ const char *a;
+ const char *b;
+ UnitCell *match;
+
+ a = should_match ? "" : "NOT ";
+ b = " with compare_reindexed_cell_parameters";
+
+ match = compare_reindexed_cell_parameters(cell, cref, tols, &m);
+
+ if ( (match != NULL) != should_match )
+ {
+ complain(cell, cref, a, b);
+ STATUS("The transformation matrix to create the cell was:\n");
+ rtnl_mtx_print(tr);
+ STATUS("Cell comparison says do this to the reference to "
+ "create the cell:\n");
+ rtnl_mtx_print(m);
+ rtnl_mtx_free(m);
+ return 1;
+ }
+ rtnl_mtx_free(m);
+ return 0;
+}
+
+
+static void yaro_test()
+{
+ UnitCell *cell;
+ UnitCell *reference;
+ UnitCell *cmatch;
+ //float tols[] = {5, 5, 5, 1.5};
+ double dtols[] = {0.05, 0.05, 0.05, deg2rad(5.0), deg2rad(5.0), deg2rad(5.0)};
+
+ cell = cell_new_from_parameters(63.24e-10, 63.94e-10, 64.61e-10,
+ deg2rad(89.98), deg2rad(89.82), deg2rad(119.87));
+ cell_set_unique_axis(cell, 'c');
+ cell_set_lattice_type(cell, L_HEXAGONAL);
+ cell_set_centering(cell, 'P');
+
+ reference = cell_new_from_parameters(64.7e-10, 64.7e-10, 65.2e-10,
+ deg2rad(90.0), deg2rad(90.0), deg2rad(120.0));
+ cell_set_unique_axis(reference, 'c');
+ cell_set_lattice_type(reference, L_HEXAGONAL);
+ cell_set_centering(reference, 'P');
+
+ STATUS("The cell:\n");
+ cell_print(cell);
+ STATUS("The reference:\n");
+ cell_print(reference);
+ //cmatch = match_cell(cell, reference, 0, tols, 1);
+ //STATUS("The match:\n");
+ //cell_print(cmatch);
+ //cell_free(cmatch);
+
+ RationalMatrix *m = NULL;
+ cmatch = compare_reindexed_cell_parameters(cell, reference, dtols, &m);
+ STATUS("The new match:\n")
+ cell_print(cmatch);
+ STATUS("The matrix:\n");
+ rtnl_mtx_print(m);
+ cell_free(cmatch);
+ rtnl_mtx_free(m);
+
+ cell_free(cell);
+ cell_free(reference);
+}
+
+
+extern IntegerMatrix *reduce_g6(struct g6 g, double epsrel);
+
+int main(int argc, char *argv[])
+{
+ UnitCell *cell, *cref;
+ gsl_rng *rng;
+ int i;
+ const int ntrial = 10;
+ double tols[] = { 0.01, 0.01, 0.01,
+ deg2rad(1.0), deg2rad(1.0), deg2rad(1.0) };
+
+ rng = gsl_rng_alloc(gsl_rng_mt19937);
+
+ yaro_test();
+
+ cref = cell_new_from_parameters(3e-10, 5.196e-10, 2e-10,
+ deg2rad(103.9166666),
+ deg2rad(109.4666666),
+ deg2rad(134.8833333));
+ cell_set_centering(cref, 'P');
+ if ( cref == NULL ) return 1;
+
+ /* Just rotate cell */
+ for ( i=0; i<ntrial; i++ ) {
+
+ cell = cell_rotate(cref, random_quaternion(rng));
+ if ( cell == NULL ) return 1;
+
+ if ( check_ccp(cell, cref, tols, 1) ) return 1;
+ if ( check_ccpao(cell, cref, tols, 0) ) return 1;
+ if ( check_cpcpao(cell, cref, tols, 0) ) return 1;
+ if ( check_cdcp(cell, cref, tols, NULL, 1) ) return 1;
+ if ( check_crcp(cell, cref, tols, NULL, 1) ) return 1;
+
+ cell_free(cell);
+ progress_bar(i+1, ntrial, "Plain rotation");
+ }
+
+ /* Permute axes but don't rotate */
+ for ( i=0; i<ntrial; i++ ) {
+
+ IntegerMatrix *tr;
+
+ tr = random_permutation(rng);
+ cell = cell_transform_intmat(cref, tr);
+
+ if ( check_ccp(cell, cref, tols, intmat_is_identity(tr)) ) return 1;
+ if ( check_ccpao(cell, cref, tols, intmat_is_identity(tr)) ) return 1;
+ if ( check_cpcpao(cell, cref, tols, 1) ) return 1;
+ if ( check_cdcp(cell, cref, tols, NULL, 1) ) return 1;
+ if ( check_crcp(cell, cref, tols, NULL, 1) ) return 1;
+
+ cell_free(cell);
+ intmat_free(tr);
+ progress_bar(i+1, ntrial, "Axis permutation");
+ }
+
+ /* Rotate cell and permute axes */
+ for ( i=0; i<ntrial; i++ ) {
+
+ IntegerMatrix *tr;
+ UnitCell *cell2;
+
+ cell2 = cell_rotate(cref, random_quaternion(rng));
+ if ( cell2 == NULL ) return 1;
+
+ tr = random_permutation(rng);
+ cell = cell_transform_intmat(cell2, tr);
+ cell_free(cell2);
+
+ if ( check_ccp(cell, cref, tols, intmat_is_identity(tr)) ) return 1;
+ if ( check_ccpao(cell, cref, tols, 0) ) return 1;
+ if ( check_cpcpao(cell, cref, tols, 0) ) return 1;
+ if ( check_cdcp(cell, cref, tols, NULL, 1) ) return 1;
+ if ( check_crcp(cell, cref, tols, NULL, 1) ) return 1;
+
+ cell_free(cell);
+ intmat_free(tr);
+ progress_bar(i+1, ntrial, "Rotation with axis permutation");
+ }
+
+ /* Derivative lattice */
+ for ( i=0; i<ntrial; i++ ) {
+
+ RationalMatrix *tr;
+
+ cell = NULL;
+ tr = NULL;
+ do {
+ cell_free(cell);
+ rtnl_mtx_free(tr);
+ tr = random_derivative(rng);
+ cell = cell_transform_rational(cref, tr);
+ } while ( (cell_get_centering(cell) == '?')
+ || (cell_get_centering(cell) == 'H' ) );
+ /* H centering is no good because it needs a unique axis to
+ * be specified in order for uncentering in c_r_c_p to work.
+ * cell_transform_rational doesn't set the unique axis (yet?) */
+
+ if ( check_ccp(cell, cref, tols, rtnl_mtx_is_identity(tr)) ) return 1;
+ if ( check_ccpao(cell, cref, tols, rtnl_mtx_is_identity(tr)) ) return 1;
+ if ( check_cpcpao(cell, cref, tols, rtnl_mtx_is_perm(tr)) ) return 1;
+ if ( check_cdcp(cell, cref, tols, tr, 1) ) return 1;
+ /* check_crcp: Sometimes yes, hard to tell */
+
+ cell_free(cell);
+ rtnl_mtx_free(tr);
+ progress_bar(i+1, ntrial, "Derivative lattice");
+ }
+
+ /* Derivative lattice and rotate */
+ for ( i=0; i<ntrial; i++ ) {
+
+ RationalMatrix *tr;
+ UnitCell *cell2;
+
+ cell2 = cell_rotate(cref, random_quaternion(rng));
+ if ( cell2 == NULL ) return 1;
+
+ cell = NULL;
+ tr = NULL;
+ do {
+ cell_free(cell);
+ rtnl_mtx_free(tr);
+ tr = random_derivative(rng);
+ cell = cell_transform_rational(cell2, tr);
+ } while ( (cell_get_centering(cell) == '?')
+ || (cell_get_centering(cell) == 'H' ) ); /* See above */
+ cell_free(cell2);
+
+ if ( check_ccp(cell, cref, tols, rtnl_mtx_is_identity(tr)) ) return 1;
+ if ( check_ccpao(cell, cref, tols, 0) ) return 1;
+ if ( check_cpcpao(cell, cref, tols, 0) ) return 1;
+ if ( check_cdcp(cell, cref, tols, tr, 1) ) return 1;
+ /* check_crcp: Sometimes yes, hard to tell */
+
+ cell_free(cell);
+ rtnl_mtx_free(tr);
+ progress_bar(i+1, ntrial, "Derivative lattice with rotation");
+ }
+
+ cell_free(cref);
+ gsl_rng_free(rng);
+
+ return 0;
+}
diff --git a/tests/transformation_check.c b/tests/transformation_check.c
index 33f44340..8c8f7fa0 100644
--- a/tests/transformation_check.c
+++ b/tests/transformation_check.c
@@ -396,7 +396,7 @@ int main(int argc, char *argv[])
intmat_set_all_3x3(part2, 0,0,1,
0,1,0,
-1,0,0);
- tfn = intmat_intmat_mult(part1, part2);
+ tfn = intmat_times_intmat(part1, part2);
fail += check_identity(cell, tfn);
intmat_free(part1);
intmat_free(part2);