Skip to content

Commit

Permalink
symmetry operation triplets: allow decimal fractions
Browse files Browse the repository at this point in the history
Some COD CIFs have decimal fractions such as "-x+0.25", ".5+Y", "1.25000-y".
  • Loading branch information
wojdyr committed Apr 26, 2024
1 parent 7a17566 commit e2906e4
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
17 changes: 15 additions & 2 deletions include/gemmi/symmetry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,23 @@ inline std::array<int, 4> parse_triplet_part(const std::string& s) {
fail("wrong or unsupported triplet format: " + s);
int r_idx;
int den = 1;
if (*c >= '0' && *c <= '9') {
if ((*c >= '0' && *c <= '9') || *c == '.') {
// syntax examples in this branch: "1", "-1/2", "+2*x", "1/2 * b"
char* endptr;
num *= std::strtol(c, &endptr, 10);
int n = std::strtol(c, &endptr, 10);
// some COD CIFs have decimal fractions ("-x+0.25", ".5+Y", "1.25000-y")
if (*endptr == '.') {
// avoiding strtod() etc which is locale-dependent
double fract = n;
for (double denom = 0.1; *++endptr >= '0' && *endptr <= '9'; denom *= 0.1)
fract += int(*endptr - '0') * denom;
double rounded = std::round(fract * num);
if (std::fabs(rounded - fract * num) > 0.05)
fail("unexpected number in a symmetry triplet part: " + s);
num = int(rounded);
} else {
num *= n;
}
if (*endptr == '/')
den = std::strtol(endptr + 1, &endptr, 10);
if (*endptr == '*') {
Expand Down
6 changes: 6 additions & 0 deletions tests/test_symmetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
"1+Y" : [ 0, D, 0, D],
"-2+Y" : [ 0, D, 0, -D*2],
"-z-5/6": [ 0, 0,-D, -D*5//6],
# some CIF files from COD have decimal fractions
"0.5-x": [-D, 0, 0, D//2],
".5+Y": [ 0, D, 0, D//2],
"-Z+0.25": [ 0, 0, -D, D//4],
"x+0.6666666667": [ D, 0, 0, D*2//3],
"1.25000-y": [ 0, -D, 0, D*5//4],
}

# From PLATON manual (WinGX v1.80, Chapter 9.3 PLATON),
Expand Down

0 comments on commit e2906e4

Please sign in to comment.