/// <summary> /// Creates a new instance of MolHandler /// </summary> /// <param name="molFile">atomContainer file name</param> public MolHandler(string molFile, bool removeHydrogen, bool cleanMolecule) { MDLReader molRead = null; this.removeHydrogen = removeHydrogen; try { Stream readMolecule = null; readMolecule = new FileStream(molFile, FileMode.Open, FileAccess.Read); molRead = new MDLReader(new StreamReader(readMolecule)); this.atomContainer = (IAtomContainer)molRead.Read(new AtomContainer()); molRead.Close(); readMolecule.Close(); /* Remove Hydrogen by Asad */ if (removeHydrogen) { atomContainer = ExtAtomContainerManipulator.RemoveHydrogensExceptSingleAndPreserveAtomID(atomContainer); } if (cleanMolecule) { if (!IsPseudoAtoms()) { atomContainer = canonLabeler.GetCanonicalMolecule(atomContainer); } // percieve atoms, set valency etc ExtAtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(atomContainer); //Add implicit Hydrogens var adder = CDK.HydrogenAdder; adder.AddImplicitHydrogens(atomContainer); // figure out which atoms are in aromatic rings: Aromaticity.CDKLegacy.Apply(atomContainer); BondTools.MakeUpDownBonds(atomContainer); } } catch (IOException ex) { Debug.WriteLine(ex); } catch (CDKException e) { Console.Error.WriteLine(e); } finally { if (molRead != null) { try { molRead.Close(); } catch (IOException ioe) { Trace.TraceWarning("Couldn't close molReader: ", ioe.Message); Debug.WriteLine(ioe); } } } }
/// <summary> /// Places the atoms in a linear chain. /// </summary> /// <remarks> /// Expects the first atom to be placed and /// places the next atom according to initialBondVector. The rest of the chain /// is placed such that it is as linear as possible (in the overall result, the /// angles in the chain are set to 120 Deg.) /// </remarks> /// <param name="atomContainer">The IAtomContainer containing the chain atom to be placed</param> /// <param name="initialBondVector">The Vector indicating the direction of the first bond</param> /// <param name="bondLength">The factor used to scale the initialBondVector</param> public void PlaceLinearChain(IAtomContainer atomContainer, Vector2 initialBondVector, double bondLength) { var withh = atomContainer.Builder.NewAtomContainer(atomContainer); // BUGFIX - withh does not have cloned cloned atoms, so changes are // reflected in our atom container. If we're using implicit hydrogens // the correct counts need saving and restoring var numh = new int[atomContainer.Atoms.Count]; for (int i = 0, n = atomContainer.Atoms.Count; i < n; i++) { numh[i] = atomContainer.Atoms[i].ImplicitHydrogenCount ?? 0; } Debug.WriteLine($"Placing linear chain of length {atomContainer.Atoms.Count}"); var bondVector = initialBondVector; IBond prevBond = null; for (int f = 0; f < atomContainer.Atoms.Count - 1; f++) { var atom = atomContainer.Atoms[f]; var nextAtom = atomContainer.Atoms[f + 1]; var currBond = atomContainer.GetBond(atom, nextAtom); var atomPoint = atom.Point2D.Value; bondVector = Vector2.Normalize(bondVector); bondVector = bondVector * bondLength; atomPoint += bondVector; nextAtom.Point2D = atomPoint; nextAtom.IsPlaced = true; bool trans = false; if (prevBond != null && IsColinear(atom, Molecule.GetConnectedBonds(atom))) { int atomicNumber = atom.AtomicNumber; int charge = atom.FormalCharge.Value; // double length of the last bond to determining next placement var p = prevBond.GetOther(atom).Point2D.Value; p = Vector2.Lerp(p, atom.Point2D.Value, 2); nextAtom.Point2D = p; } if (GeometryUtil.Has2DCoordinates(atomContainer)) { try { if (f > 2 && BondTools.IsValidDoubleBondConfiguration(withh, withh.GetBond(withh.Atoms[f - 2], withh.Atoms[f - 1]))) { trans = BondTools.IsCisTrans(withh.Atoms[f - 3], withh.Atoms[f - 2], withh.Atoms[f - 1], withh.Atoms[f - 0], withh); } } catch (Exception) { Debug.WriteLine("Exception in detecting E/Z. This could mean that cleanup does not respect E/Z"); } bondVector = GetNextBondVector(nextAtom, atom, GeometryUtil.Get2DCenter(Molecule), trans); } else { bondVector = GetNextBondVector(nextAtom, atom, GeometryUtil.Get2DCenter(Molecule), true); } prevBond = currBond; } // BUGFIX part 2 - restore hydrogen counts for (int i = 0, n = atomContainer.Atoms.Count; i < n; i++) { atomContainer.Atoms[i].ImplicitHydrogenCount = numh[i]; } }