void expandNode(Node node) { // System.out.println(node.toString(target)); QuerySequenceElement el = sequence.get(node.sequenceElNum); if (el.center == null) // This node describers a bond that closes a ring { // Checking whether this bond is present in the target IAtom tAt0 = node.atoms[query.getAtomNumber(el.atoms[0])]; IAtom tAt1 = node.atoms[query.getAtomNumber(el.atoms[1])]; IBond tBo = target.getBond(tAt0, tAt1); if (tBo != null) if (el.bonds[0].matches(tBo)) { node.sequenceElNum++; // stack.push(node); if (node.sequenceElNum == sequence.size()) { // The node is not added in the stack if the end of the sequence is reached isomorphismFound = true; if (FlagStoreIsomorphismNode) isomorphismNodes.add(node); } else stack.push(node); } } else { targetAt.clear(); IAtom tAt = node.atoms[el.centerNum]; List<IAtom> conAt = target.getConnectedAtomsList(tAt); for (int i = 0; i < conAt.size(); i++) { if (!containsAtom(node.atoms, conAt.get(i))) targetAt.add(conAt.get(i)); } if (el.atoms.length <= targetAt.size()) generateNodes(node); } }
private boolean isTerminal(IAtom atom, IAtomContainer atomContainer) { int numberOfHeavyAtomsConnected = 0; for (IAtom connected : atomContainer.getConnectedAtomsList(atom)) { if (connected.getSymbol().equals("H")) { continue; } ++numberOfHeavyAtomsConnected; } return numberOfHeavyAtomsConnected < 2; }
/** * Partition the bonding partners of a given atom into ring atoms and non-ring atoms * * @param atom The atom whose bonding partners are to be partitioned * @param ring The ring against which the bonding partners are checked * @param ringAtoms An AtomContainer to store the ring bonding partners * @param nonRingAtoms An AtomContainer to store the non-ring bonding partners */ public void partitionNonRingPartners( IAtom atom, IRing ring, IAtomContainer ringAtoms, IAtomContainer nonRingAtoms) { java.util.List atoms = molecule.getConnectedAtomsList(atom); for (int i = 0; i < atoms.size(); i++) { IAtom curAtom = (IAtom) atoms.get(i); if (!ring.contains(curAtom)) { nonRingAtoms.addAtom(curAtom); } else { ringAtoms.addAtom(curAtom); } } }
/** * Returns the bridge atoms, that is the outermost atoms in the chain of more than two atoms which * are shared by two rings * * @param sharedAtoms The atoms (n > 2) which are shared by two rings * @return The bridge atoms, i.e. the outermost atoms in the chain of more than two atoms which * are shared by two rings */ private IAtom[] getBridgeAtoms(IAtomContainer sharedAtoms) { IAtom[] bridgeAtoms = new IAtom[2]; IAtom atom; int counter = 0; for (int f = 0; f < sharedAtoms.getAtomCount(); f++) { atom = sharedAtoms.getAtom(f); if (sharedAtoms.getConnectedAtomsList(atom).size() == 1) { bridgeAtoms[counter] = atom; counter++; } } return bridgeAtoms; }
private Map<IAtom, List<String>> labelAtomsBySymbol(IAtomContainer atomCont) { Map<IAtom, List<String>> label_list = new HashMap<>(); for (int i = 0; i < atomCont.getAtomCount(); i++) { List<String> label = new ArrayList<>(7); for (int a = 0; a < 7; a++) { label.add(a, "Z9"); } IAtom refAtom = atomCont.getAtom(i); /* * Important Step: Discriminate between source atom types */ String referenceAtom; if (refAtom instanceof IQueryAtom) { referenceAtom = ((IQueryAtom) refAtom).getSymbol() == null ? "*" : ((IQueryAtom) refAtom).getSymbol(); // System.out.println("referenceAtom " + referenceAtom); } else if (!(refAtom instanceof IQueryAtom) && this.matchAtomType) { referenceAtom = refAtom.getAtomTypeName() == null ? refAtom.getSymbol() : refAtom.getAtomTypeName(); } else { referenceAtom = refAtom.getSymbol(); } label.set(0, referenceAtom); List<IAtom> connAtoms = atomCont.getConnectedAtomsList(refAtom); int counter = 1; for (IAtom negAtom : connAtoms) { String neighbouringAtom; if (refAtom instanceof IQueryAtom) { neighbouringAtom = ((IQueryAtom) negAtom).getSymbol() == null ? "*" : ((IQueryAtom) negAtom).getSymbol(); // System.out.println("neighbouringAtom " + neighbouringAtom); } else if (!(negAtom instanceof IQueryAtom) && this.matchAtomType) { neighbouringAtom = negAtom.getAtomTypeName() == null ? negAtom.getSymbol() : negAtom.getAtomTypeName(); } else { neighbouringAtom = negAtom.getSymbol(); } label.set(counter, neighbouringAtom); counter += 1; } // System.out.println("label " + label); bubbleSort(label); label_list.put(refAtom, label); } return label_list; }
/** * Obtain the ligands connected to the 'atom' excluding 'exclude'. This is mainly meant as util * for double-bond labelling. * * @param atom an atom * @param container a structure to which 'atom' belongs * @param exclude exclude this atom - can not be null * @return the ligands */ private static ILigand[] getLigands(IAtom atom, IAtomContainer container, IAtom exclude) { List<IAtom> neighbors = container.getConnectedAtomsList(atom); ILigand[] ligands = new ILigand[neighbors.size() - 1]; int i = 0; for (IAtom neighbor : neighbors) { if (neighbor != exclude) ligands[i++] = new Ligand(container, new VisitedAtoms(), atom, neighbor); } return ligands; }
/** * Place hydrogens connected to the provided atom <i>atom</i> using the specified * <i>bondLength</i>. * * @param container atom container * @param bondLength bond length to user * @throws IllegalArgumentException thrown if the <i>atom</i> or <i>container</i> was null or the * atom has connected atoms which have not been placed. */ @TestMethod("testNoConnections,testNullContainer,unplacedNonHydrogen") public void placeHydrogens2D(IAtomContainer container, IAtom atom, double bondLength) { if (container == null) throw new IllegalArgumentException("cannot place hydrogens, no container provided"); if (atom.getPoint2d() == null) throw new IllegalArgumentException("cannot place hydrogens on atom without coordinates"); logger.debug( "placing hydrogens connected to atom ", atom.getSymbol(), ": ", atom.getPoint2d()); logger.debug("bond length", bondLength); AtomPlacer atomPlacer = new AtomPlacer(); atomPlacer.setMolecule(container); List<IAtom> connected = container.getConnectedAtomsList(atom); IAtomContainer placed = container.getBuilder().newInstance(IAtomContainer.class); IAtomContainer unplaced = container.getBuilder().newInstance(IAtomContainer.class); // divide connected atoms into those which are have and haven't been placed for (final IAtom conAtom : connected) { if (conAtom.getPoint2d() == null) { if (conAtom.getSymbol().equals("H")) { unplaced.addAtom(conAtom); } else { throw new IllegalArgumentException( "cannot place hydrogens, atom has connected" + " non-hydrogens without coordinates"); } } else { placed.addAtom(conAtom); } } logger.debug("Atom placement before procedure:"); logger.debug("Centre atom ", atom.getSymbol(), ": ", atom.getPoint2d()); for (int i = 0; i < unplaced.getAtomCount(); i++) { logger.debug("H-" + i, ": ", unplaced.getAtom(i).getPoint2d()); } Point2d centerPlacedAtoms = GeometryTools.get2DCenter(placed); atomPlacer.distributePartners(atom, placed, centerPlacedAtoms, unplaced, bondLength); logger.debug("Atom placement after procedure:"); logger.debug("Centre atom ", atom.getSymbol(), ": ", atom.getPoint2d()); for (int i = 0; i < unplaced.getAtomCount(); i++) { logger.debug("H-" + i, ": ", unplaced.getAtom(i).getPoint2d()); } }
/** * Prepare the target molecule for analysis. * * <p>We perform ring perception and aromaticity detection and set up the appropriate properties. * Right now, this function is called each time we need to do a query and this is inefficient. * * @throws CDKException if there is a problem in ring perception or aromaticity detection, which * is usually related to a timeout in the ring finding code. */ private void initializeMolecule() throws CDKException { // Code copied from // org.openscience.cdk.qsar.descriptors.atomic.AtomValenceDescriptor; Map<String, Integer> valencesTable = new HashMap<String, Integer>(); valencesTable.put("H", 1); valencesTable.put("Li", 1); valencesTable.put("Be", 2); valencesTable.put("B", 3); valencesTable.put("C", 4); valencesTable.put("N", 5); valencesTable.put("O", 6); valencesTable.put("F", 7); valencesTable.put("Na", 1); valencesTable.put("Mg", 2); valencesTable.put("Al", 3); valencesTable.put("Si", 4); valencesTable.put("P", 5); valencesTable.put("S", 6); valencesTable.put("Cl", 7); valencesTable.put("K", 1); valencesTable.put("Ca", 2); valencesTable.put("Ga", 3); valencesTable.put("Ge", 4); valencesTable.put("As", 5); valencesTable.put("Se", 6); valencesTable.put("Br", 7); valencesTable.put("Rb", 1); valencesTable.put("Sr", 2); valencesTable.put("In", 3); valencesTable.put("Sn", 4); valencesTable.put("Sb", 5); valencesTable.put("Te", 6); valencesTable.put("I", 7); valencesTable.put("Cs", 1); valencesTable.put("Ba", 2); valencesTable.put("Tl", 3); valencesTable.put("Pb", 4); valencesTable.put("Bi", 5); valencesTable.put("Po", 6); valencesTable.put("At", 7); valencesTable.put("Fr", 1); valencesTable.put("Ra", 2); valencesTable.put("Cu", 2); valencesTable.put("Mn", 2); valencesTable.put("Co", 2); // do all ring perception AllRingsFinder arf = new AllRingsFinder(); IRingSet allRings; try { allRings = arf.findAllRings(atomContainer); } catch (CDKException e) { logger.debug(e.toString()); throw new CDKException(e.toString(), e); } // sets SSSR information SSSRFinder finder = new SSSRFinder(atomContainer); IRingSet sssr = finder.findEssentialRings(); for (IAtom atom : atomContainer.atoms()) { // add a property to each ring atom that will be an array of // Integers, indicating what size ring the given atom belongs to // Add SSSR ring counts if (allRings.contains(atom)) { // it's in a ring atom.setFlag(CDKConstants.ISINRING, true); // lets find which ring sets it is a part of List<Integer> ringsizes = new ArrayList<Integer>(); IRingSet currentRings = allRings.getRings(atom); int min = 0; for (int i = 0; i < currentRings.getAtomContainerCount(); i++) { int size = currentRings.getAtomContainer(i).getAtomCount(); if (min > size) min = size; ringsizes.add(size); } atom.setProperty(CDKConstants.RING_SIZES, ringsizes); atom.setProperty(CDKConstants.SMALLEST_RINGS, sssr.getRings(atom)); } else { atom.setFlag(CDKConstants.ISINRING, false); } // determine how many rings bonds each atom is a part of int hCount; if (atom.getImplicitHydrogenCount() == CDKConstants.UNSET) hCount = 0; else hCount = atom.getImplicitHydrogenCount(); List<IAtom> connectedAtoms = atomContainer.getConnectedAtomsList(atom); int total = hCount + connectedAtoms.size(); for (IAtom connectedAtom : connectedAtoms) { if (connectedAtom.getSymbol().equals("H")) { hCount++; } } atom.setProperty(CDKConstants.TOTAL_CONNECTIONS, total); atom.setProperty(CDKConstants.TOTAL_H_COUNT, hCount); if (valencesTable.get(atom.getSymbol()) != null) { int formalCharge = atom.getFormalCharge() == CDKConstants.UNSET ? 0 : atom.getFormalCharge(); atom.setValency(valencesTable.get(atom.getSymbol()) - formalCharge); } } for (IBond bond : atomContainer.bonds()) { if (allRings.getRings(bond).getAtomContainerCount() > 0) { bond.setFlag(CDKConstants.ISINRING, true); } } for (IAtom atom : atomContainer.atoms()) { List<IAtom> connectedAtoms = atomContainer.getConnectedAtomsList(atom); int counter = 0; IAtom any; for (IAtom connectedAtom : connectedAtoms) { any = connectedAtom; if (any.getFlag(CDKConstants.ISINRING)) { counter++; } } atom.setProperty(CDKConstants.RING_CONNECTIONS, counter); } // check for atomaticity try { AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(atomContainer); CDKHueckelAromaticityDetector.detectAromaticity(atomContainer); } catch (CDKException e) { logger.debug(e.toString()); throw new CDKException(e.toString(), e); } }
/** * This routine is called 'getRing() in Figueras original article finds the smallest ring of which * rootNode is part of. * * @param rootNode The Atom to be searched for the smallest ring it is part of * @param molecule The molecule that contains the rootNode * @return The smallest Ring rootnode is part of */ private IRing getRing(IAtom rootNode, IAtomContainer molecule) { IAtom node, neighbor, mAtom; List neighbors, mAtoms; /** OKatoms is Figueras nomenclature, giving the number of atoms in the structure */ int OKatoms = molecule.getAtomCount(); /** queue for Breadth First Search of this graph */ Queue queue = new Queue(); /* Initialize a path Vector for each node */ // Vector pfad1,pfad2; List<List<IAtom>> path = new ArrayList<List<IAtom>>(OKatoms); List<IAtom> intersection = new ArrayList<IAtom>(); List<IAtom> ring = new ArrayList<IAtom>(); for (int f = 0; f < OKatoms; f++) { path.set(f, new ArrayList<IAtom>()); ((List<IAtom>) molecule.getAtom(f).getProperty(PATH)).clear(); } // Initialize the queue with nodes attached to rootNode neighbors = molecule.getConnectedAtomsList(rootNode); for (int f = 0; f < neighbors.size(); f++) { // if the degree of the f-st neighbor of rootNode is greater // than zero (i.e., it has not yet been deleted from the list) neighbor = (IAtom) neighbors.get(f); // push the f-st node onto our FIFO queue // after assigning rootNode as its source queue.push(neighbor); ((List<IAtom>) neighbor.getProperty(PATH)).add(rootNode); ((List<IAtom>) neighbor.getProperty(PATH)).add(neighbor); } while (queue.size() > 0) { node = (IAtom) queue.pop(); mAtoms = molecule.getConnectedAtomsList(node); for (int f = 0; f < mAtoms.size(); f++) { mAtom = (IAtom) mAtoms.get(f); if (mAtom != ((List) node.getProperty(PATH)) .get(((List<IAtom>) node.getProperty(PATH)).size() - 2)) { if (((List) mAtom.getProperty(PATH)).size() > 0) { intersection = getIntersection((List) node.getProperty(PATH), (List) mAtom.getProperty(PATH)); if (intersection.size() == 1) { // we have found a valid ring closure // now let's prepare the path to // return in tempAtomSet logger.debug("path1 ", ((List) node.getProperty(PATH))); logger.debug("path2 ", ((List) mAtom.getProperty(PATH))); logger.debug("rootNode ", rootNode); logger.debug("ring ", ring); ring = getUnion((List) node.getProperty(PATH), (List) mAtom.getProperty(PATH)); return prepareRing(ring, molecule); } } else { // if path[mNumber] is null // update the path[mNumber] // pfad2 = (Vector)node.getProperty(PATH); mAtom.setProperty(PATH, new ArrayList<IAtom>((List<IAtom>) node.getProperty(PATH))); ((List<IAtom>) mAtom.getProperty(PATH)).add(mAtom); // pfad1 = (Vector)mAtom.getProperty(PATH); // now push the node m onto the queue queue.push(mAtom); } } } } return null; }
/** * calculates the kier shape indices for an atom container * * @param container AtomContainer * @return kier1, kier2 and kier3 are returned as arrayList of doubles * @throws CDKException Possible Exceptions */ @Override public DescriptorValue calculate(IAtomContainer container) { IAtomContainer atomContainer; try { atomContainer = (IAtomContainer) container.clone(); } catch (CloneNotSupportedException e) { DoubleArrayResult kierValues = new DoubleArrayResult(3); kierValues.add(Double.NaN); kierValues.add(Double.NaN); kierValues.add(Double.NaN); return new DescriptorValue( getSpecification(), getParameterNames(), getParameters(), kierValues, getDescriptorNames()); } atomContainer = AtomContainerManipulator.removeHydrogens(atomContainer); // org.openscience.cdk.interfaces.IAtom[] atoms = atomContainer.getAtoms(); java.util.List firstAtomNeighboors; java.util.List secondAtomNeighboors; java.util.List thirdAtomNeighboors; DoubleArrayResult kierValues = new DoubleArrayResult(3); double bond1; double bond2; double bond3; double kier1; double kier2; double kier3; double atomsCount = atomContainer.getAtomCount(); ArrayList<Double> singlePaths = new ArrayList<Double>(); ArrayList<String> doublePaths = new ArrayList<String>(); ArrayList<String> triplePaths = new ArrayList<String>(); double[] sorterFirst = new double[2]; double[] sorterSecond = new double[3]; String tmpbond2; String tmpbond3; for (int a1 = 0; a1 < atomsCount; a1++) { bond1 = 0; firstAtomNeighboors = atomContainer.getConnectedAtomsList(atomContainer.getAtom(a1)); for (int a2 = 0; a2 < firstAtomNeighboors.size(); a2++) { bond1 = atomContainer.getBondNumber( atomContainer.getAtom(a1), (IAtom) firstAtomNeighboors.get(a2)); if (!singlePaths.contains(new Double(bond1))) { singlePaths.add(bond1); java.util.Collections.sort(singlePaths); } secondAtomNeighboors = atomContainer.getConnectedAtomsList((IAtom) firstAtomNeighboors.get(a2)); for (int a3 = 0; a3 < secondAtomNeighboors.size(); a3++) { bond2 = atomContainer.getBondNumber( (IAtom) firstAtomNeighboors.get(a2), (IAtom) secondAtomNeighboors.get(a3)); if (!singlePaths.contains(new Double(bond2))) { singlePaths.add(bond2); } sorterFirst[0] = bond1; sorterFirst[1] = bond2; java.util.Arrays.sort(sorterFirst); tmpbond2 = sorterFirst[0] + "+" + sorterFirst[1]; if (!doublePaths.contains(tmpbond2) && (bond1 != bond2)) { doublePaths.add(tmpbond2); } thirdAtomNeighboors = atomContainer.getConnectedAtomsList((IAtom) secondAtomNeighboors.get(a3)); for (int a4 = 0; a4 < thirdAtomNeighboors.size(); a4++) { bond3 = atomContainer.getBondNumber( (IAtom) secondAtomNeighboors.get(a3), (IAtom) thirdAtomNeighboors.get(a4)); if (!singlePaths.contains(new Double(bond3))) { singlePaths.add(bond3); } sorterSecond[0] = bond1; sorterSecond[1] = bond2; sorterSecond[2] = bond3; java.util.Arrays.sort(sorterSecond); tmpbond3 = sorterSecond[0] + "+" + sorterSecond[1] + "+" + sorterSecond[2]; if (!triplePaths.contains(tmpbond3)) { if ((bond1 != bond2) && (bond1 != bond3) && (bond2 != bond3)) { triplePaths.add(tmpbond3); } } } } } } if (atomsCount == 1) { kier1 = 0; kier2 = 0; kier3 = 0; } else { kier1 = (((atomsCount) * ((atomsCount - 1) * (atomsCount - 1))) / (singlePaths.size() * singlePaths.size())); if (atomsCount == 2) { kier2 = 0; kier3 = 0; } else { if (doublePaths.size() == 0) kier2 = Double.NaN; else kier2 = (((atomsCount - 1) * ((atomsCount - 2) * (atomsCount - 2))) / (doublePaths.size() * doublePaths.size())); if (atomsCount == 3) { kier3 = 0; } else { if (atomsCount % 2 != 0) { if (triplePaths.size() == 0) kier3 = Double.NaN; else kier3 = (((atomsCount - 1) * ((atomsCount - 3) * (atomsCount - 3))) / (triplePaths.size() * triplePaths.size())); } else { if (triplePaths.size() == 0) kier3 = Double.NaN; else kier3 = (((atomsCount - 3) * ((atomsCount - 2) * (atomsCount - 2))) / (triplePaths.size() * triplePaths.size())); } } } } kierValues.add(kier1); kierValues.add(kier2); kierValues.add(kier3); return new DescriptorValue( getSpecification(), getParameterNames(), getParameters(), kierValues, getDescriptorNames()); }