Assign a Kekulé representation to the aromatic systems of a compound.

@param ac structural representation
@throws CDKException a Kekulé form could not be assigned
186390
public static void kekulize(final IAtomContainer ac) throws CDKException {

        // storage of pairs of atoms that have pi-bonded
        final Matching matching = Matching.withCapacity(ac.getAtomCount());

        // exract data structures for efficient access
        final IAtom[] atoms = AtomContainerManipulator.getAtomArray(ac);
        final EdgeToBondMap bonds = EdgeToBondMap.withSpaceFor(ac);
        final int[][] graph = GraphUtil.toAdjList(ac, bonds);

        // determine which atoms are available to have a pi bond placed
        final BitSet available = available(graph, atoms, bonds);

        // attempt to find a perfect matching such that a pi bond is placed
        // next to each available atom. if not found the solution is ambiguous
        if (!matching.perfect(graph, available))
            throw new CDKException("Cannot assign Kekulé structure without randomly creating radicals.");

        // propegate bond order information from the matching
        for (final IBond bond : ac.bonds()) {
            if (bond.getOrder() == UNSET && bond.isAromatic()) bond.setOrder(SINGLE);
        }
        for (int v = available.nextSetBit(0); v >= 0; v = available.nextSetBit(v + 1)) {
            final int w = matching.other(v);
            final IBond bond = bonds.get(v, w);

            // sanity check, something wrong if this happens
            if (bond.getOrder().numeric() > 1)
                throw new CDKException(
                        "Cannot assign Kekulé structure, non-sigma bond order has already been assigned?");

            bond.setOrder(IBond.Order.DOUBLE);
            available.clear(w);
        }
    }
362415
public void saturate(IAtom atom, IAtomContainer ac) throws CDKException {
        logger.info("Saturating atom by adjusting lone pair electrons...");
        IAtomType atomType = factory.getAtomType(atom.getAtomTypeName());
        int lpCount = (Integer) atomType.getProperty(CDKConstants.LONE_PAIR_COUNT);
        int missingLPs = lpCount - ac.getConnectedLonePairsCount(atom);

        for (int j = 0; j < missingLPs; j++) {
            ILonePair lp = atom.getBuilder().newInstance(ILonePair.class, atom);
            ac.addLonePair(lp);
        }
    }
858858
private static boolean isHueckelValid(IAtomContainer singleRing) throws CDKException {
        int electronCount = 0;
        for (IAtom ringAtom : singleRing.atoms()) {
            if (ringAtom.getHybridization() != CDKConstants.UNSET && (ringAtom.getHybridization() == Hybridization.SP2)
                    || ringAtom.getHybridization() == Hybridization.PLANAR3) {
                // for example, a carbon
                // note: the double bond is in the ring, that has been tested earlier
                // FIXME: this does assume bond orders to be resolved too, when detecting
                // sprouting double bonds
                if ("N.planar3".equals(ringAtom.getAtomTypeName())) {
                    electronCount += 2;
                } else if ("N.minus.planar3".equals(ringAtom.getAtomTypeName())) {
                    electronCount += 2;
                } else if ("N.amide".equals(ringAtom.getAtomTypeName())) {
                    electronCount += 2;
                } else if ("S.2".equals(ringAtom.getAtomTypeName())) {
                    electronCount += 2;
                } else if ("S.planar3".equals(ringAtom.getAtomTypeName())) {
                    electronCount += 2;
                } else if ("C.minus.planar".equals(ringAtom.getAtomTypeName())) {
                    electronCount += 2;
                } else if ("O.planar3".equals(ringAtom.getAtomTypeName())) {
                    electronCount += 2;
                } else if ("N.sp2.3".equals(ringAtom.getAtomTypeName())) {
                    electronCount += 1;
                } else {
                    if (factory == null) {
                        factory = AtomTypeFactory.getInstance("org/openscience/cdk/dict/data/cdk-atom-types.owl",
                                ringAtom.getBuilder());
                    }
                    IAtomType type = factory.getAtomType(ringAtom.getAtomTypeName());
                    Object property = type.getProperty(CDKConstants.PI_BOND_COUNT);
                    if (property != null && property instanceof Integer) {
                        electronCount += ((Integer) property).intValue();
                    }
                }
            } else if (ringAtom.getHybridization() != null && ringAtom.getHybridization() == Hybridization.SP3
                    && getLonePairCount(ringAtom) > 0) {
                // for example, a nitrogen or oxygen
                electronCount += 2;
            }
        }
        return (electronCount % 4 == 2) && (electronCount > 2);
    }
