class TestSchnetPack:

    pos1 = Posinp.from_file(os.path.join(pos_folder, "N2.xyz"))
    model1 = os.path.join(model_folder, "ani1_N2_model")
    model2 = os.path.join(model_folder, "wacsf_model")
    model3 = os.path.join(model_folder, "H2O_model")
    calc1 = SchnetPackCalculator(model_dir=model1)
    calc2 = SchnetPackCalculator(model_dir=model2)
    calc3 = SchnetPackCalculator(model_dir=model3)
    job = Job(posinp=pos1, calculator=calc1)
    jobwacsf = Job(posinp=pos1, calculator=calc2)

    def test_only_energy(self):
        self.job.run("energy")
        assert np.array(-2979.6067) == self.job.results["energy"][0]
        new_job = deepcopy(self.job)
        new_job.calculator.units = {"energy": "hartree", "positions": "atomic"}
        new_job.run("energy")
        assert new_job.results["energy"][0] == np.array(-81079.228)
        self.job.results["energy"] = None

    def test_forces_from_deriv(self):
        assert self.job.calculator.available_properties == ["energy"]
        self.job.run("forces")
        ref_forces = np.array([[-0.0, -0.0, -0.31532133],
                               [-0.0, -0.0, 0.31532133]])
        assert np.isclose(self.job.results["forces"][0], ref_forces).all()
        new_job = deepcopy(self.job)
        new_job.calculator.units = {"energy": "hartree", "positions": "atomic"}
        new_job.run("forces")
        assert np.isclose(ref_forces * 51.42206334724,
                          new_job.results["forces"][0]).all()

    def test_forces_from_finite_difference(self):
        assert self.job.calculator.available_properties == ["energy"]
        self.job.run("forces", finite_difference=True)
        ref_forces = np.array([[-0.0, -0.0, -0.32416448],
                               [-0.0, -0.0, 0.32416448]])
        assert np.isclose(self.job.results["forces"][0], ref_forces).all()

    def test_wacsf(self):
        self.jobwacsf.run("energy")
        assert self.jobwacsf.results["energy"] is not None

    def test_bad_property(self):
        with pytest.raises(ValueError):
            self.job.run("dipole")

    def test_convert(self):
        pos_angstrom = Posinp.from_file(
            os.path.join(pos_folder, "H2O_unrelaxed.xyz"))
        pos_atomic = Posinp.from_file(
            os.path.join(pos_folder, "H2O_atomic.xyz"))
        job1 = Job(posinp=pos_angstrom, calculator=self.calc3)
        job2 = Job(posinp=pos_atomic, calculator=self.calc3)
        job1.run("energy")
        job2.run("energy")
        assert job1.results["energy"] == job2.results["energy"]
Пример #2
0
    def run(self, batch_size=128, **kwargs):
        r"""
        Parameters
        ----------
        batch_size : int
            Batch size used when passing the structures to the model
        **kwargs :
            Optional arguments for the geometry optimization.
            Only useful if the relaxation is unstable.
        """
        if self.relax:
            geopt = Geopt(posinp=self.posinp,
                          calculator=self.calculator,
                          **kwargs)
            geopt.run(batch_size=batch_size)
            self._ground_state = deepcopy(geopt.final_posinp)

        if self.finite_difference:
            job = Job(posinp=self._create_displacements(),
                      calculator=self.calculator)
            job.run(property="forces", batch_size=batch_size)
        else:
            job = Job(posinp=self._ground_state, calculator=self.calculator)
            job.run(property="hessian", batch_size=batch_size)
        self._post_proc(job)
Пример #3
0
    def test_both_models(self):
        ens = EnsembleCalculator(modelpaths=[self.model1, self.model2])
        job1 = Job(posinp=self.pos1, calculator=ens)
        job1.run("energy")
        assert job1.results["energy"] == np.array(-1277.0513)
        assert job1.results["energy_std"] == np.array(799.70636)

        ref_forces = np.array(
            [
                [0, 0.7647542, -7.8656354],
                [0, -2.2895808, 3.8240397],
                [0, 1.5248268, 4.0415955],
            ],
            dtype=np.float32,
        )
        ref_std = np.array(
            [
                [0, 0.03656149, 1.2570109],
                [0, 0.8168775, 0.4650414],
                [0, 0.8534391, 0.7919693],
            ],
            dtype=np.float32,
        )
        job2 = Job(posinp=self.pos1, calculator=ens)
        job2.run("forces")
        assert np.isclose(job2.results["forces"], ref_forces, atol=1e-04).all()
        assert np.isclose(job2.results["forces_std"], ref_std,
                          atol=1e-04).all()
 def test_convert(self):
     pos_angstrom = Posinp.from_file(
         os.path.join(pos_folder, "H2O_unrelaxed.xyz"))
     pos_atomic = Posinp.from_file(
         os.path.join(pos_folder, "H2O_atomic.xyz"))
     job1 = Job(posinp=pos_angstrom, calculator=self.calc3)
     job2 = Job(posinp=pos_atomic, calculator=self.calc3)
     job1.run("energy")
     job2.run("energy")
     assert job1.results["energy"] == job2.results["energy"]
