Returns the largest (number of atoms) ring set in a molecule.

@param ringSystems RingSystems of a molecule
@return The largestRingSet
332864
public IRingSet getLargestRingSet(List<IRingSet> ringSystems) {
        IRingSet       largestRingSet = null;
        int            atomNumber     = 0;
        IAtomContainer container      = null;
        for (int i = 0; i < ringSystems.size(); i++) {
            container = getAllInOneContainer(ringSystems.get(i));
            if (atomNumber < container.getAtomCount()) {
                atomNumber = container.getAtomCount();
                largestRingSet = ringSystems.get(i);
            }
        }
        return largestRingSet;
    }
286542
public static IAtomContainerSet getAllAtomContainers(IReactionScheme scheme, IAtomContainerSet molSet) {
        // A ReactionScheme can contain other IRreactionSet objects
        if (scheme.getReactionSchemeCount() != 0) for (IReactionScheme rm : scheme.reactionSchemes()) {
            for (IAtomContainer ac : getAllAtomContainers(rm, molSet).atomContainers()) {
                boolean contain = false;
                for (IAtomContainer atomContainer : molSet.atomContainers()) {
                    if (atomContainer.equals(ac)) {
                        contain = true;
                        break;
                    }
                }
                if (!contain) molSet.addAtomContainer((IAtomContainer) (ac));
            }
        }
        for (IReaction reaction : scheme.reactions()) {
            List<IAtomContainer> newAtomContainerSet = ReactionManipulator.getAllAtomContainers(reaction);
            for (IAtomContainer ac : newAtomContainerSet) {
                boolean contain = false;
                for (IAtomContainer atomContainer : molSet.atomContainers()) {
                    if (atomContainer.equals(ac)) {
                        contain = true;
                        break;
                    }
                }
                if (!contain) molSet.addAtomContainer(ac);

            }
        }

        return molSet;
    }
224689
private MacroScore bestScore(IRing macrocycle, IRingSet ringset, int wind, int[] winding) {

        final int numAtoms = macrocycle.getAtomCount();

        List<Integer> heteroIdxs = new ArrayList<>();
        List<List<Integer>> ringAttachs = new ArrayList<>();

        // hetero atoms
        for (int i = 0; i < numAtoms; i++) {
            if (macrocycle.getAtom(i).getAtomicNumber() != 6)
                heteroIdxs.add(i);
        }
        for (IAtomContainer other : ringset.atomContainers()) {
            if (other == macrocycle)
                continue;
            IAtomContainer shared = AtomContainerManipulator.getIntersection(macrocycle, other);

            if (shared.getAtomCount() >= 2 && shared.getAtomCount() <= 4)
                ringAttachs.add(getAttachedInOrder(macrocycle, shared));
        }

        // convex and concave are relative
        final int convex = wind;
        final int concave = -wind;

        MacroScore best = null;

        for (int i = 0; i < winding.length; i++) {

            // score ring attachs
            int nRingClick = 0;
            for (List<Integer> ringAttach : ringAttachs) {
                int r1, r2, r3, r4;
                switch (ringAttach.size()) {
                    case 2:
                        r1 = (ringAttach.get(0) + i) % numAtoms;
                        r2 = (ringAttach.get(1) + i) % numAtoms;
                        if (winding[r1] == winding[r2]) {
                            if (winding[r1] == convex)
                                nRingClick += 5;
                            else
                                nRingClick++;
                        }
                        break;
                    case 3:
                        r1 = (ringAttach.get(0) + i) % numAtoms;
                        r2 = (ringAttach.get(1) + i) % numAtoms;
                        r3 = (ringAttach.get(2) + i) % numAtoms;
                        if (winding[r1] == convex &&
                            winding[r2] == concave &&
                            winding[r3] == convex)
                            nRingClick += 5;
                        else if (winding[r1] == concave &&
                                 winding[r2] == convex &&
                                 winding[r3] == concave)
                            nRingClick++;
                        break;
                    case 4:
                        r1 = (ringAttach.get(0) + i) % numAtoms;
                        r2 = (ringAttach.get(1) + i) % numAtoms;
                        r3 = (ringAttach.get(2) + i) % numAtoms;
                        r4 = (ringAttach.get(3) + i) % numAtoms;
                        if (winding[r1] == convex &&
                            winding[r2] == concave &&
                            winding[r3] == concave &&
                            winding[r4] == convex)
                            nRingClick++;
                        else if (winding[r1] == concave &&
                                 winding[r2] == convex &&
                                 winding[r3] == convex &&
                                 winding[r4] == concave)
                            nRingClick++;
                        break;
                }
            }

            // score hetero atoms in concave positions
            int nConcaveHetero = 0;
            for (int heteroIdx : heteroIdxs) {
                int k = (heteroIdx + i) % numAtoms;
                if (winding[k] == concave)
                    nConcaveHetero++;
            }

            int nCorrectStereo   = 0;
            int nIncorrectStereo = 0;
            for (IStereoElement se : macrocycle.stereoElements()) {
                if (se.getConfigClass() == IStereoElement.CisTrans) {
                    IBond bond = (IBond) se.getFocus();
                    IAtom beg  = bond.getBegin();
                    IAtom end  = bond.getEnd();
                    int cfg;
                    if (winding[(macrocycle.indexOf(beg) + i) % numAtoms] ==
                        winding[(macrocycle.indexOf(end) + i) % numAtoms]) {
                        cfg = IStereoElement.TOGETHER;
                    } else {
                        cfg = IStereoElement.OPPOSITE;
                    }
                    if (cfg == se.getConfigOrder()) {
                        nCorrectStereo++;
                    } else {
                        nIncorrectStereo++;
                    }
                }
            }
            MacroScore score = new MacroScore(i,
                                              nConcaveHetero,
                                              nCorrectStereo,
                                              nRingClick);
            if (score.compareTo(best) < 0) {
                best = score;
            }
        }

        return best;
    }