435624
@Override
    public void setParameters(Object[] params) throws CDKException {
        if (params.length != 2) {
            throw new CDKException("RotatableBondsCount expects two parameters");
        }
        if (!(params[0] instanceof Boolean) || !(params[1] instanceof Boolean)) {
            throw new CDKException("The parameters must be of type Boolean");
        }
        // ok, all should be fine
        includeTerminals = (Boolean) params[0];
        excludeAmides = (Boolean) params[1];
    }
844910
public static void removeAcidicOxygen(IAminoAcid acid) throws CDKException {
        if (acid.getCTerminus() == null) throw new CDKException("Cannot remove oxygen: C-terminus is not defined!");

        java.util.List<IBond> bonds = acid.getConnectedBondsList(acid.getCTerminus());
        // ok, look for the oxygen which is singly bonded
        for (IBond bond : bonds) {
            if (bond.getOrder() == Order.SINGLE) {
                for (int j = 0; j < bond.getAtomCount(); j++) {
                    if (bond.getAtom(j).getSymbol().equals("O")) {
                        // yes, we found a singly bonded oxygen!
                        acid.removeAtom(bond.getAtom(j));
                    }
                }
            }
        }
    }
108687
public static IAtom getAtomById(IAtomContainer ac, String id) throws CDKException {
        for (int i = 0; i < ac.getAtomCount(); i++) {
            if (ac.getAtom(i).getID() != null && ac.getAtom(i).getID().equals(id)) return ac.getAtom(i);
        }
        throw new CDKException("no suc atom");
    }
1063162
public boolean isSaturated(IAtom atom, IAtomContainer ac) throws CDKException {
        createAtomTypeFactory(ac.getBuilder());
        IAtomType atomType = factory.getAtomType(atom.getAtomTypeName());
        int lpCount = (Integer) atomType.getProperty(CDKConstants.LONE_PAIR_COUNT);
        int foundLPCount = ac.getConnectedLonePairsCount(atom);
        return foundLPCount >= lpCount;
    }
163805
public static void layout(@javax.annotation.Nonnull final Component c) {
    c.doLayout();
    if (c instanceof Container) {
      Arrays.stream(((Container) c).getComponents()).forEach(com.simiacryptus.util.Util::layout);
    }
  }
968440
private static IAtomContainer initiateIonization(IAtomContainer container, IAtom atom) throws CDKException {
        IReactionProcess reactionNBE = new ElectronImpactNBEReaction();

        IAtomContainerSet setOfReactants = container.getBuilder().newInstance(IAtomContainerSet.class);
        setOfReactants.addAtomContainer(container);

        atom.setFlag(CDKConstants.REACTIVE_CENTER, true);
        List<IParameterReact> paramList = new ArrayList<IParameterReact>();
        IParameterReact param = new SetReactionCenter();
        param.setParameter(Boolean.TRUE);
        paramList.add(param);
        reactionNBE.setParameterList(paramList);

        /* initiate */
        IReactionSet setOfReactions = reactionNBE.initiate(setOfReactants, null);
        atom.setFlag(CDKConstants.REACTIVE_CENTER, false);
        if (setOfReactions != null && setOfReactions.getReactionCount() == 1
                && setOfReactions.getReaction(0).getProducts().getAtomContainerCount() == 1)
            return setOfReactions.getReaction(0).getProducts().getAtomContainer(0);
        else
            return null;
    }
1306054
private void setAtomsToPlace(IAtomContainer ac) {
        for (int i = 0; i < ac.getAtomCount(); i++) {
            ac.getAtom(i).setFlag(CDKConstants.ISPLACED, true);
        }
    }
40418
private void setActiveCenters(IAtomContainer reactant) throws CDKException {
        if (AtomContainerManipulator.getTotalCharge(reactant) > 0) return;

        Iterator<IAtom> atoms = reactant.atoms().iterator();
        while (atoms.hasNext()) {
            IAtom atomi = atoms.next(); // Atom pos 1
            if ((atomi.getFormalCharge() == CDKConstants.UNSET ? 0 : atomi.getFormalCharge()) <= 0
                    && reactant.getConnectedLonePairsCount(atomi) > 0
                    && reactant.getConnectedSingleElectronsCount(atomi) == 0) {
                atomi.setFlag(CDKConstants.REACTIVE_CENTER, true);

            }
        }
    }
