Exemplo n.º 1
0
    def test_k3_peaks_periodic(self):
        """Tests that the final spectra does not change when translating atoms
        in a periodic cell. This is not trivially true unless the weight of
        angles is weighted according to the cell indices of the involved three
        atoms. Notice that the values of the geometry and weight functions are
        not equal before summing them up in the final graph.
        """
        scale = 0.85
        desc = MBTR(
            species=["H"],
            k3={
                "geometry": {"function": "angle"},
                "grid": {"min": 0, "max": 180, "sigma": 5, "n": 2000},
                "weighting": {"function": "exp", "scale": scale, "cutoff": 1e-3},
            },
            normalize_gaussians=False,
            periodic=True,
            flatten=True,
            sparse=False
        )

        atoms = Atoms(
            cell=[
                [10, 0, 0],
                [0, 10, 0],
                [0, 0, 10],
            ],
            symbols=3*["H"],
            scaled_positions=[
                [0.05, 0.40, 0.5],
                [0.05, 0.60, 0.5],
                [0.95, 0.5, 0.5],
            ],
            pbc=True
        )
        features = desc.create(atoms)[0, :]
        x = desc.get_k3_axis()

        # Calculate assumed locations and intensities.
        assumed_locs = np.array([45, 90])
        dist = 2+2*np.sqrt(2)  # The total distance around the three atoms
        weight = np.exp(-scale*dist)
        assumed_ints = np.array([4*weight, 2*weight])
        assumed_ints /= 2  # The periodic distances ar halved because they belong to different cells

        # Check the H-H-H peaks
        hhh_feat = features[desc.get_location(("H", "H", "H"))]
        hhh_peak_indices = find_peaks(hhh_feat, prominence=0.01)[0]
        hhh_peak_locs = x[hhh_peak_indices]
        hhh_peak_ints = hhh_feat[hhh_peak_indices]
        self.assertTrue(np.allclose(hhh_peak_locs, assumed_locs, rtol=0, atol=1e-1))
        self.assertTrue(np.allclose(hhh_peak_ints, assumed_ints, rtol=0, atol=1e-1))

        # Check that everything else is zero
        features[desc.get_location(("H", "H", "H"))] = 0
        self.assertEqual(features.sum(), 0)
Exemplo n.º 2
0
    def test_k3_peaks_finite(self):
        """Tests that all the correct angles are present in finite systems.
        There should be n*(n-1)*(n-2)/2 unique angles where the division by two
        gets rid of duplicate angles.
        """
        desc = MBTR(
            species=["H", "O"],
            k3={
                "geometry": {"function": "angle"},
                "grid": {"min": -10, "max": 180, "sigma": 5, "n": 2000},
                "weighting": {"function": "unity"},
            },
            normalize_gaussians=False,
            periodic=False,
            flatten=True,
            sparse=False
        )
        features = desc.create(H2O)[0, :]
        x = desc.get_k3_axis()

        # Check the H-H-O peaks
        hho_assumed_locs = np.array([38])
        hho_assumed_ints = np.array([2])
        hho_feat = features[desc.get_location(("H", "H", "O"))]
        hho_peak_indices = find_peaks(hho_feat, prominence=0.5)[0]
        hho_peak_locs = x[hho_peak_indices]
        hho_peak_ints = hho_feat[hho_peak_indices]
        self.assertTrue(np.allclose(hho_peak_locs, hho_assumed_locs, rtol=0, atol=5e-2))
        self.assertTrue(np.allclose(hho_peak_ints, hho_assumed_ints, rtol=0, atol=5e-2))

        # Check the H-O-H peaks
        hoh_assumed_locs = np.array([104])
        hoh_assumed_ints = np.array([1])
        hoh_feat = features[desc.get_location(("H", "O", "H"))]
        hoh_peak_indices = find_peaks(hoh_feat, prominence=0.5)[0]
        hoh_peak_locs = x[hoh_peak_indices]
        hoh_peak_ints = hoh_feat[hoh_peak_indices]
        self.assertTrue(np.allclose(hoh_peak_locs, hoh_assumed_locs, rtol=0, atol=5e-2))
        self.assertTrue(np.allclose(hoh_peak_ints, hoh_assumed_ints, rtol=0, atol=5e-2))

        # Check that everything else is zero
        features[desc.get_location(("H", "H", "O"))] = 0
        features[desc.get_location(("H", "O", "H"))] = 0
        self.assertEqual(features.sum(), 0)