1138899
public IAtomContainer fixAromaticBondOrders(IAtomContainer atomContainer) throws CDKException {

        // preset all bond orders to single
        for (IBond bond : atomContainer.bonds()) {
            if (bond.isAromatic() && bond.getOrder() == IBond.Order.UNSET)
                bond.setOrder(IBond.Order.SINGLE);
        }

        // OK, we take advantage here from the fact that this class does not take
        // into account rings larger than 7 atoms. See fixAromaticBondOrders().
        IRingSet rs = allRingsFinder.findAllRings(atomContainer, 7);
        storeRingSystem(atomContainer, rs);

        IRingSet ringSet;

        // TODO remove rings with nonsp2 carbons(?) and rings larger than 7 atoms
        ringSet = removeExtraRings(atomContainer);

        if (ringSet == null) throw new CDKException("failure in AllRingsFinder.findAllRings");

        List<List<List<String>>> MasterList = new ArrayList<List<List<String>>>();

        //this.counter=0;// counter which keeps track of all current possibilities for placing double bonds

        this.FixPyridineNOxides(atomContainer, ringSet);

        for (int i = 0; i <= ringSet.getAtomContainerCount() - 1; i++) {

            IRing ring = (IRing) ringSet.getAtomContainer(i);

            // only takes into account rings up to 7 atoms... if that changes,
            // make sure to update the findAllRings() calls too!
            if (ring.getAtomCount() == 5) {
                fiveMemberedRingPossibilities(atomContainer, ring, MasterList);
            } else if (ring.getAtomCount() == 6) {
                sixMemberedRingPossibilities(atomContainer, ring, MasterList);
            } else if (ring.getAtomCount() == 7) {
                sevenMemberedRingPossibilities(atomContainer, ring, MasterList);
                //TODO- add code for all 7 membered aromatic ring possibilities not just 3 bonds
            } else {
                //TODO: what about other rings systems?
                logger.debug("Found ring of size: " + ring.getAtomCount());
            }
        }

        IAtomContainerSet som = atomContainer.getBuilder().newInstance(IAtomContainerSet.class);

        //		int number=1; // total number of possibilities
        //
        //		for (int ii=0;ii<=MasterList.size()-1;ii++) {
        //		ArrayList ringlist=(ArrayList)MasterList.get(ii);
        //		number*=ringlist.size();
        //		}
        //		logger.debug("number= "+number);

        int[] choices;

        //if (number> 1000000) return null;

        choices = new int[MasterList.size()];

        if (MasterList.size() > 0) {
            IAtomContainer iAtomContainer = loop(System.currentTimeMillis(), atomContainer, 0, MasterList, choices, som);
            if (iAtomContainer != null) return iAtomContainer;
        }

        int mincount = 99999999;

        int best = -1; // one with minimum number of bad atoms

        // minimize number of potentially bad nitrogens among AtomContainers in the set

        for (int i = 0; i <= som.getAtomContainerCount() - 1; i++) {

            IAtomContainer mol = som.getAtomContainer(i);

            ringSet = removeExtraRings(mol);

            if (ringSet == null) continue;

            int count = getBadCount(mol, ringSet);

            //logger.debug(i + "\t" + count);

            if (count < mincount) {
                mincount = count;
                best = i;
            }

        }

        if (som.getAtomContainerCount() > 0) return som.getAtomContainer(best);
        return atomContainer;
    }
