コード例 #1
0
 def setUp(self):
     self.bvc = BVSCalculator()
     if not hasattr(self, 'rutile'):
         type(self).rutile = loadDiffPyStructure('rutile.cif')
         # rutile.cif does not have charge data, we need to add them here
         iondict = {'Ti': 'Ti4+', 'O': 'O2-'}
         for a in self.rutile:
             a.element = iondict[a.element]
     return
コード例 #2
0
 def test_pickling(self):
     '''check pickling and unpickling of BVSCalculator.
     '''
     bvsc = BVSCalculator()
     bvsc.rmin = 0.1
     bvsc.rmax = 12.3
     bvsc.valenceprecision = 0.3e-4
     spkl = pickle.dumps(bvsc)
     bvsc1 = pickle.loads(spkl)
     self.assertFalse(bvsc is bvsc1)
     for a in bvsc._namesOfDoubleAttributes():
         self.assertEqual(getattr(bvsc, a), getattr(bvsc1, a))
     self.assertRaises(RuntimeError, pickle_with_attr, bvsc, foo='bar')
     return
コード例 #3
0
 def test___init__(self):
     """check BVSCalculator.__init__()
     """
     self.assertEqual(1e-5, self.bvc.valenceprecision)
     bvc1 = BVSCalculator(valenceprecision=1e-4)
     self.assertEqual(1e-4, bvc1.valenceprecision)
     return
コード例 #4
0
    def __init__(self, parset, sig=1, scaled=False):
        """Initialize the Restraint.

        parset  --  SrRealParSet that creates this BVSRestraint.
        sig     --  The uncertainty on the BVS (default 1).
        scaled  --  A flag indicating if the restraint is scaled
                    (multiplied) by the unrestrained point-average chi^2
                    (chi^2/numpoints) (bool, default False).

        """
        from diffpy.srreal.bvscalculator import BVSCalculator
        self._calc = BVSCalculator()
        self._parset = parset
        self.sig = float(sig)
        self.scaled = bool(scaled)
        return
コード例 #5
0
 def setUp(self):
     self.bvc = BVSCalculator()
     if not hasattr(self, 'rutile'):
         type(self).rutile = loadDiffPyStructure('rutile.cif')
         # rutile.cif does not have charge data, we need to add them here
         iondict = {'Ti' : 'Ti4+',  'O' : 'O2-'}
         for a in self.rutile:  a.element = iondict[a.element]
     return
コード例 #6
0
 def setUp(self):
     self.bvc = BVSCalculator()
     if not hasattr(self, "rutile"):
         type(self).rutile = loadDiffPyStructure("rutile.cif")
         # rutile.cif does not have charge data, we need to add them here
         iondict = {"Ti": "Ti4+", "O": "O2-"}
         for a in self.rutile:
             a.element = iondict[a.element]
     return
コード例 #7
0
ファイル: bvsrestraint.py プロジェクト: cfarrow/diffpy.srfit
    def __init__(self, parset, sig = 1, scaled = False):
        """Initialize the Restraint.

        parset  --  SrRealParSet that creates this BVSRestraint.
        sig     --  The uncertainty on the BVS (default 1).
        scaled  --  A flag indicating if the restraint is scaled
                    (multiplied) by the unrestrained point-average chi^2
                    (chi^2/numpoints) (bool, default False).

        """
        self._calc = BVSCalculator()
        self._parset = parset
        self.sig = float(sig)
        self.scaled = bool(scaled)
        return
コード例 #8
0
ファイル: calculator.py プロジェクト: xpdAcq/pdffitx
def bvs_to_xarray(calculator: BVSCalculator,
                  dim_name: str = "site") -> Dataset:
    """Convert the BSVCalculator to a xarray dataset."""
    data = dict()
    for name, attr, dim in yield_name_attr(calculator):
        if dim > 0:
            data[name] = (dim_name, attr)
        else:
            data[name] = attr
    coords = defaultdict(lambda: (dim_name, list()))
    for atom in calculator.getStructure():
        for name, attr, dim in yield_name_attr(atom):
            if dim == 0:
                coords[name][1].append(attr)
    return Dataset(data_vars=data, coords=coords)