246668
private void setActiveCenters(IAtomContainer reactant) throws CDKException {
        Iterator<IBond> bonds = reactant.bonds().iterator();
        while (bonds.hasNext()) {
            IBond bondi = bonds.next();
            IAtom atom1 = bondi.getBegin();
            IAtom atom2 = bondi.getEnd();
            if (bondi.getOrder() == IBond.Order.SINGLE
                    && (atom1.getFormalCharge() == CDKConstants.UNSET ? 0 : atom1.getFormalCharge()) == 0
                    && (atom2.getFormalCharge() == CDKConstants.UNSET ? 0 : atom2.getFormalCharge()) == 0
                    && reactant.getConnectedSingleElectronsCount(atom1) == 0
                    && reactant.getConnectedSingleElectronsCount(atom2) == 0) {
                bondi.setFlag(CDKConstants.REACTIVE_CENTER, true);
                atom1.setFlag(CDKConstants.REACTIVE_CENTER, true);
                atom2.setFlag(CDKConstants.REACTIVE_CENTER, true);
            }
        }
    }
443849
@Override
    public void generateFragments(IAtomContainer atomContainer) throws CDKException {
        Set<Long> fragmentSet = new HashSet<Long>();
        frameMap.clear();
        ringMap.clear();
        run(atomContainer, fragmentSet);
    }
1314054
private IChemFile readChemFile(IChemFile cf) throws CDKException {
        // have to do stuff here
        try {
            String line = null;
            while ((line = input.readLine()) != null) {
                if (line.startsWith("INChI=") || line.startsWith("InChI=")) {
                    // ok, the fun starts
                    cf = cf.getBuilder().newInstance(IChemFile.class);
                    // ok, we need to parse things like:
                    // INChI=1.12Beta/C6H6/c1-2-4-6-5-3-1/h1-6H
                    final String INChI = line.substring(6);
                    StringTokenizer tokenizer = new StringTokenizer(INChI, "/");
                    // ok, we expect 4 tokens
                    tokenizer.nextToken(); // 1.12Beta not stored since never used
                    final String formula = tokenizer.nextToken(); // C6H6
                    String connections = null;
                    if (tokenizer.hasMoreTokens()) {
                        connections = tokenizer.nextToken().substring(1); // 1-2-4-6-5-3-1
                    }
                    //final String hydrogens = tokenizer.nextToken().substring(1); // 1-6H

                    IAtomContainer parsedContent = inchiTool.processFormula(
                            cf.getBuilder().newInstance(IAtomContainer.class), formula);
                    if (connections != null)
                        inchiTool.processConnections(connections, parsedContent, -1);

                    IAtomContainerSet moleculeSet = cf.getBuilder().newInstance(IAtomContainerSet.class);
                    moleculeSet.addAtomContainer(cf.getBuilder().newInstance(IAtomContainer.class, parsedContent));
                    IChemModel model = cf.getBuilder().newInstance(IChemModel.class);
                    model.setMoleculeSet(moleculeSet);
                    IChemSequence sequence = cf.getBuilder().newInstance(IChemSequence.class);
                    sequence.addChemModel(model);
                    cf.addChemSequence(sequence);
                }
            }
        } catch (IOException | IllegalArgumentException exception) {
            exception.printStackTrace();
            throw new CDKException("Error while reading INChI file: " + exception.getMessage(), exception);
        }
        return cf;
    }