106977
public static final int getNrGroups(Structure s) {
		int nrGroups = 0;

		List<Chain> chains = s.getChains(0);
		for (Chain c : chains) {
			nrGroups += c.getAtomLength();
		}
		return nrGroups;
	}
526239
private IRing prepareRing(List vec, IAtomContainer mol) {
        // add the atoms in vec to the new ring
        int atomCount = vec.size();
        IRing ring = mol.getBuilder().newInstance(IRing.class, atomCount);
        IAtom[] atoms = new IAtom[atomCount];
        vec.toArray(atoms);
        ring.setAtoms(atoms);
        // add the bonds in mol to the new ring
        try {
            IBond b;
            for (int i = 0; i < atomCount - 1; i++) {
                b = mol.getBond(atoms[i], atoms[i + 1]);
                if (b != null) {
                    ring.addBond(b);
                } else {
                    logger.error("This should not happen.");
                }
            }
            b = mol.getBond(atoms[0], atoms[atomCount - 1]);
            if (b != null) {
                ring.addBond(b);
            } else {
                logger.error("This should not happen either.");
            }
        } catch (Exception exc) {
            logger.debug(exc);
        }
        logger.debug("found Ring  ", ring);
        return ring;
    }
325099
public static IAtomContainerSet getAllMolecules(IReactionSet set) {
        IAtomContainerSet moleculeSet = set.getBuilder().newInstance(IAtomContainerSet.class);
        for (IReaction reaction : set.reactions()) {
            IAtomContainerSet molecules = ReactionManipulator.getAllMolecules(reaction);
            for (IAtomContainer ac : molecules.atomContainers()) {
                boolean contain = false;
                for (IAtomContainer atomContainer : moleculeSet.atomContainers()) {
                    if (atomContainer.equals(ac)) {
                        contain = true;
                        break;
                    }
                }
                if (!contain) moleculeSet.addAtomContainer(ac);

            }
        }
        return moleculeSet;
    }
441943
List<AtomPair> findCongestedPairs() {

        List<AtomPair> pairs = new ArrayList<>();

        // only add a single pair between each ring system, otherwise we
        // may have many pairs that are actually all part of the same
        // congestion
        Set<IntTuple> ringpairs = new HashSet<>();

        // score at which to check for crossing bonds
        final double maybeCrossed = 1.0 / (2 * 2);

        final int numAtoms = mol.getAtomCount();
        for (int u = 0; u < numAtoms; u++) {
            for (int v = u + 1; v < numAtoms; v++) {
                double contribution = congestion.contribution(u, v);
                // <0 = bonded
                if (contribution <= 0)
                    continue;

                // we don't modify ring bonds with the class to when the atoms
                // same ring systems we can't reduce the congestion
                if (ringsystems[u] > 0 && ringsystems[u] == ringsystems[v])
                    continue;

                // an un-bonded atom pair is congested if they're and with a certain distance
                // or any of their bonds are crossing
                if (contribution >= MIN_SCORE || contribution >= maybeCrossed && haveCrossingBonds(u, v)) {

                    int uWeight = mol.getAtom(u).getProperty(AtomPlacer.PRIORITY);
                    int vWeight = mol.getAtom(v).getProperty(AtomPlacer.PRIORITY);

                    int[] path = uWeight > vWeight ? apsp.from(u).pathTo(v)
                                                   : apsp.from(v).pathTo(u);

                    // something not right here if the len is < 3
                    int len = path.length;
                    if (len < 3) continue;

                    // build the seqAt and bndAt lists from shortest path
                    int[] seqAt = new int[len - 2];
                    IBond[] bndAt = new IBond[len - 1];
                    makeAtmBndQueues(path, seqAt, bndAt);

                    // we already know about this collision between these ring systems
                    // so dont add the pair
                    if (ringsystems[u] > 0 && ringsystems[v] > 0 &&
                            !ringpairs.add(new IntTuple(ringsystems[u], ringsystems[v])))
                        continue;

                    // add to pairs to overlap
                    pairs.add(new AtomPair(u, v, seqAt, bndAt));
                }
            }
        }

        // sort the pairs to attempt consistent overlap resolution (order independent)
        Collections.sort(pairs, new Comparator<AtomPair>() {
            @Override
            public int compare(AtomPair a, AtomPair b) {
                int a1 = atoms[a.fst].getProperty(AtomPlacer.PRIORITY);
                int a2 = atoms[a.snd].getProperty(AtomPlacer.PRIORITY);
                int b1 = atoms[b.fst].getProperty(AtomPlacer.PRIORITY);
                int b2 = atoms[b.snd].getProperty(AtomPlacer.PRIORITY);
                int amin, amax;
                int bmin, bmax;
                if (a1 < a2) {
                    amin = a1;
                    amax = a2;
                }
                else {
                    amin = a2;
                    amax = a1;
                }
                if (b1 < b2) {
                    bmin = a1;
                    bmax = a2;
                }
                else {
                    bmin = a2;
                    bmax = a1;
                }
                int cmp = Integer.compare(amin, bmin);
                if (cmp != 0) return cmp;
                return Integer.compare(amax, bmax);
            }
        });

        return pairs;
    }