コード例 #9
0
 def test_pickling(self):
     '''check pickling and unpickling of BVSCalculator.
     '''
     bvsc = BVSCalculator()
     bvsc.rmin = 0.1
     bvsc.rmax = 12.3
     bvsc.valenceprecision = 0.3e-4
     bvsc.foobar = 'asdf'
     spkl = cPickle.dumps(bvsc)
     bvsc1 = cPickle.loads(spkl)
     self.failIf(bvsc is bvsc1)
     for a in bvsc._namesOfDoubleAttributes():
         self.assertEqual(getattr(bvsc, a), getattr(bvsc1, a))
     self.assertEqual('asdf', bvsc1.foobar)
     return
コード例 #10
0
 def test_pickling(self):
     '''check pickling and unpickling of BVSCalculator.
     '''
     bvsc = BVSCalculator()
     bvsc.rmin = 0.1
     bvsc.rmax = 12.3
     bvsc.valenceprecision = 0.3e-4
     spkl = pickle.dumps(bvsc)
     bvsc1 = pickle.loads(spkl)
     self.assertFalse(bvsc is bvsc1)
     for a in bvsc._namesOfDoubleAttributes():
         self.assertEqual(getattr(bvsc, a), getattr(bvsc1, a))
     self.assertRaises(RuntimeError, pickle_with_attr, bvsc, foo='bar')
     return
コード例 #11
0
 def test_pickling(self):
     """check pickling and unpickling of BVSCalculator.
     """
     bvsc = BVSCalculator()
     bvsc.rmin = 0.1
     bvsc.rmax = 12.3
     bvsc.valenceprecision = 0.3e-4
     bvsc.foobar = "asdf"
     spkl = cPickle.dumps(bvsc)
     bvsc1 = cPickle.loads(spkl)
     self.assertFalse(bvsc is bvsc1)
     for a in bvsc._namesOfDoubleAttributes():
         self.assertEqual(getattr(bvsc, a), getattr(bvsc1, a))
     self.assertEqual("asdf", bvsc1.foobar)
     return
