def test_Uisotropy(self):
     """check isotropy value for ADP-s at specified sites.
     """
     sg225 = GetSpaceGroup(225)
     corepos = [[0, 0, 0], [0.1, 0.13, 0.17]]
     eau = ExpandAsymmetricUnit(sg225, corepos)
     self.assertEqual([True, False], eau.Uisotropy)
     sc = SymmetryConstraints(sg225, eau.expandedpos)
     self.assertEqual(4 * [True] + 192 * [False], sc.Uisotropy)
     return
Beispiel #2
0
    def expandAsymmetricUnit(self, spacegroup, indices, sgoffset=[0,0,0]):
        """Perform symmetry expansion for atoms at given indices.
        Temperature factors may be corrected to reflect the symmetry.
        All constraints for expanded atoms are erased with the exception
        of the occupancy("occ".  Constraints of unaffected atoms are adjusted
        for new positions self.initial.

        spacegroup  -- instance of SpaceGroup from diffpy.structure
        indices     -- list of integer indices of atoms to be expanded
        sgoffset    -- optional offset of space group origin [0,0,0]
        """
        from diffpy.structure.symmetryutilities import ExpandAsymmetricUnit
        acd = self._popAtomConstraints()
        # get unique, reverse sorted indices
        ruindices = dict.fromkeys(indices).keys()
        ruindices.sort()
        ruindices.reverse()
        coreatoms = [self.initial[i] for i in ruindices]
        corepos = [a.xyz for a in coreatoms]
        coreUijs = [a.U for a in coreatoms]
        eau = ExpandAsymmetricUnit(spacegroup, corepos, coreUijs,
                sgoffset=sgoffset, eps=self.symposeps)
        # build a nested list of new atoms:
        newatoms = []
        for i in range(len(coreatoms)):
            ca = coreatoms[i]
            caocc_con = None
            if ca in acd and "occ" in acd[ca]:
                caocc_con = acd[ca]["occ"]
            eca = []    # expanded core atom
            for j in range(eau.multiplicity[i]):
                a = Atom(ca)
                a.xyz = eau.expandedpos[i][j]
                a.U = eau.expandedUijs[i][j]
                eca.append(a)
                if caocc_con is None:   continue
                # make a copy of occupancy constraint
                acd[a] = {"occ" : copy.copy(caocc_con)}
            newatoms.append(eca)
        # insert new atoms where they belong
        for i, atomlist in zip(ruindices, newatoms):
            self.initial[i:i+1] = atomlist
        # remember this spacegroup as the last one used
        self.initial.pdffit["spcgr"] = spacegroup.short_name
        self.initial.pdffit["sgoffset"] = list(sgoffset)
        # tidy constraints
        self._restoreAtomConstraints(acd)
        return
 def test_corepos(self):
     """test_corepos - find positions in the asymmetric unit.
     """
     sg225 = GetSpaceGroup(225)
     corepos = [[0, 0, 0], [0.1, 0.13, 0.17]]
     eau = ExpandAsymmetricUnit(sg225, corepos)
     sc = SymmetryConstraints(sg225, eau.expandedpos)
     self.assertEqual(2, len(sc.corepos))
     self.assertTrue(numpy.all(corepos[0] == sc.corepos[0]))
     self.assertTrue(numpy.all(corepos[1] == sc.corepos[1]))
     self.assertEqual(2, len(sc.coremap))
     mapped_count = sum(len(idcs) for idcs in sc.coremap.values())
     self.assertEqual(len(sc.positions), mapped_count)
     self.assertTrue(sc.coremap[0] == list(range(4)))
     self.assertTrue(sc.coremap[4] == list(range(4, 4+192)))
     return
