geometric-pyo3 0.1.2

PyO3 (Rust) interface to geomeTRIC (molecular structure geometry optimization program)
Documentation
//! Main optimizer interface for geomeTRIC.

use pyo3::prelude::*;
use pyo3::types::PyDict;
use tempfile::NamedTempFile;

/// Run the optimization using the custom engine and parameters.
///
/// - `custom_engine`: The custom engine to use for the optimization.
/// - `params`: The parameters for the optimization.
/// - `input`: Optional input file path. If `None`, a temporary file will be
///   created.
pub fn run_optimization(
    custom_engine: PyObject,
    params: &Py<PyDict>,
    input: Option<&str>,
) -> PyResult<PyObject> {
    Python::with_gil(|py| {
        // Import the geometric Python module
        let run_optimizer = py.import("geometric.optimize")?.getattr("run_optimizer")?;

        // kwargs for run_optimizer: make a deep copy of the params
        let deepcopy = py.import("copy")?.getattr("deepcopy")?;
        let kwargs = deepcopy.call1((params,))?.extract::<Bound<PyDict>>()?;

        // Create a temporary file anyway
        let tmpfile = NamedTempFile::new()?;
        let tmp_path = tmpfile.path().to_str().unwrap();

        // Only use the temporary file if input is None
        match input {
            Some(input) => kwargs.set_item("input", input)?,
            None => kwargs.set_item("input", tmp_path)?,
        }

        // Update custom_engine in kwargs
        kwargs.set_item("customengine", custom_engine)?;
        let result = run_optimizer.call((), Some(&kwargs))?;
        Ok(result.into())
    })
}