コード例 #12
0
class TestBVSCalculator(unittest.TestCase):

    def setUp(self):
        self.bvc = BVSCalculator()
        if not hasattr(self, 'rutile'):
            type(self).rutile = loadDiffPyStructure('rutile.cif')
            # rutile.cif does not have charge data, we need to add them here
            iondict = {'Ti' : 'Ti4+',  'O' : 'O2-'}
            for a in self.rutile:  a.element = iondict[a.element]
        return


    def tearDown(self):
        return


    def test___init__(self):
        """check BVSCalculator.__init__()
        """
        self.assertEqual(1e-5, self.bvc.valenceprecision)
        bvc1 = BVSCalculator(valenceprecision=1e-4)
        self.assertEqual(1e-4, bvc1.valenceprecision)
        return


    def test___call__(self):
        """check BVSCalculator.__call__()
        """
        vcalc = self.bvc(self.rutile)
        self.assertEqual(len(self.rutile), len(vcalc))
        self.assertEqual(tuple(self.bvc.value), tuple(vcalc))
        self.assertTrue(vcalc[0] > 0)
        self.assertTrue(vcalc[-1] < 0)
        self.assertAlmostEqual(0.0, sum(vcalc), 12)
        self.assertAlmostEqual(0.0, sum(self.bvc.valences), 12)
        for vo, vc in zip(self.bvc.valences, vcalc):
            self.assertTrue(abs((vo - vc) / vo) < 0.1)
        return


    def test_bvdiff(self):
        """check BVSCalculator.bvdiff
        """
        self.bvc(self.rutile)
        self.assertEqual(6, len(self.bvc.bvdiff))
        # rutile is overbonded
        for bvd in self.bvc.bvdiff:
            self.assertTrue(bvd < 0)
        return


    def test_bvmsdiff(self):
        """check BVSCalculator.bvmsdiff
        """
        self.assertEqual(0, self.bvc.bvmsdiff)
        self.bvc(self.rutile)
        self.assertAlmostEqual(0.0158969, self.bvc.bvmsdiff, 6)
        return


    def test_bvrmsdiff(self):
        """check BVSCalculator.bvrmsdiff
        """
        from math import sqrt
        self.assertEqual(0, self.bvc.bvrmsdiff)
        self.bvc(self.rutile)
        self.assertTrue(self.bvc.bvrmsdiff > 0)
        self.assertAlmostEqual(sqrt(self.bvc.bvmsdiff),
                self.bvc.bvrmsdiff, 12)
        bvrmsd0 = self.bvc.bvrmsdiff
        # check mixed occupancy
        rutilemix = self.rutile.copy()
        for a in self.rutile:
            rutilemix.addNewAtom(a)
        for a in rutilemix:
            a.occupancy = 0.5
        self.bvc(rutilemix)
        self.assertEqual(12, len(self.bvc.value))
        self.assertAlmostEqual(bvrmsd0, self.bvc.bvrmsdiff, 12)
        return


    def test_eval(self):
        """check BVSCalculator.eval()
        """
        vcalc = self.bvc.eval(self.rutile)
        self.assertEqual(tuple(vcalc), tuple(self.bvc.value))
        return


    def test_valences(self):
        """check BVSCalculator.valences
        """
        self.bvc(self.rutile)
        self.assertEqual((4, 4, -2, -2, -2, -2),
                tuple(self.bvc.valences))
        return


    def test_value(self):
        """check BVSCalculator.value
        """
        self.assertEqual(0, len(self.bvc.value))
        return


    def test_pickling(self):
        '''check pickling and unpickling of BVSCalculator.
        '''
        bvsc = BVSCalculator()
        bvsc.rmin = 0.1
        bvsc.rmax = 12.3
        bvsc.valenceprecision = 0.3e-4
        spkl = pickle.dumps(bvsc)
        bvsc1 = pickle.loads(spkl)
        self.assertFalse(bvsc is bvsc1)
        for a in bvsc._namesOfDoubleAttributes():
            self.assertEqual(getattr(bvsc, a), getattr(bvsc1, a))
        self.assertRaises(RuntimeError, pickle_with_attr, bvsc, foo='bar')
        return


    def test_mask_pickling(self):
        '''Check if mask gets properly pickled and restored.
        '''
        self.bvc.maskAllPairs(False)
        self.bvc.setPairMask(0, 1, True)
        self.assertTrue(False is self.bvc.getPairMask(0, 0))
        self.assertTrue(True is self.bvc.getPairMask(0, 1))
        bvc1 = pickle.loads(pickle.dumps(self.bvc))
        self.assertTrue(False is bvc1.getPairMask(0, 0))
        self.assertTrue(True is bvc1.getPairMask(0, 1))
        return


    def test_table_pickling(self):
        '''Check if bvparamtable gets correctly pickled and restored.
        '''
        self.bvc.bvparamtable.setCustom('A', 1, 'B', -2, 7, 8)
        bvc1 = pickle.loads(pickle.dumps(self.bvc))
        bpab = bvc1.bvparamtable.lookup('A+', 'B2-')
        self.assertEqual("A", bpab.atom0)
        self.assertEqual(1, bpab.valence0)
        self.assertEqual("B", bpab.atom1)
        self.assertEqual(-2, bpab.valence1)
        self.assertEqual(7, bpab.Ro)
        self.assertEqual(8, bpab.B)
        return


    def test_pickling_derived_structure(self):
        '''check pickling of BVSCalculator with DerivedStructureAdapter.
        '''
        from diffpy.srreal.tests.testutils import DerivedStructureAdapter
        bvc = self.bvc
        stru0 = DerivedStructureAdapter()
        bvc.setStructure(stru0)
        self.assertEqual(1, stru0.cpqcount)
        spkl = pickle.dumps(bvc)
        bvc1 = pickle.loads(spkl)
        self.assertTrue(stru0 is bvc.getStructure())
        stru1 = bvc1.getStructure()
        self.assertTrue(type(stru1) is DerivedStructureAdapter)
        self.assertFalse(stru1 is stru0)
        self.assertEqual(1, stru1.cpqcount)
        return


    def test_table_atom_valence(self):
        '''check calculation with defined valences in bvparamtable
        '''
        bvc = self.bvc
        barerutile = self.rutile.copy()
        for a in barerutile:
            a.element = a.element.rstrip('+-012345678')
        self.assertEqual({"Ti" : 2, "O" : 4}, barerutile.composition)
        self.assertFalse(any(bvc(barerutile)))
        bptb = bvc.bvparamtable
        bptb.setAtomValence("Ti", +4)
        bptb.setAtomValence("O", -2)
        vcalc = bvc(barerutile)
        self.assertEqual(4, bptb.getAtomValence("Ti"))
        self.assertEqual(-2, bptb.getAtomValence("O"))
        self.assertEqual(set((+4, -2)), set(round(x) for x in vcalc))
        self.assertEqual(set((+4, -2)), set(bvc.valences))
        bptb.resetAtomValences()
        self.assertFalse(any(bvc(barerutile)))
        return
