diff options
-rw-r--r-- | libcrystfel/src/cell-utils.c | 111 | ||||
-rw-r--r-- | libcrystfel/src/cell.c | 2 | ||||
-rw-r--r-- | tests/centering_check.c | 48 |
3 files changed, 109 insertions, 52 deletions
diff --git a/libcrystfel/src/cell-utils.c b/libcrystfel/src/cell-utils.c index 12443c8d..f3eb7c16 100644 --- a/libcrystfel/src/cell-utils.c +++ b/libcrystfel/src/cell-utils.c @@ -252,16 +252,19 @@ int bravais_lattice(UnitCell *cell) case 'B' : case 'C' : if ( lattice == L_MONOCLINIC ) { - if ( (ua=='a') && (centering=='A') ) return 1; - if ( (ua=='b') && (centering=='B') ) return 1; - if ( (ua=='c') && (centering=='C') ) return 1; + if ( (ua=='a') && (centering!='A') ) return 1; + if ( (ua=='b') && (centering!='B') ) return 1; + if ( (ua=='c') && (centering!='C') ) return 1; } else if ( lattice == L_ORTHORHOMBIC) { return 1; } return 0; case 'I' : - if ( (lattice == L_ORTHORHOMBIC) + /* We accept monoclinic I as "Bravais", even though it's + * unconventional */ + if ( (lattice == L_MONOCLINIC) + || (lattice == L_ORTHORHOMBIC) || (lattice == L_TETRAGONAL) || (lattice == L_CUBIC) ) { @@ -313,15 +316,31 @@ static UnitCellTransformation *uncentering_transformation(UnitCell *in, if ( t == NULL ) return NULL; if ( ua == 'a' ) { - tfn_combine(t, tfn_vector(0,0,1), - tfn_vector(0,1,0), - tfn_vector(-1,0,0)); + tfn_combine(t, tfn_vector(0,1,0), + tfn_vector(0,0,1), + tfn_vector(1,0,0)); + if ( lt == L_MONOCLINIC ) { + assert(cen != 'A'); + switch ( cen ) { + case 'B' : cen = 'A'; break; + case 'C' : cen = 'B'; break; + case 'I' : cen = 'I'; break; + } + } } if ( ua == 'b' ) { - tfn_combine(t, tfn_vector(1,0,0), - tfn_vector(0,0,1), - tfn_vector(0,-1,0)); + tfn_combine(t, tfn_vector(0,0,1), + tfn_vector(1,0,0), + tfn_vector(0,1,0)); + if ( lt == L_MONOCLINIC ) { + assert(cen != 'B'); + switch ( cen ) { + case 'C' : cen = 'A'; break; + case 'A' : cen = 'B'; break; + case 'I' : cen = 'I'; break; + } + } } switch ( cen ) { @@ -365,12 +384,38 @@ static UnitCellTransformation *uncentering_transformation(UnitCell *in, break; case 'A' : + tfn_combine(t, tfn_vector( 1, 0, 0), + tfn_vector( 0, H, H), + tfn_vector( 0,-H, H)); + if ( lt == L_ORTHORHOMBIC ) { + *new_latt = L_MONOCLINIC; + } else { + *new_latt = L_TRICLINIC; + } + *new_centering = 'P'; + break; + case 'B' : + tfn_combine(t, tfn_vector( H, 0, H), + tfn_vector( 0, 1, 0), + tfn_vector(-H, 0, H)); + if ( lt == L_ORTHORHOMBIC ) { + *new_latt = L_MONOCLINIC; + } else { + *new_latt = L_TRICLINIC; + } + *new_centering = 'P'; + break; + case 'C' : - tfn_combine(t, tfn_vector(H,H,0), - tfn_vector(-H,H,0), - tfn_vector(0,0,1)); - *new_latt = L_MONOCLINIC; + tfn_combine(t, tfn_vector( H, H, 0), + tfn_vector(-H, H, 0), + tfn_vector( 0, 0, 1)); + if ( lt == L_ORTHORHOMBIC ) { + *new_latt = L_MONOCLINIC; + } else { + *new_latt = L_TRICLINIC; + } *new_centering = 'P'; break; @@ -394,15 +439,15 @@ static UnitCellTransformation *uncentering_transformation(UnitCell *in, * transformation */ if ( !((cen=='H') && (*new_latt == L_RHOMBOHEDRAL)) ) { if ( ua == 'a' ) { - tfn_combine(t, tfn_vector(0,0,-1), - tfn_vector(0,1,0), - tfn_vector(1,0,0)); + tfn_combine(t, tfn_vector(0,0,1), + tfn_vector(1,0,0), + tfn_vector(0,1,0)); } if ( ua == 'b' ) { - tfn_combine(t, tfn_vector(1,0,0), - tfn_vector(0,0,-1), - tfn_vector(0,1,0)); + tfn_combine(t, tfn_vector(0,1,0), + tfn_vector(0,0,1), + tfn_vector(1,0,0)); } } @@ -933,6 +978,7 @@ static void determine_lattice(UnitCell *cell, /* Orthorhombic. Unique axis irrelevant, but point group * can have different orientations. */ cell_set_lattice_type(cell, L_ORTHORHOMBIC); + cell_set_unique_axis(cell, '*'); return; } @@ -1201,19 +1247,18 @@ int validate_cell(UnitCell *cell) err = 1; } - cen = cell_get_centering(cell); - ua = cell_get_unique_axis(cell); - if ( (cen == 'A') && (ua != 'a') ) { - ERROR("WARNING: centering doesn't match unique axis.\n"); - err = 1; - } - if ( (cen == 'B') && (ua != 'b') ) { - ERROR("WARNING: centering doesn't match unique axis.\n"); - err = 1; - } - if ( (cen == 'C') && (ua != 'c') ) { - ERROR("WARNING: centering doesn't match unique axis.\n"); - err = 1; + /* For monoclinic A, B or C centering, the unique axis must be something + * other than the centering. */ + if ( cell_get_lattice_type(cell) == L_MONOCLINIC ) { + cen = cell_get_centering(cell); + ua = cell_get_unique_axis(cell); + if ( ((cen == 'A') && (ua == 'a')) + || ((cen == 'B') && (ua == 'b')) + || ((cen == 'C') && (ua == 'c')) ) { + ERROR("WARNING: A, B or C centering matches unique" + " axis.\n"); + err = 1; + } } return err; diff --git a/libcrystfel/src/cell.c b/libcrystfel/src/cell.c index 8c14cce4..44c767f0 100644 --- a/libcrystfel/src/cell.c +++ b/libcrystfel/src/cell.c @@ -125,7 +125,7 @@ UnitCell *cell_new() cell->pointgroup = strdup("1"); cell->lattice_type = L_TRICLINIC; cell->centering = 'P'; - cell->unique_axis = 'c'; + cell->unique_axis = '?'; return cell; } diff --git a/tests/centering_check.c b/tests/centering_check.c index e17915d3..f4073072 100644 --- a/tests/centering_check.c +++ b/tests/centering_check.c @@ -212,17 +212,29 @@ int main(int argc, char *argv[]) fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 100.0, L_MONOCLINIC, 'P', 'c'); - /* Monoclinic A */ + /* Monoclinic "C"-centered, unique axis a, three cell choices */ fail += check_centering(10e-10, 20e-10, 30e-10, 100.0, 90.0, 90.0, - L_MONOCLINIC, 'A', 'a'); + L_MONOCLINIC, 'B', 'a'); + fail += check_centering(10e-10, 20e-10, 30e-10, 100.0, 90.0, 90.0, + L_MONOCLINIC, 'C', 'a'); + fail += check_centering(10e-10, 20e-10, 30e-10, 100.0, 90.0, 90.0, + L_MONOCLINIC, 'I', 'a'); - /* Monoclinic B */ + /* Monoclinic "C"-centered, unique axis b, three cell choices */ + fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 100.0, 90.0, + L_MONOCLINIC, 'C', 'b'); fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 100.0, 90.0, - L_MONOCLINIC, 'B', 'b'); + L_MONOCLINIC, 'A', 'b'); + fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 100.0, 90.0, + L_MONOCLINIC, 'I', 'b'); - /* Monoclinic C */ + /* Monoclinic "C"-centered, unique axis c, three cell choices */ + fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 100.0, + L_MONOCLINIC, 'A', 'c'); + fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 100.0, + L_MONOCLINIC, 'B', 'c'); fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 100.0, - L_MONOCLINIC, 'C', 'c'); + L_MONOCLINIC, 'I', 'c'); /* Orthorhombic P */ fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, @@ -230,15 +242,15 @@ int main(int argc, char *argv[]) /* Orthorhombic A */ fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, - L_ORTHORHOMBIC, 'A', 'a'); + L_ORTHORHOMBIC, 'A', '*'); /* Orthorhombic B */ fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, - L_ORTHORHOMBIC, 'B', 'b'); + L_ORTHORHOMBIC, 'B', '*'); /* Orthorhombic C */ fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, - L_ORTHORHOMBIC, 'C', 'c'); + L_ORTHORHOMBIC, 'C', '*'); /* Orthorhombic I */ fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, @@ -249,19 +261,19 @@ int main(int argc, char *argv[]) L_ORTHORHOMBIC, 'F', '*'); /* Tetragonal P */ - fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, + fail += check_centering(10e-10, 30e-10, 30e-10, 90.0, 90.0, 90.0, L_TETRAGONAL, 'P', 'a'); - fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, + fail += check_centering(30e-10, 10e-10, 30e-10, 90.0, 90.0, 90.0, L_TETRAGONAL, 'P', 'b'); - fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, + fail += check_centering(30e-10, 30e-10, 10e-10, 90.0, 90.0, 90.0, L_TETRAGONAL, 'P', 'c'); /* Tetragonal I */ - fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, + fail += check_centering(10e-10, 30e-10, 30e-10, 90.0, 90.0, 90.0, L_TETRAGONAL, 'I', 'a'); - fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, + fail += check_centering(30e-10, 10e-10, 30e-10, 90.0, 90.0, 90.0, L_TETRAGONAL, 'I', 'b'); - fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 90.0, + fail += check_centering(30e-10, 30e-10, 10e-10, 90.0, 90.0, 90.0, L_TETRAGONAL, 'I', 'c'); /* Rhombohedral R */ @@ -269,11 +281,11 @@ int main(int argc, char *argv[]) L_RHOMBOHEDRAL, 'R', '*'); /* Hexagonal P */ - fail += check_centering(10e-10, 20e-10, 30e-10, 120.0, 90.0, 90.0, + fail += check_centering(30e-10, 10e-10, 10e-10, 120.0, 90.0, 90.0, L_HEXAGONAL, 'P', 'a'); - fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 120.0, 90.0, + fail += check_centering(10e-10, 30e-10, 10e-10, 90.0, 120.0, 90.0, L_HEXAGONAL, 'P', 'b'); - fail += check_centering(10e-10, 20e-10, 30e-10, 90.0, 90.0, 120.0, + fail += check_centering(10e-10, 10e-10, 30e-10, 90.0, 90.0, 120.0, L_HEXAGONAL, 'P', 'c'); /* Hexagonal H (PDB-speak for rhombohedral) */ |