Beispiel #4
0
    def updateWidgets(self):
        """Update the widgets."""
        # Update space group
        sgname = self.sgComboBox.GetValue()
        try:
            self.spacegroup = self.structure.getSpaceGroup(sgname)
            error = None
        except ValueError:
            error = "Space group %s does not exist." % sgname
        # This changes list box value to the short_name of the new spacegroup
        # or to the name of previous spacegroup when getSpaceGroup failed.
        self.sgComboBox.SetValue(self.spacegroup.short_name)

        # Update offset
        for i in range(3):
            textctrl = self.textCtrls[i]
            val = textctrl.GetValue()
            # make sure the value is meaningful
            try:
                val = float(eval("1.0*" + val, dict(math.__dict__)))
            except (NameError, TypeError, SyntaxError):
                val = 0.0
            textctrl.SetValue("%s" % val)
            self.offset[i] = val

        # find how many new atoms would be generated
        from diffpy.structure.symmetryutilities import ExpandAsymmetricUnit
        corepos = [self.structure[i].xyz for i in self.indices]
        symposeps = self.structure.symposeps
        eau = ExpandAsymmetricUnit(self.spacegroup,
                                   corepos,
                                   sgoffset=self.offset,
                                   eps=symposeps)
        newsize = sum(eau.multiplicity)
        s = ""
        if len(self.indices) != 1:
            s = "s"
        message = "%i atom%s selected.  Expanding to %i positions." %\
                (len(self.indices), s, newsize)
        self.numConstrainedLabel.SetLabel(message)

        # Raise an error if we had to change the space group
        if error:
            raise ControlValueError(error)
        return
 def test_UFormula_g186c_eqxyz(self):
     '''Check rotated U formulas at the symmetry positions of c-site in 186.
     '''
     sg186 = GetSpaceGroup(186)
     crules = [
             {'U11': 'A', 'U22': 'A', 'U33': 'C',
                 'U12': 'D', 'U13': 'E', 'U23': '-E'},
             {'U11': 'A', 'U22': '2*A-2*D', 'U33': 'C',
                 'U12': 'A-D', 'U13': 'E', 'U23': '2*E'},
             {'U11': '2*A-2*D', 'U22': 'A', 'U33': 'C',
                 'U12': 'A-D', 'U13': '-2*E', 'U23': '-E'},
             {'U11': 'A', 'U22': 'A', 'U33': 'C',
                 'U12': 'D', 'U13': '-E', 'U23': 'E'},
             {'U11': 'A', 'U22': '2*A-2*D', 'U33': 'C',
                 'U12': 'A-D', 'U13': '-E', 'U23': '-2*E'},
             {'U11': '2*A-2*D', 'U22': 'A', 'U33': 'C',
                 'U12': 'A-D', 'U13': '2*E', 'U23': 'E'},
             ]
     self.assertEqual(6, len(self.g186c.eqxyz))
     gc = self.g186c
     for idx in range(6):
         self.assertEqual(crules[idx], gc.UFormula(gc.eqxyz[idx], 'ABCDEF'))
     uiso = numpy.array([[2, 1, 0], [1, 2, 0], [0, 0, 2]])
     eau = ExpandAsymmetricUnit(sg186, [gc.xyz], [uiso])
     for u in eau.expandedUijs:
         du = numpy.linalg.norm((uiso - u).flatten())
         self.assertAlmostEqual(0.0, du, 8)
     symcon = SymmetryConstraints(sg186, sum(eau.expandedpos, []),
             sum(eau.expandedUijs, []))
     upd = dict(symcon.Upars)
     self.assertEqual(2.0, upd['U110'])
     self.assertEqual(2.0, upd['U330'])
     self.assertEqual(1.0, upd['U120'])
     self.assertEqual(0.0, upd['U130'])
     uisod = {'U11' : 2.0, 'U22' : 2.0, 'U33' : 2.0,
              'U12' : 1.0, 'U13' : 0.0, 'U23' : 0.0}
     for ufms in symcon.UFormulas():
         for n, fm in ufms.items():
             self.assertEqual(uisod[n], eval(fm, upd))
     return
Beispiel #6
0
    def _expandAsymmetricUnit(self, block):
        """Perform symmetry expansion of self.stru using self.spacegroup.

        This method updates data in stru and eau.

        Parameters
        ----------
        block : CifBlock
            The top-level block containing crystal structure data.
        """
        from diffpy.structure.symmetryutilities import ExpandAsymmetricUnit
        corepos = [a.xyz for a in self.stru]
        coreUijs = [a.U for a in self.stru]
        self.eau = ExpandAsymmetricUnit(self.spacegroup,
                                        corepos,
                                        coreUijs,
                                        eps=self.eps)
        # setup anisotropy according to symmetry requirements
        # unless it was already explicitly set
        for ca, uisotropy in zip(self.stru, self.eau.Uisotropy):
            if not ca.label in self.anisotropy:
                ca.anisotropy = not uisotropy
                self.anisotropy[ca.label] = ca.anisotropy
        # build a nested list of new atoms:
        newatoms = []
        for i, ca in enumerate(self.stru):
            eca = []  # expanded core atom
            for j in range(self.eau.multiplicity[i]):
                a = Atom(ca)
                a.xyz = self.eau.expandedpos[i][j]
                if j > 0:
                    a.label += '_' + str(j + 1)
                if a.anisotropy:
                    a.U = self.eau.expandedUijs[i][j]
                eca.append(a)
            newatoms.append(eca)
        # insert new atoms where they belong
        self.stru[:] = sum(newatoms, [])
        return
 def test___init__(self):
     """check SymmetryConstraints.__init__()
     """
     sg225 = GetSpaceGroup(225)
     # initialize from nested lists and arrays from ExpandAsymmetricUnit
     eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]])
     sc0 = SymmetryConstraints(sg225, eau.expandedpos)
     self.assertEqual(1, len(sc0.coremap))
     # initialize from list of arrays of coordinates
     poslistarrays = [xyz for xyz in sc0.positions]
     sc1 = SymmetryConstraints(sg225, poslistarrays)
     self.assertEqual(1, len(sc1.coremap))
     # initialize from list of lists of coordinates
     poslistlist = [list(xyz) for xyz in poslistarrays]
     sc2 = SymmetryConstraints(sg225, poslistlist)
     self.assertEqual(1, len(sc2.coremap))
     # initialize from nx3 array
     posarray = numpy.array(poslistlist)
     sc3 = SymmetryConstraints(sg225, posarray)
     self.assertEqual(1, len(sc3.coremap))
     # finally initialize from a single coordinate
     sc4 = SymmetryConstraints(sg225, [0, 0, 0])
     self.assertEqual(1, len(sc4.coremap))
     return