コード例 #13
0
class TestBVSCalculator(unittest.TestCase):

    def setUp(self):
        self.bvc = BVSCalculator()
        if not hasattr(self, 'rutile'):
            type(self).rutile = loadDiffPyStructure('rutile.cif')
            # rutile.cif does not have charge data, we need to add them here
            iondict = {'Ti' : 'Ti4+',  'O' : 'O2-'}
            for a in self.rutile:  a.element = iondict[a.element]
        return


    def tearDown(self):
        return


    def test___init__(self):
        """check BVSCalculator.__init__()
        """
        self.assertEqual(1e-5, self.bvc.valenceprecision)
        bvc1 = BVSCalculator(valenceprecision=1e-4)
        self.assertEqual(1e-4, bvc1.valenceprecision)
        return


    def test___call__(self):
        """check BVSCalculator.__call__()
        """
        vcalc = self.bvc(self.rutile)
        self.assertEqual(len(self.rutile), len(vcalc))
        self.assertEqual(tuple(self.bvc.value), tuple(vcalc))
        self.failUnless(vcalc[0] > 0)
        self.failUnless(vcalc[-1] < 0)
        self.assertAlmostEqual(0.0, sum(vcalc), 12)
        self.assertAlmostEqual(0.0, sum(self.bvc.valences), 12)
        for vo, vc in zip(self.bvc.valences, vcalc):
            self.failUnless(abs((vo - vc) / vo) < 0.1)
        return


    def test_bvdiff(self):
        """check BVSCalculator.bvdiff
        """
        self.bvc(self.rutile)
        self.assertEqual(6, len(self.bvc.bvdiff))
        # rutile is overbonded
        for bvd in self.bvc.bvdiff:
            self.failUnless(bvd < 0)
        return


    def test_bvmsdiff(self):
        """check BVSCalculator.bvmsdiff
        """
        self.assertEqual(0, self.bvc.bvmsdiff)
        self.bvc(self.rutile)
        self.assertAlmostEqual(0.0158969, self.bvc.bvmsdiff, 6)
        return


    def test_bvrmsdiff(self):
        """check BVSCalculator.bvrmsdiff
        """
        from math import sqrt
        self.assertEqual(0, self.bvc.bvrmsdiff)
        self.bvc(self.rutile)
        self.failUnless(self.bvc.bvrmsdiff > 0)
        self.assertAlmostEqual(sqrt(self.bvc.bvmsdiff),
                self.bvc.bvrmsdiff, 12)
        bvrmsd0 = self.bvc.bvrmsdiff
        # check mixed occupancy
        rutilemix = Structure(self.rutile)
        for a in self.rutile:
            rutilemix.addNewAtom(a)
        for a in rutilemix:
            a.occupancy = 0.5
        self.bvc(rutilemix)
        self.assertEqual(12, len(self.bvc.value))
        self.assertAlmostEqual(bvrmsd0, self.bvc.bvrmsdiff, 12)
        return


    def test_eval(self):
        """check BVSCalculator.eval()
        """
        vcalc = self.bvc.eval(self.rutile)
        self.assertEqual(tuple(vcalc), tuple(self.bvc.value))
        return


    def test_valences(self):
        """check BVSCalculator.valences
        """
        self.bvc(self.rutile)
        self.assertEqual((4, 4, -2, -2, -2, -2),
                tuple(self.bvc.valences))
        return


    def test_value(self):
        """check BVSCalculator.value
        """
        self.assertEqual(0, len(self.bvc.value))
        return


    def test_pickling(self):
        '''check pickling and unpickling of BVSCalculator.
        '''
        bvsc = BVSCalculator()
        bvsc.rmin = 0.1
        bvsc.rmax = 12.3
        bvsc.valenceprecision = 0.3e-4
        bvsc.foobar = 'asdf'
        spkl = cPickle.dumps(bvsc)
        bvsc1 = cPickle.loads(spkl)
        self.failIf(bvsc is bvsc1)
        for a in bvsc._namesOfDoubleAttributes():
            self.assertEqual(getattr(bvsc, a), getattr(bvsc1, a))
        self.assertEqual('asdf', bvsc1.foobar)
        return


    def test_mask_pickling(self):
        '''Check if mask gets properly pickled and restored.
        '''
        self.bvc.maskAllPairs(False)
        self.bvc.setPairMask(0, 1, True)
        self.failUnless(False is self.bvc.getPairMask(0, 0))
        self.failUnless(True is self.bvc.getPairMask(0, 1))
        bvc1 = cPickle.loads(cPickle.dumps(self.bvc))
        self.failUnless(False is bvc1.getPairMask(0, 0))
        self.failUnless(True is bvc1.getPairMask(0, 1))
        return
