MolSSI / QCEngine

Quantum chemistry program executor and IO standardizer (QCSchema).
https://molssi.github.io/QCEngine/
BSD 3-Clause "New" or "Revised" License
163 stars 78 forks source link

handle_output_metadata deletes .extras values if they were returned on a FailedOperation object #397

Open coltonbh opened 1 year ago

coltonbh commented 1 year ago

Describe the bug If the output_data passed to util.handle_output_metadata is a FailedOperation object (or corresponding dictionary) the reinstantiation of the FailedOperation object on lines 208-212 removes these values.

To Reproduce Pass any FailedOperation object containing values in the .extras field to handle_output_metadata and note that the returned object has these values removed.

Expected behavior All data on output_data fed to handle_output_metadata is included on the returned object, including .extras.

Additional context The TeraChemPBSHarness and TeraChemFrontendHarness both return AtomicResult or FailedOperation objects upon success/failure of a calculation. When the FailedOperation object is passed to handle_ouput_metadata the values in the .extras field get.

loriab commented 1 year ago

I agree it shouldn't be dropping fields. I'm not able to reproduct the problem, though. The test below has extras on output_data passed into handle_output_metadata, and both tests pass, albeit it's on FailedOperation.input_data. Do you have an example of the problem?

@using("psi4")
@pytest.mark.parametrize("goodin", [True, False])
def test_program_failed_extras(goodin):
    keywords = {} if goodin else {"badpsi4key": "badpsi4value"}
    inp = AtomicInput(
        **{
            "molecule": {"symbols": ["H", "H"], "geometry": [0, 0, 0, 0, 0, 2]},
            "driver": "energy",
            "model": {"method": "B3LYP", "basis": "sto-3g"},
            "keywords": {"scf_type": "df"},
            "extras": {"wfn_qcvars_only": True, "psi4:save_tamps": False},
            "keywords": keywords,
        }
    )

    ret = qcng.compute(inp, "psi4", raise_error=False, return_dict=False)

    import pprint
    pprint.pprint(ret.dict(), width=200)

    if goodin:
        assert isinstance(ret, AtomicResult)
        assert ret.success is True
        assert ret.extras["wfn_qcvars_only"] is True
    else:
        assert isinstance(ret, FailedOperation)
        assert ret.success is False
        assert ret.error.error_type == qcng.exceptions.InputError.error_type
        assert ret.input_data["extras"]["wfn_qcvars_only"] is True