Exemplo n.º 3
0
    def test_periodic_images(self):
        """Tests that periodic images are handled correctly.
        """
        decay = 1
        desc = MBTR(
            species=[1],
            periodic=True,
            k1={
                "geometry": {"function": "atomic_number"},
                "grid": {"min": 0, "max": 2, "sigma": 0.1, "n": 21}
            },
            k2={
                "geometry": {"function": "inverse_distance"},
                "grid": {"min": 0, "max": 1.0, "sigma": 0.02, "n": 21},
                "weighting": {"function": "exp", "scale": decay, "cutoff": 1e-4}
            },
            k3={
                "geometry": {"function": "cosine"},
                "grid": {"min": -1.0, "max": 1.0, "sigma": 0.02, "n": 21},
                "weighting": {"function": "exp", "scale": decay, "cutoff": 1e-4},
            },
            normalization="l2_each",  # This normalizes the spectrum
            flatten=True
        )

        # Tests that a system has the same spectrum as the supercell of
        # the same system.
        molecule = H.copy()
        a = 1.5
        molecule.set_cell([
            [a, 0.0, 0.0],
            [0.0, a, 0.0],
            [0.0, 0.0, a]
        ])
        cubic_cell = desc.create(molecule)
        suce = molecule * (2, 1, 1)
        cubic_suce = desc.create(suce)

        diff = abs(np.sum(cubic_cell[0, :] - cubic_suce[0, :]))
        cubic_sum = abs(np.sum(cubic_cell[0, :]))
        self.assertTrue(diff/cubic_sum < 0.05)  # A 5% error is tolerated

        # Same test but for triclinic cell
        molecule.set_cell([
            [0.0, 2.0, 1.0],
            [1.0, 0.0, 1.0],
            [1.0, 2.0, 0.0]
        ])

        triclinic_cell = desc.create(molecule)
        suce = molecule * (2, 1, 1)
        triclinic_suce = desc.create(suce)

        diff = abs(np.sum(triclinic_cell[0, :] - triclinic_suce[0, :]))
        tricl_sum = abs(np.sum(triclinic_cell[0, :]))
        self.assertTrue(diff/tricl_sum < 0.05)

        # Testing that the same crystal, but different unit cells will have a
        # similar spectrum when they are normalized. There will be small
        # differences in the shape (due to not double counting distances)
        a1 = bulk('H', 'fcc', a=2.0)
        a2 = bulk('H', 'fcc', a=2.0, orthorhombic=True)
        a3 = bulk('H', 'fcc', a=2.0, cubic=True)

        triclinic_cell = desc.create(a1)
        orthorhombic_cell = desc.create(a2)
        cubic_cell = desc.create(a3)

        diff1 = abs(np.sum(triclinic_cell[0, :] - orthorhombic_cell[0, :]))
        diff2 = abs(np.sum(triclinic_cell[0, :] - cubic_cell[0, :]))
        tricl_sum = abs(np.sum(triclinic_cell[0, :]))
        self.assertTrue(diff1/tricl_sum < 0.05)
        self.assertTrue(diff2/tricl_sum < 0.05)

        # Tests that the correct peak locations are present in a cubic periodic
        desc = MBTR(
            species=["H"],
            periodic=True,
            k3={
                "geometry": {"function": "cosine"},
                "grid": {"min": -1.1, "max": 1.1, "sigma": 0.010, "n": 600},
                "weighting": {"function": "exp", "scale": decay, "cutoff": 1e-4}
            },
            normalization="l2_each",  # This normalizes the spectrum
            flatten=True
        )
        a = 2.2
        system = Atoms(
            cell=[
                [a, 0.0, 0.0],
                [0.0, a, 0.0],
                [0.0, 0.0, a]
            ],
            positions=[
                [0, 0, 0],
            ],
            symbols=["H"],
        )
        cubic_spectrum = desc.create(system)[0, :]
        x3 = desc.get_k3_axis()

        peak_ids = find_peaks_cwt(cubic_spectrum, [2])
        peak_locs = x3[peak_ids]

        assumed_peaks = np.cos(np.array(
            [
                180,
                90,
                np.arctan(np.sqrt(2))*180/np.pi,
                45,
                np.arctan(np.sqrt(2)/2)*180/np.pi,
                0
            ])*np.pi/180
        )
        self.assertTrue(np.allclose(peak_locs, assumed_peaks, rtol=0, atol=5*np.pi/180))

        # Tests that the correct peak locations are present in a system with a
        # non-cubic basis
        desc = MBTR(
            species=["H"],
            periodic=True,
            k3={
                "geometry": {"function": "cosine"},
                "grid": {"min": -1.0, "max": 1.0, "sigma": 0.030, "n": 200},
                "weighting": {"function": "exp", "scale": 1.5, "cutoff": 1e-4}
            },
            normalization="l2_each",  # This normalizes the spectrum
            flatten=True,
            sparse=False
        )
        a = 2.2
        system = Atoms(
            cell=[
                [a, 0.0, 0.0],
                [0.0, a, 0.0],
                [0.0, 0.0, a]
            ],
            positions=[
                [0, 0, 0],
            ],
            symbols=["H"],
        )
        angle = 30
        system = Atoms(
            cell=ase.geometry.cellpar_to_cell([3*a, a, a, angle, 90, 90]),
            positions=[
                [0, 0, 0],
            ],
            symbols=["H"],
        )
        tricl_spectrum = desc.create(system)
        x3 = desc.get_k3_axis()

        peak_ids = find_peaks_cwt(tricl_spectrum[0, :], [3])
        peak_locs = x3[peak_ids]

        angle = (6)/(np.sqrt(5)*np.sqrt(8))
        assumed_peaks = np.cos(np.array([180, 105, 75, 51.2, 30, 0])*np.pi/180)
        self.assertTrue(np.allclose(peak_locs, assumed_peaks, rtol=0, atol=5*np.pi/180))