コード例 #14
0
ファイル: bvsrestraint.py プロジェクト: cfarrow/diffpy.srfit
class BVSRestraint(Restraint):
    """Wrapping of BVSCalculator.bvmsdiff as a Restraint.

    The restraint penalty is the root-mean-square deviation of the theoretical
    and calculated bond-valence sum of a structure.

    Attributes:
    _calc   --  The SrReal BVSCalculator instance.
    _parset --  The SrRealParSet that created this BVSRestraint.
    sig     --  The uncertainty on the BVS (default 1).
    scaled  --  A flag indicating if the restraint is scaled (multiplied)
                by the unrestrained point-average chi^2 (chi^2/numpoints)
                (default False).

    """

    def __init__(self, parset, sig = 1, scaled = False):
        """Initialize the Restraint.

        parset  --  SrRealParSet that creates this BVSRestraint.
        sig     --  The uncertainty on the BVS (default 1).
        scaled  --  A flag indicating if the restraint is scaled
                    (multiplied) by the unrestrained point-average chi^2
                    (chi^2/numpoints) (bool, default False).

        """
        self._calc = BVSCalculator()
        self._parset = parset
        self.sig = float(sig)
        self.scaled = bool(scaled)
        return

    def penalty(self, w = 1.0):
        """Calculate the penalty of the restraint.

        w   --  The point-average chi^2 which is optionally used to scale the
                penalty (float, default 1.0).
        
        """
        # Get the bvms from the BVSCalculator
        stru = self._parset._getSrRealStructure()
        self._calc.eval(stru)
        penalty = self._calc.bvmsdiff

        # Scale by the prefactor
        penalty /= self.sig**2

        # Optionally scale by w
        if self.scaled: penalty *= w

        return penalty

    def _validate(self):
        """This evaluates the calculator.

        Raises AttributeError if validation fails.
        
        """
        from numpy import nan
        p = self.penalty()
        if p is None or p is nan:
            raise AttributeError("Cannot evaluate penalty")

        return
