Say, I have two crystal structures of a particular organic molecule, the crystal structures are basically identical, apart from a rotation and redefinition of the lattice vectors/angles, a simple result of different choices during the structure refinement process after the xray or neutron experiment for structure determination. As a practical example consider triclinic (P-1) malonic acid for which two structures have been published:

one (MALNAC02) with: a,b,c, alpha,beta,gamma=5.156,5.341,8.407,71.48,76.12,85.09

the other (MALNAC) with a,b,c, alpha,beta,gamma=5.33,5.14,11.25,102.7,135.17,85.17

If I wanted to convert one structure to the other so that they perfectly overlap (apart from a trivial translation step), by rotating it successively through one or more of the cartesian (x,y,z) axis through appropriate angles, how would I find these angles?

I understand there are different ways to do this, other than the successive rotation around the cartesian axes (use a rotation matrix or Eulerian angles) but here I need to know these angles (around the cartesian axes), also I know there is not only one unique version of these angles - but I am fine with having just one of them.


If you know which atoms correspond to each other in the two structures, you can use a structural superposition method. Least-squares superposition methods find the rotation matrix and translation that minimizes the RMSD between given points.

There are a few well-established methods. Recently, I had to use one and I picked QCP (because it comes with BSD-licensed C code), but for a small set of points like in your problem any method should work.

  • $\begingroup$ thanks, QCP looks like a rather useful tool, however, my goal is not to align two structures but to figure out the angles mentioned in the original post, it might be trivial for an expert, but I don;t know how to get these angles from the rotation matrix that a tool like QCP would supply. $\endgroup$ – Michael Brunsteiner Jan 9 at 13:11
  • $\begingroup$ see Rotation matrix → Euler angles $\endgroup$ – marcin Jan 12 at 10:30

It seems to me that there is a discrepancy about the c-axis in the 2 unit cells, producing a significant difference in the unit cell volume (213.1 and 210.8, respectively).

If you apply the transformation matrix [-b,-a,c] to the first unit cell 5.156 5.341 8.407 71.48 76.12 85.09 and compare with the second one you obtain:

5.341 5.156 8.407 103.88 108.52 85.09 Transformed Unit Cell 5.33 5.14 11.25 102.7 135.17 85.17 Second Unit Cell

You can see that a and b axes, as well as gamma (the angle between a and b) are in good agreement in both cases (within experimental differences), whereas the parameters where the c-axis plays a role diverge (c-axis and alfa and beta angles). I would suggest to draw both structures using the corresponding structural data (if available) as well as to compare the occupation of the special positions (if any) for the different atoms.

  • $\begingroup$ the lattice parameters are indeed different, but the crystal structures are still identical (within exptl error bars) the crystallographers simply made different decisions about how to represent the structure in both cases (think about P21/n vs P21/c) so that is not the issue really - the question is how to rotate one cell so that the content of both cells are aligned/superimposed (again within exptl error bars)... $\endgroup$ – Michael Brunsteiner Jan 9 at 14:52
  • $\begingroup$ no, this is not a simple problem of rotation. here you are in the triclinic system (space group P-1); you have no symmetry axis (in this case the unique symmetry operation is the inversion). So there are no different settings in this group as in the P21/c SG where different main axes can be selected. In any case, the unit cell volume must be the same, whichever the cell choice (if both structures are really the same). at first sight I would say that the c-axis of the 2nd cell is actually a combination of the c-axis in the first unit cell with other axes. $\endgroup$ – gryphys Jan 9 at 16:53
  • $\begingroup$ In fact if you apply the transformation [-b,-a,b+c] to the first unit cell you obtain 5.341 5.156 11.3017 102.64 135.14 85.09 that are by about the same paramters of the 2nd cell. The problem is that this 2nd cell has a higher unit cell volume, whereas you should choose the lower one. For this reason the structural model of the 2nd cell could be correct in principle, but should be rearranged according to the 1st one model. $\endgroup$ – gryphys Jan 9 at 17:02
  • $\begingroup$ [-b,-a,b+c] ... sorry i'm not familiar with this type notation, could you explain? also, both structures are xray and according to the CCDC (content of cif files) taken at room temperature, but one (MALNAC) is from 1957 and the other (MALNAC02) from 1994, so a difference in cell volume of about 1 percent should be acceptable/tolerable i believe... $\endgroup$ – Michael Brunsteiner Jan 9 at 18:12
  • $\begingroup$ you have to consider them as vectors. for example, -b means that in the 2nd cell the a-axis has the length of the b-axis in the first one, but the vector is directed in an opposite direction. the c-axis of the 2-nd cell is given b the vector summation of the b and axis in th first one. in matrix form corresponds to a 3x3 matrix: [ 0 -1 0] [ -1 0 1] [ 0 0 1] for details look at International Tables for Crystallography (2006). Vol. A, Chapter 5.1, pp. 78. $\endgroup$ – gryphys Jan 10 at 10:17

If you're familiar with Python, this can be done using pymatgen fairly easily.

To illustrate, let's first define our problem:

from pymatgen.core.lattice import Lattice
from pymatgen.core.structure import Structure

malnac_lattice = Lattice.from_parameters(5.33, 5.14, 11.25, 102.7, 135.17, 85.17)
malnac02_lattice = Lattice.from_parameters(5.156, 5.341, 8.407, 71.48, 76.12, 85.09)

# here, because we're only interested in the lattices, 
# we can define a "dummy structure" with a single H atom at the origin

malnac_struct = Structure(malnac_lattice, ["H"], [[0.0, 0.0, 0.0]])
malnac02_struct = Structure(malnac02_lattice, ["H"], [[0.0, 0.0, 0.0]])

Now we have the structures defined, we can use StructureMatcher to compare them and find the transformation to change one into the other.

from pymatgen.analysis.structure_matcher import StructureMatcher

# StructureMatcher can accept different tolerances for judging equivalence
matcher = StructureMatcher(primitive_cell=False)

# first, we can verify these lattices are equivalent
matcher.fit(malnac_struct, malnac02_struct)  # returns True

# and we can get the transformation matrix from one to the other
# this returns the supercell matrix (e.g. change of basis), 
# as well as any relevant translation, and mapping of atoms from one
# crystal to the other
matcher.get_transformation(malnac_struct, malnac02_struct)
# returns (array([[ 0, -1,  0], [-1,  0,  0], [ 0,  1,  1]]), array([0., 0., 0.]), [0])

This gives your answer:

$$\begin{pmatrix} 0 & -1 & 0 \\ -1 & 0 & 0 \\ 0 & 1 & 1 \end{pmatrix}$$

This matrix defines the transformation from the one set of lattice vectors (a, b, c) into the other, and the angles can be obtained from here.

More information can be found in the pymatgen docs, or you can ask the developers (myself included) at matsci.org/pymatgen.

Hope this helps!

  • 1
    $\begingroup$ I still have to try that, but it looks exactly like what i was looking for, thanks! $\endgroup$ – Michael Brunsteiner Jan 15 at 13:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.