Open stgeo opened 2 months ago
This is up to @j-wags but I'm a little down on this idea, or maybe I don't understand the motivation. Adding more and more keyword arguments to toolkit wrappers rapidly increases the complexity and makes the toolkit harder and harder to test and maintain, so IMHO there should be a high barrier to increasing API surface in these modules. This one in particular would probably only ever interact with AmberToolsToolkitWrapper
, but would be passed through the rest of the machinery (Molecule
, etc.).
If it's a matter of debugging installation issues, there are plenty of ways that can be handled externally to this. We have a script we sometimes use that reports information about the user's machine and setup, for example. If the installation issues stem from packaging ecosystems other than the one we support, then that's quickly of scope with what we handle. If there are modifications you want to make to how AmberTools is ultimately called, that can be done externally and the charges/conformers/etc. brought to the toolkit with the existing API. (charge_from_molecules
, add_conformers
, etc.) - these wrappers are meant to comprise a simple and uniform API, not something that goes deep into the nuts and bolts of each underlying tool.
I see your point - I also don't think this belongs in the API. But each toolkit wrapper has a lot of unique (possibly private) functions outside the uniform API, so I think adding a toggle (e.g. property, possibly private) to AmberToolsToolkitWrapper
which decides what to do with the intermediate files is a good option. Then one can instantiate the wrapper, set the toggle as desired, and register it in the ToolkitRegistry
(or even get the existing one from registered_toolkits
and just set the toggle in place).
Your suggestion to call AmberTools (or rather antechamber
) myself and provide the charges manually would of course work, and we may even end up going that route for other reasons.
However, I still think that if a single python function call (in this case assign_partial_charges
) produces multiple temporary files as a result of multiple system calls, which may fail not only due to installation issues, but also one of the many possible reasons that the AmberTools binaries may throw an error, it would be helpful to provide the user with a bit more than a generic exception. Giving them access to the files allows you to say "try to figure out what went wrong inside AmberTools by looking at these files" and wash your hands of the matter. There is even an existing TODO in the code with this exact sentiment - I forgot to mention it in the original post but I will add it now:
# Check to ensure charges were actually produced
if not os.path.exists(f"{tmpdir}/charges.txt"):
# TODO: copy files into local directory to aid debugging?
raise ChargeCalculationError(
"Antechamber/sqm partial charge calculation failed on "
"molecule {} (SMILES {})".format(
molecule.name, molecule.to_smiles()
)
)
To me this looks like the issue was already on your table so I would just like to add my vote in favor :slightly_smiling_face:
I think adding a toggle (e.g. property, possibly private) to AmberToolsToolkitWrapper which decides what to do with the intermediate files is a good option. Then one can instantiate the wrapper, set the toggle as desired, and register it in the ToolkitRegistry (or even get the existing one from registered_toolkits and just set the toggle in place).
Agree. I think that adding a new attribute like AmberToolsToolkitWrapper.temporary_file_directory
would be a good solution here. It would default to None
, which would give the current behavior, but if the user set it then the temp files would be kept. It wouldn't interfere with the standard interface, but would let power users customize whether temp files are kept.
I'd be happy to take a PR that does this! The test could run AM1BCC on something really small (like water) and ensure that some expected files are present in the specified directory.
Thanks, I'll see what I can do about that PR. Since I haven't contributed before and am not familiar with the layout of the project and the requirements for PRs and tests, would you kindly point me towards the relevant guidelines? I've seen this: https://docs.openforcefield.org/projects/toolkit/en/stable/users/developing.html - is there anything more detailed?
Sure! Unfortunately we don't have better resources on how to contribute, but a general outline for this one would be:
AmberToolsToolkitWrapper
in ambertools_wrapper.py
in that branch to have the changes described here_tests/test_toolkits.py
to have an additional test modeled like this one, but which changes the AmberToolsToolkitWrapper by setting the temporary file directory, and then asserts that the path and files exist after the charge calculation finishes. pytest
locally
Is your feature request related to a problem? Please describe. We've integrated part of the openff-toolkit into a closed-source project and so we need to distribute the AmberTools binaries separately to conform with the GPL. We had some issues when preparing the distribution (paths not set, missing libraries, etc.) and these were difficult to diagnose because the AmberTools wrapper deletes the temporary directory where antechamber is run regardless of whether the system calls were successful or not.
Describe the solution you'd like There should be an option to always keep the temporary directory and ideally the default behavior should be to keep it when antechamber returns a non-zero exit code. Not sure what implementation best fits the philosophy but I suppose it can either be an optional argument in the public methods of the
AmberToolsToolkitWrapper
(but so far these have the same call signature for all children ofToolkitWrapper
), an extra method which configures the behavior, or some global variable.There are some existing TODOs in the
assign_partial_charges
code hinting that this is a known issue:and
Describe alternatives you've considered As a workaround, we copied the entire
ambertools_wrapper.py
into our project and changed theassign_partial_charges
method to always keep the temporary directory (diff below). We then manually re-register this patched version into theGLOBAL_TOOLKIT_REGISTRY
. This is not ideal since we would need to port upstream changes there (or fork the whole openff-toolkit project to change these few lines).