コード例 #15
0
class TestBVSCalculator(unittest.TestCase):
    def setUp(self):
        self.bvc = BVSCalculator()
        if not hasattr(self, 'rutile'):
            type(self).rutile = loadDiffPyStructure('rutile.cif')
            # rutile.cif does not have charge data, we need to add them here
            iondict = {'Ti': 'Ti4+', 'O': 'O2-'}
            for a in self.rutile:
                a.element = iondict[a.element]
        return

    def tearDown(self):
        return

    def test___init__(self):
        """check BVSCalculator.__init__()
        """
        self.assertEqual(1e-5, self.bvc.valenceprecision)
        bvc1 = BVSCalculator(valenceprecision=1e-4)
        self.assertEqual(1e-4, bvc1.valenceprecision)
        return

    def test___call__(self):
        """check BVSCalculator.__call__()
        """
        vcalc = self.bvc(self.rutile)
        self.assertEqual(len(self.rutile), len(vcalc))
        self.assertEqual(tuple(self.bvc.value), tuple(vcalc))
        self.failUnless(vcalc[0] > 0)
        self.failUnless(vcalc[-1] < 0)
        self.assertAlmostEqual(0.0, sum(vcalc), 12)
        self.assertAlmostEqual(0.0, sum(self.bvc.valences), 12)
        for vo, vc in zip(self.bvc.valences, vcalc):
            self.failUnless(abs((vo - vc) / vo) < 0.1)
        return

    def test_bvdiff(self):
        """check BVSCalculator.bvdiff
        """
        self.bvc(self.rutile)
        self.assertEqual(6, len(self.bvc.bvdiff))
        # rutile is overbonded
        for bvd in self.bvc.bvdiff:
            self.failUnless(bvd < 0)
        return

    def test_bvmsdiff(self):
        """check BVSCalculator.bvmsdiff
        """
        self.assertEqual(0, self.bvc.bvmsdiff)
        self.bvc(self.rutile)
        self.assertAlmostEqual(0.0158969, self.bvc.bvmsdiff, 6)
        return

    def test_bvrmsdiff(self):
        """check BVSCalculator.bvrmsdiff
        """
        from math import sqrt
        self.assertEqual(0, self.bvc.bvrmsdiff)
        self.bvc(self.rutile)
        self.failUnless(self.bvc.bvrmsdiff > 0)
        self.assertAlmostEqual(sqrt(self.bvc.bvmsdiff), self.bvc.bvrmsdiff, 12)
        bvrmsd0 = self.bvc.bvrmsdiff
        # check mixed occupancy
        rutilemix = Structure(self.rutile)
        for a in self.rutile:
            rutilemix.addNewAtom(a)
        for a in rutilemix:
            a.occupancy = 0.5
        self.bvc(rutilemix)
        self.assertEqual(12, len(self.bvc.value))
        self.assertAlmostEqual(bvrmsd0, self.bvc.bvrmsdiff, 12)
        return

    def test_eval(self):
        """check BVSCalculator.eval()
        """
        vcalc = self.bvc.eval(self.rutile)
        self.assertEqual(tuple(vcalc), tuple(self.bvc.value))
        return

    def test_valences(self):
        """check BVSCalculator.valences
        """
        self.bvc(self.rutile)
        self.assertEqual((4, 4, -2, -2, -2, -2), tuple(self.bvc.valences))
        return

    def test_value(self):
        """check BVSCalculator.value
        """
        self.assertEqual(0, len(self.bvc.value))
        return

    def test_pickling(self):
        '''check pickling and unpickling of BVSCalculator.
        '''
        bvsc = BVSCalculator()
        bvsc.rmin = 0.1
        bvsc.rmax = 12.3
        bvsc.valenceprecision = 0.3e-4
        bvsc.foobar = 'asdf'
        spkl = cPickle.dumps(bvsc)
        bvsc1 = cPickle.loads(spkl)
        self.failIf(bvsc is bvsc1)
        for a in bvsc._namesOfDoubleAttributes():
            self.assertEqual(getattr(bvsc, a), getattr(bvsc1, a))
        self.assertEqual('asdf', bvsc1.foobar)
        return

    def test_mask_pickling(self):
        '''Check if mask gets properly pickled and restored.
        '''
        self.bvc.maskAllPairs(False)
        self.bvc.setPairMask(0, 1, True)
        self.failUnless(False is self.bvc.getPairMask(0, 0))
        self.failUnless(True is self.bvc.getPairMask(0, 1))
        bvc1 = cPickle.loads(cPickle.dumps(self.bvc))
        self.failUnless(False is bvc1.getPairMask(0, 0))
        self.failUnless(True is bvc1.getPairMask(0, 1))
        return
コード例 #16
0
def test_bvs_to_xarray(db):
    stru = db["Ni_stru"]
    calc = BVSCalculator()
    calc(stru)
    arr = bvs_to_xarray(calc)
    print(arr)
