def calc_inertia_tensor(atom_iter): """Calculate moment of inertia tensor at the centroid of the atoms. """ al = Structure.AtomList(atom_iter) centroid = al.calc_centroid() I = numpy.zeros((3, 3), float) for atm in al: x = atm.position - centroid I[0, 0] += x[1]**2 + x[2]**2 I[1, 1] += x[0]**2 + x[2]**2 I[2, 2] += x[0]**2 + x[1]**2 I[0, 1] += -x[0] * x[1] I[1, 0] += -x[0] * x[1] I[0, 2] += -x[0] * x[2] I[2, 0] += -x[0] * x[2] I[1, 2] += -x[1] * x[2] I[2, 1] += -x[1] * x[2] evals, evecs = numpy.linalg.eig(I) elist = [(evals[0], evecs[0]), (evals[1], evecs[1]), (evals[2], evecs[2])] elist.sort() R = numpy.array((elist[0][1], elist[1][1], elist[2][1]), float) ## make sure the tensor uses a right-handed coordinate system if numpy.allclose(numpy.linalg.det(R), -1.0): I = numpy.identity(3, float) I[0, 0] = -1.0 R = numpy.dot(I, R) assert numpy.allclose(numpy.linalg.det(R), 1.0) return centroid, R