From dc6e85df2899816ccc69ccbee38afde90364e4e2 Mon Sep 17 00:00:00 2001 From: Marco Foscato Date: Wed, 22 Nov 2023 00:23:39 +0100 Subject: [PATCH] moving generation of atom tags to chem.soft.-agnostic code --- .../java/autocompchem/atom/AtomUtils.java | 30 ++++------- .../chemsoftware/ChemSoftInputWriter.java | 23 ++++++-- .../autocompchem/chemsoftware/Directive.java | 8 +++ .../nwchem/NWChemInputWriter.java | 12 ----- .../autocompchem/molecule/MolecularUtils.java | 54 ++++++++++++++++++- .../java/autocompchem/atom/AtomUtilsTest.java | 37 +++++++++++++ .../molecule/MolecularUtilsTest.java | 43 +++++++++++++-- test/t87.check | 2 +- test/t87.params | 1 + test/t91.check | 5 -- test/t91.params | 1 + test/t92.params | 1 + test/t93.params | 1 + 13 files changed, 170 insertions(+), 48 deletions(-) diff --git a/src/main/java/autocompchem/atom/AtomUtils.java b/src/main/java/autocompchem/atom/AtomUtils.java index 7dad3a2b..36cfe9a0 100644 --- a/src/main/java/autocompchem/atom/AtomUtils.java +++ b/src/main/java/autocompchem/atom/AtomUtils.java @@ -345,15 +345,7 @@ public static String getSymbolOrLabel(IAtom atm) } else if (atm instanceof PseudoAtom) { - if (isPsaudoAtmWithLabel(atm,AtomConstants.DUMMYATMLABEL)) - { - res = AtomConstants.DUMMYATMLABEL; - } - else if (isPsaudoAtmWithLabel(atm, - AtomConstants.ATTACHMENTPOINTLABEL)) - { - res = AtomConstants.ATTACHMENTPOINTLABEL; - } + res = ((PseudoAtom) atm).getLabel(); } else if (atm instanceof Atom) { @@ -418,18 +410,14 @@ public static Integer countExplicitHydrogens(IAtom atm, IAtomContainer mol) public static Point3d getCoords3d(IAtom atom) { Point3d p3d = new Point3d(); - try { - Point2d atp2d = new Point2d(); - atp2d = atom.getPoint2d(); - p3d.x = atp2d.x; - p3d.y = atp2d.y; - p3d.z = 0.0000; - } catch (Throwable t) { - Point3d atp3d = new Point3d(); - atp3d = atom.getPoint3d(); - p3d.x = atp3d.x; - p3d.y = atp3d.y; - p3d.z = atp3d.z; + if (atom.getPoint3d()!=null) + { + Point3d atp3d = atom.getPoint3d(); + p3d = new Point3d(atp3d.x, atp3d.y, atp3d.z); + } else if (atom.getPoint2d()!=null) + { + Point2d atp2d = atom.getPoint2d(); + p3d = new Point3d(atp2d.x, atp2d.y, 0); } return p3d; } diff --git a/src/main/java/autocompchem/chemsoftware/ChemSoftInputWriter.java b/src/main/java/autocompchem/chemsoftware/ChemSoftInputWriter.java index 872b084b..e737a4e7 100644 --- a/src/main/java/autocompchem/chemsoftware/ChemSoftInputWriter.java +++ b/src/main/java/autocompchem/chemsoftware/ChemSoftInputWriter.java @@ -515,8 +515,12 @@ private void produceSingleJobInputFiles(List mols, molSpecJob.setParameter(ChemSoftConstants.PAROUTFILEROOT, outFileNameRoot, true); - // Add atom coordinates to the so-far molecule-agnostic job - setChemicalSystem(molSpecJob, mols); + // Add atom coordinates to the so-far possible molecule-agnostic job + if (useAtomTags) + setChemicalSystem(molSpecJob, makeAtomContainersWithAtomTags(mols)); + else + setChemicalSystem(molSpecJob, mols); + // We keep a copy of the agnostic chemical system definition in the job // parameters setChemicalSystemAsJobParam(molSpecJob, mols); @@ -543,7 +547,7 @@ private void produceSingleJobInputFiles(List mols, } } - // These calls take care also of the sub-jobs/directives + // This call takes care also of the sub-jobs/directives molSpecJob.processDirectives(mols, this.getMyJob()); // Ensure a value of charge and spin has been defined @@ -570,6 +574,19 @@ private void produceSingleJobInputFiles(List mols, } } +//------------------------------------------------------------------------------ + + private List makeAtomContainersWithAtomTags( + List mols) + { + List molsWithAtomTags = new ArrayList(); + for (IAtomContainer iac : mols) + { + molsWithAtomTags.add(MolecularUtils.makeSimpleCopyWithAtomTags(iac)); + } + return molsWithAtomTags; + } + //------------------------------------------------------------------------------ private void setChemicalSystemAsJobParam(CompChemJob job, diff --git a/src/main/java/autocompchem/chemsoftware/Directive.java b/src/main/java/autocompchem/chemsoftware/Directive.java index 418c7c69..b9315393 100644 --- a/src/main/java/autocompchem/chemsoftware/Directive.java +++ b/src/main/java/autocompchem/chemsoftware/Directive.java @@ -47,6 +47,7 @@ import autocompchem.modeling.basisset.BasisSetGenerator; import autocompchem.modeling.constraints.ConstraintsGenerator; import autocompchem.modeling.constraints.ConstraintsSet; +import autocompchem.molecule.MolecularUtils; import autocompchem.molecule.conformation.ConformationalSpace; import autocompchem.molecule.conformation.ConformationalSpaceGenerator; import autocompchem.molecule.intcoords.zmatrix.ZMatrix; @@ -1231,6 +1232,8 @@ private void performACCTask(List mols, ParameterStorage params, ChemSoftConstants.PARMULTIGEOMID).getValueAsString()); } + boolean useAtomTags = params.contains(ChemSoftConstants.PARUSEATMTAGS); + switch (coordsType) { case ZMAT: @@ -1244,6 +1247,7 @@ private void performACCTask(List mols, ParameterStorage params, Worker w = WorkerFactory.createWorker(zmatMakerTask, masterJob); ZMatrixHandler zmh = (ZMatrixHandler) w; + //TODO-gg make it use atom tags upon request ZMatrix zmat = zmh.makeZMatrix(); if (params.contains(ZMatrixConstants.SELECTORMODE)) { @@ -1290,6 +1294,10 @@ private void performACCTask(List mols, ParameterStorage params, default: { IAtomContainer mol = mols.get(geometryId); + if (useAtomTags) + { + mol = MolecularUtils.makeSimpleCopyWithAtomTags(mol); + } ((IValueContainer) dirComp).setValue(mol); break; } diff --git a/src/main/java/autocompchem/chemsoftware/nwchem/NWChemInputWriter.java b/src/main/java/autocompchem/chemsoftware/nwchem/NWChemInputWriter.java index aeb947ec..24bc442e 100644 --- a/src/main/java/autocompchem/chemsoftware/nwchem/NWChemInputWriter.java +++ b/src/main/java/autocompchem/chemsoftware/nwchem/NWChemInputWriter.java @@ -272,22 +272,10 @@ private ArrayList getTextForInput(Directive d) break; case IATOMCONTAINER: - boolean useTags = false; - if (data.getTaskParams()!=null - && data.getTaskParams().contains( - ChemSoftConstants.PARUSEATMTAGS)) - { - useTags = true; - } IAtomContainer mol = (IAtomContainer) data.getValue(); for (IAtom atm : mol.atoms()) { String atmId = AtomUtils.getSymbolOrLabel(atm); - if (useTags) - { - // Convention is to use 1-based indexing here - atmId = atmId + (mol.indexOf(atm)+1); - } Point3d p3d = AtomUtils.getCoords3d(atm); ddLines.add(String.format(Locale.ENGLISH," %3s", atmId) + String.format(Locale.ENGLISH," %10.6f",p3d.x) diff --git a/src/main/java/autocompchem/molecule/MolecularUtils.java b/src/main/java/autocompchem/molecule/MolecularUtils.java index ef81310f..eb3a07d8 100644 --- a/src/main/java/autocompchem/molecule/MolecularUtils.java +++ b/src/main/java/autocompchem/molecule/MolecularUtils.java @@ -30,13 +30,19 @@ import javax.vecmath.Point3d; import javax.vecmath.Vector3d; +import org.openscience.cdk.Atom; +import org.openscience.cdk.Bond; import org.openscience.cdk.CDKConstants; +import org.openscience.cdk.DefaultChemObjectBuilder; +import org.openscience.cdk.PseudoAtom; import org.openscience.cdk.aromaticity.Kekulization; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.interfaces.IAtom; import org.openscience.cdk.interfaces.IAtomContainer; import org.openscience.cdk.interfaces.IBond; +import org.openscience.cdk.interfaces.IChemObjectBuilder; import org.openscience.cdk.interfaces.IBond.Order; +import org.openscience.cdk.tools.periodictable.PeriodicTable; import autocompchem.atom.AtomUtils; import autocompchem.geometry.DistanceMatrix; @@ -58,6 +64,9 @@ public class MolecularUtils //TODO move to constants @SuppressWarnings("unused") private static double linearBendThld = 175.0; + + private static IChemObjectBuilder chemBuilder = + DefaultChemObjectBuilder.getInstance(); //------------------------------------------------------------------------------ @@ -807,7 +816,50 @@ public static void ensureNoUnsetBondOrders(IAtomContainer mol) } } } - + +//------------------------------------------------------------------------------ + + /** + * Makes a simplified copy of the given {@link IAtomContainer} considering + * only the list of atoms as elements/labels and points in 3D, set of bonds, + * and container title/name, + * without any further property of atoms, bonds, or of the container, and + * sets the atom label to be an atom tag, i.e., a string that allows to + * identify the atom (e.g., "C3"). The tag is generated by concatenating + * the elemental symbol (or initial {@link PseudoAtom} label) with the + * 1-based index of the atom in the given container. + * @param iac the original atom container to copy and decorate with atom + * tags. + * @return the copy of the original container with the atom tags. + */ + public static IAtomContainer makeSimpleCopyWithAtomTags(IAtomContainer iac) + { + IAtomContainer iacWithTags = chemBuilder.newAtomContainer(); + int iAtm = 0; + for (IAtom origAtm : iac.atoms()) + { + iAtm++; + String atomTag = AtomUtils.getSymbolOrLabel(origAtm) + iAtm; + IAtom atmWithTag = new PseudoAtom(atomTag); + Point3d p3d = AtomUtils.getCoords3d(origAtm); + atmWithTag.setPoint3d(new Point3d(p3d.x, p3d.y, p3d.z)); + iacWithTags.addAtom(atmWithTag); + } + for (IBond origBnd : iac.bonds()) + { + IAtom[] atomsInNewBond = new IAtom[origBnd.getAtomCount()]; + for (int i=0; i