コード例 #17
0
class TestBVSCalculator(unittest.TestCase):
    def setUp(self):
        self.bvc = BVSCalculator()
        if not hasattr(self, 'rutile'):
            type(self).rutile = loadDiffPyStructure('rutile.cif')
            # rutile.cif does not have charge data, we need to add them here
            iondict = {'Ti': 'Ti4+', 'O': 'O2-'}
            for a in self.rutile:
                a.element = iondict[a.element]
        return

    def tearDown(self):
        return

    def test___init__(self):
        """check BVSCalculator.__init__()
        """
        self.assertEqual(1e-5, self.bvc.valenceprecision)
        bvc1 = BVSCalculator(valenceprecision=1e-4)
        self.assertEqual(1e-4, bvc1.valenceprecision)
        return

    def test___call__(self):
        """check BVSCalculator.__call__()
        """
        vcalc = self.bvc(self.rutile)
        self.assertEqual(len(self.rutile), len(vcalc))
        self.assertEqual(tuple(self.bvc.value), tuple(vcalc))
        self.assertTrue(vcalc[0] > 0)
        self.assertTrue(vcalc[-1] < 0)
        self.assertAlmostEqual(0.0, sum(vcalc), 12)
        self.assertAlmostEqual(0.0, sum(self.bvc.valences), 12)
        for vo, vc in zip(self.bvc.valences, vcalc):
            self.assertTrue(abs((vo - vc) / vo) < 0.1)
        return

    def test_bvdiff(self):
        """check BVSCalculator.bvdiff
        """
        self.bvc(self.rutile)
        self.assertEqual(6, len(self.bvc.bvdiff))
        # rutile is overbonded
        for bvd in self.bvc.bvdiff:
            self.assertTrue(bvd < 0)
        return

    def test_bvmsdiff(self):
        """check BVSCalculator.bvmsdiff
        """
        self.assertEqual(0, self.bvc.bvmsdiff)
        self.bvc(self.rutile)
        self.assertAlmostEqual(0.0158969, self.bvc.bvmsdiff, 6)
        return

    def test_bvrmsdiff(self):
        """check BVSCalculator.bvrmsdiff
        """
        from math import sqrt
        self.assertEqual(0, self.bvc.bvrmsdiff)
        self.bvc(self.rutile)
        self.assertTrue(self.bvc.bvrmsdiff > 0)
        self.assertAlmostEqual(sqrt(self.bvc.bvmsdiff), self.bvc.bvrmsdiff, 12)
        bvrmsd0 = self.bvc.bvrmsdiff
        # check mixed occupancy
        rutilemix = self.rutile.copy()
        for a in self.rutile:
            rutilemix.addNewAtom(a)
        for a in rutilemix:
            a.occupancy = 0.5
        self.bvc(rutilemix)
        self.assertEqual(12, len(self.bvc.value))
        self.assertAlmostEqual(bvrmsd0, self.bvc.bvrmsdiff, 12)
        return

    def test_eval(self):
        """check BVSCalculator.eval()
        """
        vcalc = self.bvc.eval(self.rutile)
        self.assertEqual(tuple(vcalc), tuple(self.bvc.value))
        return

    def test_valences(self):
        """check BVSCalculator.valences
        """
        self.bvc(self.rutile)
        self.assertEqual((4, 4, -2, -2, -2, -2), tuple(self.bvc.valences))
        return

    def test_value(self):
        """check BVSCalculator.value
        """
        self.assertEqual(0, len(self.bvc.value))
        return

    def test_pickling(self):
        '''check pickling and unpickling of BVSCalculator.
        '''
        bvsc = BVSCalculator()
        bvsc.rmin = 0.1
        bvsc.rmax = 12.3
        bvsc.valenceprecision = 0.3e-4
        bvsc.foobar = 'asdf'
        spkl = pickle.dumps(bvsc)
        bvsc1 = pickle.loads(spkl)
        self.assertFalse(bvsc is bvsc1)
        for a in bvsc._namesOfDoubleAttributes():
            self.assertEqual(getattr(bvsc, a), getattr(bvsc1, a))
        self.assertEqual('asdf', bvsc1.foobar)
        return

    def test_mask_pickling(self):
        '''Check if mask gets properly pickled and restored.
        '''
        self.bvc.maskAllPairs(False)
        self.bvc.setPairMask(0, 1, True)
        self.assertTrue(False is self.bvc.getPairMask(0, 0))
        self.assertTrue(True is self.bvc.getPairMask(0, 1))
        bvc1 = pickle.loads(pickle.dumps(self.bvc))
        self.assertTrue(False is bvc1.getPairMask(0, 0))
        self.assertTrue(True is bvc1.getPairMask(0, 1))
        return

    def test_table_pickling(self):
        '''Check if bvparamtable gets correctly pickled and restored.
        '''
        self.bvc.bvparamtable.setCustom('A', 1, 'B', -2, 7, 8)
        bvc1 = pickle.loads(pickle.dumps(self.bvc))
        bpab = bvc1.bvparamtable.lookup('A+', 'B2-')
        self.assertEqual("A", bpab.atom0)
        self.assertEqual(1, bpab.valence0)
        self.assertEqual("B", bpab.atom1)
        self.assertEqual(-2, bpab.valence1)
        self.assertEqual(7, bpab.Ro)
        self.assertEqual(8, bpab.B)
        return

    def test_pickling_derived_structure(self):
        '''check pickling of BVSCalculator with DerivedStructureAdapter.
        '''
        from diffpy.srreal.tests.testutils import DerivedStructureAdapter
        bvc = self.bvc
        stru0 = DerivedStructureAdapter()
        bvc.setStructure(stru0)
        self.assertEqual(1, stru0.cpqcount)
        spkl = pickle.dumps(bvc)
        bvc1 = pickle.loads(spkl)
        self.assertTrue(stru0 is bvc.getStructure())
        stru1 = bvc1.getStructure()
        self.assertTrue(type(stru1) is DerivedStructureAdapter)
        self.assertFalse(stru1 is stru0)
        self.assertEqual(1, stru1.cpqcount)
        return

    def test_table_atom_valence(self):
        '''check calculation with defined valences in bvparamtable
        '''
        bvc = self.bvc
        barerutile = self.rutile.copy()
        for a in barerutile:
            a.element = a.element.rstrip('+-012345678')
        self.assertEqual({"Ti": 2, "O": 4}, barerutile.composition)
        self.assertFalse(any(bvc(barerutile)))
        bptb = bvc.bvparamtable
        bptb.setAtomValence("Ti", +4)
        bptb.setAtomValence("O", -2)
        vcalc = bvc(barerutile)
        self.assertEqual(4, bptb.getAtomValence("Ti"))
        self.assertEqual(-2, bptb.getAtomValence("O"))
        self.assertEqual(set((+4, -2)), set(round(x) for x in vcalc))
        self.assertEqual(set((+4, -2)), set(bvc.valences))
        bptb.resetAtomValences()
        self.assertFalse(any(bvc(barerutile)))
        return