954428
public Set<String> getChains() {
		Set<String> chains = new HashSet<String>();
		List<ResidueRange> rrs = ResidueRange.parseMultiple(getRanges());
		for (ResidueRange rr : rrs) chains.add(rr.getChainName());
		return chains;
	}

	@Override
	public String getIdentifier() {
		return getScopId();
	}

	public List<ResidueRange> getResidueRanges() {
		return ResidueRange.parseMultiple(ranges);
	}

	@Override
	public SubstructureIdentifier toCanonical() {
		return new SubstructureIdentifier(getPdbId(), ResidueRange.parseMultiple(getRanges()));
	}

	@Override
	public Structure reduce(Structure input) throws StructureException {
		return toCanonical().reduce(input);
	}

	@Override
	public Structure loadStructure(AtomCache cache) throws StructureException,
	IOException {
		return cache.getStructureForPdbId(pdbId);
	}

}
796569
private static IRing toRing(IAtomContainer container, int[] cycle, EdgeToBondMap bondMap) {

        IAtom[] atoms = new IAtom[cycle.length - 1];
        IBond[] bonds = new IBond[cycle.length - 1];

        for (int i = 1; i < cycle.length; i++) {
            int v = cycle[i];
            int u = cycle[i - 1];
            atoms[i - 1] = container.getAtom(u);
            bonds[i - 1] = getBond(container, bondMap, u, v);
        }

        IChemObjectBuilder builder = container.getBuilder();
        IAtomContainer ring = builder.newInstance(IAtomContainer.class, 0, 0, 0, 0);
        ring.setAtoms(atoms);
        ring.setBonds(bonds);

        return builder.newInstance(IRing.class, ring);
    }
1121500
public static int getBondCount(IRingSet set) {
        int count = 0;
        for (IAtomContainer atomContainer : set.atomContainers()) {
            count += atomContainer.getBondCount();
        }
        return count;
    }
211333
def ring_is_planar(ring, r_atoms):
    """"""
    normals = []
    for a in r_atoms:
        adj = pybel.ob.OBAtomAtomIter(a.OBAtom)
        # Check for neighboring atoms in the ring
        n_coords = [pybel.Atom(neigh).coords for neigh in adj if ring.IsMember(neigh)]
        vec1, vec2 = vector(a.coords, n_coords[0]), vector(a.coords, n_coords[1])
        normals.append(np.cross(vec1, vec2))
    # Given all normals of ring atoms and their neighbors, the angle between any has to be 5.0 deg or less
    for n1, n2 in itertools.product(normals, repeat=2):
        arom_angle = vecangle(n1, n2)
        if all([arom_angle > config.AROMATIC_PLANARITY, arom_angle < 180.0 - config.AROMATIC_PLANARITY]):
            return False
    return True
313129
boolean completePartiallyPlacedRing(IRingSet rset, IRing ring, double bondLength) {
        if (ring.getFlag(CDKConstants.ISPLACED))
            return true;
        IRing partiallyPlacedRing = molecule.getBuilder().newInstance(IRing.class);
        for (IAtom atom : ring.atoms())
            if (atom.getPoint2d() != null)
                atom.setFlag(CDKConstants.ISPLACED, true);
        AtomPlacer.copyPlaced(partiallyPlacedRing, ring);

        if (partiallyPlacedRing.getAtomCount() > 1 &&
            partiallyPlacedRing.getAtomCount() < ring.getAtomCount()) {
            placeConnectedRings(rset, partiallyPlacedRing, RingPlacer.FUSED, bondLength);
            placeConnectedRings(rset, partiallyPlacedRing, RingPlacer.BRIDGED, bondLength);
            placeConnectedRings(rset, partiallyPlacedRing, RingPlacer.SPIRO, bondLength);
            ring.setFlag(CDKConstants.ISPLACED, true);
            return true;
        } else {
            return false;
        }
    }