81477
private void layoutMolecule(List ringSetMolecule, IAtomContainer molecule, AtomPlacer3D ap3d,
            AtomTetrahedralLigandPlacer3D atlp3d, AtomPlacer atomPlacer) throws CDKException, IOException,
            CloneNotSupportedException {
        //logger.debug("****** LAYOUT MOLECULE MAIN *******");
        IAtomContainer ac = null;
        int safetyCounter = 0;
        IAtom atom = null;
        //Place rest Chains/Atoms
        do {
            safetyCounter++;
            atom = ap3d.getNextPlacedHeavyAtomWithUnplacedRingNeighbour(molecule);
            if (atom != null) {
                //logger.debug("layout RingSystem...");
                IAtom unplacedAtom = ap3d.getUnplacedRingHeavyAtom(molecule, atom);
                IRingSet ringSetA = getRingSetOfAtom(ringSetMolecule, unplacedAtom);
                IAtomContainer ringSetAContainer = RingSetManipulator.getAllInOneContainer(ringSetA);
                templateHandler.mapTemplates(ringSetAContainer, ringSetAContainer.getAtomCount());

                if (checkAllRingAtomsHasCoordinates(ringSetAContainer)) {
                } else {
                    throw new IOException(
                            "RingAtomLayoutError: Not every ring atom is placed! Molecule cannot be layout.Sorry");
                }

                Point3d firstAtomOriginalCoord = unplacedAtom.getPoint3d();
                Point3d centerPlacedMolecule = ap3d.geometricCenterAllPlacedAtoms(molecule);

                setBranchAtom(molecule, unplacedAtom, atom, ap3d.getPlacedHeavyAtoms(molecule, atom), ap3d, atlp3d);
                layoutRingSystem(firstAtomOriginalCoord, unplacedAtom, ringSetA, centerPlacedMolecule, atom, ap3d);
                searchAndPlaceBranches(molecule, ringSetAContainer, ap3d, atlp3d, atomPlacer);
                //logger.debug("Ready layout Ring System");
                ringSetA = null;
                unplacedAtom = null;
                firstAtomOriginalCoord = null;
                centerPlacedMolecule = null;
            } else {
                //logger.debug("layout chains...");
                setAtomsToUnVisited(molecule);
                atom = ap3d.getNextPlacedHeavyAtomWithUnplacedAliphaticNeighbour(molecule);
                if (atom != null) {
                    ac = atom.getBuilder().newInstance(IAtomContainer.class);
                    ac.addAtom(atom);
                    searchAndPlaceBranches(molecule, ac, ap3d, atlp3d, atomPlacer);
                    ac = null;
                }
            }
        } while (!ap3d.allHeavyAtomsPlaced(molecule) || safetyCounter > molecule.getAtomCount());
    }
19471
private IAtomContainer connectAtoms(String inputInchi, IAtomContainer inputMolecule,
            Map<Integer, IAtom> inchiAtomsByPosition) throws CDKException {
        String inchi = inputInchi;
        inchi = inchi.substring(inchi.indexOf('/') + 1);
        inchi = inchi.substring(inchi.indexOf('/') + 1);
        String connections = inchi.substring(1, inchi.indexOf('/'));
        Pattern connectionPattern = Pattern.compile("(-|\\(|\\)|,|([0-9])*)");
        Matcher match = connectionPattern.matcher(connections);
        Stack<IAtom> atomStack = new Stack<IAtom>();
        IAtomContainer inchiMolGraph = inputMolecule.getBuilder().newInstance(IAtomContainer.class);
        boolean pop = false;
        boolean push = true;
        while (match.find()) {
            String group = match.group();
            push = true;
            if (!group.isEmpty()) {
                if (group.matches("[0-9]*")) {
                    IAtom atom = inchiAtomsByPosition.get(Integer.valueOf(group));
                    if (!inchiMolGraph.contains(atom)) inchiMolGraph.addAtom(atom);
                    IAtom prevAtom = null;
                    if (atomStack.size() != 0) {
                        if (pop) {
                            prevAtom = atomStack.pop();
                        } else {
                            prevAtom = atomStack.get(atomStack.size() - 1);
                        }
                        IBond bond = inputMolecule.getBuilder().newInstance(IBond.class, prevAtom, atom,
                                IBond.Order.SINGLE);
                        inchiMolGraph.addBond(bond);
                    }
                    if (push) {
                        atomStack.push(atom);
                    }
                } else if (group.equals("-")) {
                    pop = true;
                    push = true;
                } else if (group.equals(",")) {
                    atomStack.pop();
                    pop = false;
                    push = false;
                } else if (group.equals("(")) {
                    pop = false;
                    push = true;
                } else if (group.equals(")")) {
                    atomStack.pop();
                    pop = true;
                    push = true;
                } else {
                    throw new CDKException("Unexpected token " + group + " in connection table encountered.");
                }
            }
        }
        //put any unconnected atoms in the output as well
        for (IAtom at : inchiAtomsByPosition.values()) {
            if (!inchiMolGraph.contains(at)) inchiMolGraph.addAtom(at);
        }
        return inchiMolGraph;
    }
478276
@Override
    public void setParameters(Object[] params) throws CDKException {
        if (params.length > 1) {
            throw new CDKException("SigmaElectronegativityDescriptor only expects one parameter");
        }
        if (!(params[0] instanceof Integer)) {
            throw new CDKException("The parameter must be of type Integer");
        }
        if (params.length == 0) return;
        maxIterations = (Integer) params[0];
    }