コード例 #18
0
ファイル: calcbvs.py プロジェクト: DanOlds/diffpy_examples
#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''Calculation of bond valence sums using diffpy.srreal module included in
DiffPy-CMI.
'''

from __future__ import print_function
from diffpy.Structure import loadStructure
from diffpy.srreal.bvscalculator import BVSCalculator

# load crystal structure data from a CIF file
nacl = loadStructure('NaCl.cif')

# create bond valence sum calculator object
bvsc = BVSCalculator()

# calculate BVS and print the expected and actual valences
vsim = bvsc(nacl)
print('Calculate bond valence sums for NaCl "bvsc(nacl)"')
print('expected "bvsc.valences":\n ', bvsc.valences)
print('calculated "bvsc.value":\n ' , vsim)
print('difference "bvsc.bvdiff":\n ', bvsc.bvdiff)
print('root mean square difference "bvsc.bvrmsdiff":', bvsc.bvrmsdiff)
print()

# create new BVS calculator with a custom bond valence parameters
bvsc2 = BVSCalculator()

# Use alternate value for the Na+ Cl- bond valence parameters from
# http://www.iucr.org/__data/assets/file/0018/59004/bvparm2011.cif
コード例 #19
0
class BVSRestraint(Restraint):
    """Wrapping of BVSCalculator.bvmsdiff as a Restraint.

    The restraint penalty is the root-mean-square deviation of the theoretical
    and calculated bond-valence sum of a structure.

    Attributes:
    _calc   --  The SrReal BVSCalculator instance.
    _parset --  The SrRealParSet that created this BVSRestraint.
    sig     --  The uncertainty on the BVS (default 1).
    scaled  --  A flag indicating if the restraint is scaled (multiplied)
                by the unrestrained point-average chi^2 (chi^2/numpoints)
                (default False).

    """
    def __init__(self, parset, sig=1, scaled=False):
        """Initialize the Restraint.

        parset  --  SrRealParSet that creates this BVSRestraint.
        sig     --  The uncertainty on the BVS (default 1).
        scaled  --  A flag indicating if the restraint is scaled
                    (multiplied) by the unrestrained point-average chi^2
                    (chi^2/numpoints) (bool, default False).

        """
        from diffpy.srreal.bvscalculator import BVSCalculator
        self._calc = BVSCalculator()
        self._parset = parset
        self.sig = float(sig)
        self.scaled = bool(scaled)
        return

    def penalty(self, w=1.0):
        """Calculate the penalty of the restraint.

        w   --  The point-average chi^2 which is optionally used to scale the
                penalty (float, default 1.0).

        """
        # Get the bvms from the BVSCalculator
        stru = self._parset._getSrRealStructure()
        self._calc.eval(stru)
        penalty = self._calc.bvmsdiff

        # Scale by the prefactor
        penalty /= self.sig**2

        # Optionally scale by w
        if self.scaled: penalty *= w

        return penalty

    def _validate(self):
        """This evaluates the calculator.

        Raises SrFitError if validation fails.

        """
        from numpy import nan
        p = self.penalty()
        if p is None or p is nan:
            raise SrFitError("Cannot evaluate penalty")
        v = self._calc.value
        if len(v) > 1 and not v.any():
            emsg = ("Bond valence sums are all zero.  Check atom symbols in "
                    "the structure or define custom bond-valence parameters.")
            raise SrFitError(emsg)
        return