1348596
private IRing toRing(IAtomContainer container, EdgeToBondMap edges, int[] cycle) {
        IRing ring = container.getBuilder().newInstance(IRing.class, 0);

        int len = cycle.length - 1;

        IAtom[] atoms = new IAtom[len];
        IBond[] bonds = new IBond[len];

        for (int i = 0; i < len; i++) {
            atoms[i] = container.getAtom(cycle[i]);
            bonds[i] = edges.get(cycle[i], cycle[i + 1]);
            atoms[i].setFlag(CDKConstants.ISINRING, true);
        }

        ring.setAtoms(atoms);
        ring.setBonds(bonds);

        return ring;
    }
1364756
@Override
    public Order getMaximumBondOrder(IAtom atom) {
        IBond.Order max = IBond.Order.SINGLE;
        for (int i = 0; i < bondCount; i++) {
            if (bonds[i].contains(atom) && bonds[i].getOrder().ordinal() > max.ordinal()) {
                max = bonds[i].getOrder();
            }
        }
        return max;
    }
479525
private IBond checkEdges(IRing ring, IAtomContainer molecule) {
        IRing r1, r2;
        IRingSet ringSet = ring.getBuilder().newInstance(IRingSet.class);
        IBond bond;
        int minMaxSize = Integer.MAX_VALUE;
        int minMax = 0;
        logger.debug("Molecule: " + molecule);
        Iterator<IBond> bonds = ring.bonds().iterator();
        while (bonds.hasNext()) {
            bond = (IBond) bonds.next();
            molecule.removeElectronContainer(bond);
            r1 = getRing(bond.getBegin(), molecule);
            r2 = getRing(bond.getEnd(), molecule);
            logger.debug("checkEdges: " + bond);
            if (r1.getAtomCount() > r2.getAtomCount()) {
                ringSet.addAtomContainer(r1);
            } else {
                ringSet.addAtomContainer(r2);
            }
            molecule.addBond(bond);
        }
        for (int i = 0; i < ringSet.getAtomContainerCount(); i++) {
            if (((IRing) ringSet.getAtomContainer(i)).getBondCount() < minMaxSize) {
                minMaxSize = ((IRing) ringSet.getAtomContainer(i)).getBondCount();
                minMax = i;
            }
        }
        return (IBond) ring.getElectronContainer(minMax);
    }
242723
private IRingSet removeExtraRings(IAtomContainer m) {

        try {
            IRingSet rs = Cycles.sssr(m).toRingSet();

            //remove rings which dont have all aromatic atoms (according to hybridization set by lower case symbols in smiles):

            //logger.debug("numrings="+rs.size());

            iloop: for (int i = 0; i <= rs.getAtomContainerCount() - 1; i++) {

                IRing r = (IRing) rs.getAtomContainer(i);

                if (r.getAtomCount() > 7 || r.getAtomCount() < 5) {
                    rs.removeAtomContainer(i);
                    i--; // go back to first one
                    continue iloop;
                }

                //int NonSP2Count = 0;

                for (int j = 0; j <= r.getAtomCount() - 1; j++) {

                    //logger.debug(j+"\t"+r.getAtomAt(j).getSymbol()+"\t"+r.getAtomAt(j).getHybridization());

                    if (r.getAtom(j).getHybridization() == CDKConstants.UNSET
                            || !(r.getAtom(j).getHybridization() == Hybridization.SP2 || r.getAtom(j)
                                    .getHybridization() == Hybridization.PLANAR3)) {
                        rs.removeAtomContainer(i);
                        i--; // go back
                        continue iloop;
                        //                        NonSP2Count++;
                        //                        if (r.getAtom(j).getSymbol().equals("C")) {
                        //                            rs.removeAtomContainer(i);
                        //                            i--; // go back
                        //                            continue iloop;
                        //                        }
                    }
                }

                //                if (NonSP2Count > 1) {
                //                    rs.removeAtomContainer(i);
                //                    i--; // go back
                //                    continue iloop;
                //                }

            }
            return rs;

        } catch (Exception e) {
            return m.getBuilder().newInstance(IRingSet.class);
        }
    }