Пример #5
0
def main(args):

    eval_name = args.modelpath.split("/")[-1]
    eval_file = "evaluation_" + eval_name + ".txt"
    if os.path.exists(eval_file):
        if args.overwrite:
            os.remove(eval_file)
        else:
            raise Exception(
                "The evaluation file already exists. Delete it or add the overwrite flag."
            )
    device = "cuda" if args.cuda else "cpu"
    calculator = mlcalcdriver.calculators.SchnetPackCalculator(args.modelpath,
                                                               device=device)

    with connect(args.dbpath) as db:
        answers, results = (
            [[] for _ in range(len(args.properties))],
            [[] for _ in range(len(args.properties))],
        )
        posinp = []
        for row in db.select():
            for i, prop in enumerate(args.properties):
                answers[i].append(row.data[prop])
            posinp.append(Posinp.from_ase(row.toatoms()))

            if len(posinp) == args.batch_size:
                job = Job(posinp=posinp, calculator=calculator)
                for i, prop in enumerate(args.properties):
                    job.run(prop, batch_size=args.batch_size)
                    results[i].append(job.results[prop].tolist())
                posinp = []
        if len(posinp) > 0:
            job = Job(posinp=posinp, calculator=calculator)
            for i, prop in enumerate(args.properties):
                job.run(prop, batch_size=args.batch_size)
                results[i].append(job.results[prop])
            posinp = []

    header, error = [], []
    for prop in args.properties:
        header += ["MAE_" + prop, "%Error_" + prop, "RMSE_" + prop]
    for l1, l2 in zip(answers, results):
        an, re = np.array(l1).flatten(), np.concatenate(l2).flatten()
        error.append(np.abs(an - re).mean())
        error.append(np.abs((an - re) / an).mean() * 100)
        error.append(np.sqrt(np.mean((an - re)**2)))

    with open(eval_file, "w") as file:
        wr = csv.writer(file)
        wr.writerow(header)
        wr.writerow(error)
Пример #6
0
 def test_H2O(self):
     init = Job(posinp=self.posH2O, calculator=self.calcH2O)
     init.run("energy")
     assert np.isclose(init.results["energy"][0], -2076.7576, atol=1e-4)
     geo = Geopt(posinp=self.posH2O, calculator=self.calcH2O)
     geo.run()
     assert 0.964 < geo.final_posinp.distance(0, 1) < 0.965
     assert (geo.final_posinp.distance(0, 1) -
             geo.final_posinp.distance(0, 2)) < 0.0001
     # TODO Check the angle
     final = Job(posinp=geo.final_posinp, calculator=self.calcH2O)
     final.run("energy")
     assert np.isclose(final.results["energy"][0], -2078.6301, atol=1e-4)
Пример #7
0
 def test_N2(self, capsys):
     init = Job(posinp=self.posN2, calculator=self.calcN2)
     init.run("energy")
     assert init.results["energy"][0] == -2978.2354
     geo = Geopt(posinp=self.posN2, calculator=self.calcN2)
     geo.run(recenter=True, verbose=2)
     output = capsys.readouterr()
     assert 1.101 < geo.final_posinp.distance(0, 1) < 1.103
     assert np.isclose(
         geo.final_posinp.positions[0, 2],
         -geo.final_posinp.positions[1, 2],
         atol=1e-6,
     )
     assert output.out is not None
     final = Job(posinp=geo.final_posinp, calculator=self.calcN2)
     final.run("energy")
     assert final.results["energy"][0] == -2979.6070
Пример #8
0
class TestJob:

    file1, file2, file3 = (
        os.path.join(pos_folder, "free.xyz"),
        os.path.join(pos_folder, "surface.xyz"),
        os.path.join(pos_folder, "N2.xyz"),
    )
    pos1, pos2, pos3 = (
        Posinp.from_file(file1),
        Posinp.from_file(file2),
        Posinp.from_file(file3),
    )
    dummy = Calculator(available_properties="",
                       units={
                           "positions": "atomic",
                           "energy": "eV"
                       })
    badCalc = dict()
    job = Job(name="test", posinp=[pos1, pos2, pos3], calculator=dummy)

    def test_raises_no_positions(self):
        with pytest.raises(ValueError):
            j = Job(calculator=self.dummy)

    def test_raises_posinp_types(self):
        with pytest.raises(TypeError):
            j = Job(posinp=[self.pos1, 1], calculator=self.dummy)

    def test_raises_bad_calc(self):
        with pytest.raises(TypeError):
            j = Job(posinp=[self.pos1], calculator=self.badCalc)

    def test_posinp_types(self):
        job1 = Job(posinp=self.pos1, calculator=self.dummy)
        job2 = Job(posinp=[self.pos1], calculator=self.dummy)
        assert job1.posinp == job2.posinp

    @pytest.mark.parametrize(
        "value, expected",
        [(job.name, "test"), (job.num_struct, 3), (job.posinp[1], pos2)],
    )
    def test_values(self, value, expected):
        assert value == expected
Пример #9
0
 def test_posinp_types(self):
     job1 = Job(posinp=self.pos1, calculator=self.dummy)
     job2 = Job(posinp=[self.pos1], calculator=self.dummy)
     assert job1.posinp == job2.posinp
Пример #10
0
 def test_raises_bad_calc(self):
     with pytest.raises(TypeError):
         j = Job(posinp=[self.pos1], calculator=self.badCalc)
Пример #11
0
 def test_raises_posinp_types(self):
     with pytest.raises(TypeError):
         j = Job(posinp=[self.pos1, 1], calculator=self.dummy)
Пример #12
0
 def test_raises_no_positions(self):
     with pytest.raises(ValueError):
         j = Job(calculator=self.dummy)
Пример #13
0
    def test_same_result(self):
        j1 = Job(posinp=self.pos_2at, calculator=self.calc)
        j1.run("energy")
        e1 = j1.results["energy"]

        j2 = Job(posinp=self.pos_4at_red, calculator=self.calc)
        j2.run("energy")
        e2 = j2.results["energy"]

        pos_4at = deepcopy(self.pos_4at_red)
        pos_4at.convert_units("angstrom")
        j3 = Job(posinp=pos_4at, calculator=self.calc)
        j3.run("energy")
        e3 = j3.results["energy"]

        assert e2 == e3
        assert np.isclose(e2, 2 * e1, atol=0.0002)