Internal method, MMFF primary charges. Tabulated (MMFFFORMCHG.PAR) and
variable (assigned in code).

@param mol molecule
@param adjList adjacency list representation
@param edgeMap edge to bond mapping
344324
void primaryCharges(IAtomContainer mol, int[][] adjList, GraphUtil.EdgeToBondMap edgeMap) {


        for (int v = 0; v < mol.getAtomCount(); v++) {
            IAtom atom = mol.getAtom(v);
            String symbType = atom.getAtomTypeName();
            BigDecimal fc = mmffParamSet.getFormalCharge(symbType);
            
            atom.setCharge(0d);

            if (fc != null) {
                atom.setCharge(fc.doubleValue());
            }
            // charge sharing between equivalent terminal oxygens
            else if (symbType.equals("O2S") || symbType.equals("O3S") || symbType.equals("O2P") || symbType.equals("O3P") || symbType.equals("O4P")) {

                // already handled
                if (atom.getCharge() != 0)
                    continue;

                // find the central atom (S or P)
                int focus = -1;
                for (int w : adjList[v]) {
                    int elem = mol.getAtom(w).getAtomicNumber();
                    if (elem == Elements.Sulfur.number() || elem == Elements.Phosphorus.number()) {
                        if (focus >= 0) {
                            focus = -2;
                            break;
                        }
                        focus = w;
                    }
                }

                // log - multiple or unfound focus
                if (focus < 0)
                    continue;

                // ensure [P+]-[O-] vs P=O are same by including the charge from
                // the focus
                double qSum = fCharge(mol.getAtom(focus));
                int nTerm = 0;

                for (int w : adjList[focus]) {
                    if (mol.getAtom(w).getAtomTypeName().equals(symbType)) {
                        qSum += fCharge(mol.getAtom(w));
                        nTerm++;
                    }
                }
                double qSplt = qSum / nTerm;

                for (int w : adjList[focus]) {
                    if (mol.getAtom(w).getAtomTypeName().equals(symbType)) {
                        atom.setCharge(qSplt);
                    }
                }

            }
            // charge sharing between nitrogen anions 
            else if (symbType.equals("N5M")) {

                if (atom.getCharge() != 0)
                    continue;

                Set<IAtom> eqiv = new HashSet<>();
                Set<Integer> visit = new HashSet<>();
                Deque<Integer> queue = new ArrayDeque<>();

                queue.add(v);

                while (!queue.isEmpty()) {
                    int w = queue.poll();
                    visit.add(w);

                    if (mol.getAtom(w).getAtomTypeName().equals("N5M"))
                        eqiv.add(mol.getAtom(w));

                    for (int u : adjList[w]) {
                        IBond bond = edgeMap.get(w, u);
                        if (bond.getProperty(MMFF_AROM) != null && !visit.contains(u)) {
                            queue.add(u);
                        }
                    }
                }

                double q = 0;
                for (IAtom eqivAtom : eqiv) {
                    q += fCharge(eqivAtom);
                }
                q /= eqiv.size();
                for (IAtom eqivAtom : eqiv) {
                    eqivAtom.setCharge(q);
                }
            }
        }
    }
333972
private final double[] getAprxBounds(IAtomContainer mol) {
        double maxX = -Double.MAX_VALUE;
        double maxY = -Double.MAX_VALUE;
        double minX = Double.MAX_VALUE;
        double minY = Double.MAX_VALUE;
        IAtom[] boundedAtoms = new IAtom[4];
        for (int i = 0; i < mol.getAtomCount(); i++) {
            IAtom atom = mol.getAtom(i);
            if (atom.getPoint2d() != null) {
                if (atom.getPoint2d().x < minX) {
                    minX = atom.getPoint2d().x;
                    boundedAtoms[0] = atom;
                }
                if (atom.getPoint2d().y < minY) {
                    minY = atom.getPoint2d().y;
                    boundedAtoms[1] = atom;
                }
                if (atom.getPoint2d().x > maxX) {
                    maxX = atom.getPoint2d().x;
                    boundedAtoms[2] = atom;
                }
                if (atom.getPoint2d().y > maxY) {
                    maxY = atom.getPoint2d().y;
                    boundedAtoms[3] = atom;
                }
            }
        }
        double[] minmax = new double[4];
        minmax[0] = minX;
        minmax[1] = minY;
        minmax[2] = maxX;
        minmax[3] = maxY;
        double minXAdjust = adjustForHydrogen(boundedAtoms[0], mol);
        double maxXAdjust = adjustForHydrogen(boundedAtoms[1], mol);
        if (minXAdjust < 0) minmax[0] += minXAdjust;
        if (maxXAdjust > 0) minmax[1] += maxXAdjust;
        return minmax;
    }
1125206
public static IAtomContainer project(List<CDKRMap> rMapList, IAtomContainer graph, int key) {
        IAtomContainer atomContainer = graph.getBuilder().newInstance(IAtomContainer.class);

        Map<IAtom, IAtom> table = new HashMap<IAtom, IAtom>();
        IAtom atom1;
        IAtom atom2;
        IAtom atom;
        IBond bond;

        for (Iterator<CDKRMap> i = rMapList.iterator(); i.hasNext();) {
            CDKRMap rMap = i.next();
            if (key == CDKMCS.ID1) {
                bond = graph.getBond(rMap.getId1());
            } else {
                bond = graph.getBond(rMap.getId2());
            }

            atom = bond.getBegin();
            atom1 = table.get(atom);

            if (atom1 == null) {
                try {
                    atom1 = (IAtom) atom.clone();
                } catch (CloneNotSupportedException e) {
                    e.printStackTrace();
                }
                atomContainer.addAtom(atom1);
                table.put(atom, atom1);
            }

            atom = bond.getEnd();
            atom2 = table.get(atom);

            if (atom2 == null) {
                try {
                    atom2 = (IAtom) atom.clone();
                } catch (CloneNotSupportedException e) {
                    e.printStackTrace();
                }
                atomContainer.addAtom(atom2);
                table.put(atom, atom2);
            }
            IBond newBond = graph.getBuilder().newInstance(IBond.class, atom1, atom2, bond.getOrder());
            newBond.setFlag(CDKConstants.ISAROMATIC, bond.getFlag(CDKConstants.ISAROMATIC));
            atomContainer.addBond(newBond);
        }
        return atomContainer;
    }
394538
private static int countAlignedBonds(IAtomContainer mol) {
        final double ref = Math.toRadians(30);
        final double diff = Math.toRadians(1);
        int count = 0;
        for (IBond bond : mol.bonds()) {
            Point2d beg = bond.getBegin().getPoint2d();
            Point2d end = bond.getEnd().getPoint2d();
            if (beg.x > end.x) {
                Point2d tmp = beg;
                beg = end;
                end = tmp;
            }
            Vector2d vec = new Vector2d(end.x - beg.x, end.y - beg.y);
            double angle = Math.atan2(vec.y, vec.x);

            if (Math.abs(angle) - ref < diff) {
                count++;
            }
        }
        return count;
    }
104383
private void addDoubleBondStereochemistry(Graph g, IAtomContainer ac) {

        for (final Edge e : g.edges()) {

            if (e.bond() != Bond.DOUBLE) continue;

            int u = e.either();
            int v = e.other(u);

            // find a directional bond for either end
            Edge first  = null;
            Edge second = null;

            // if either atom is not incident to a directional label there
            // is no configuration
            if ((first = findDirectionalEdge(g, u)) != null) {
                if ((second = findDirectionalEdge(g, v)) != null) {

                    // if the directions (relative to the double bond) are the
                    // same then they are on the same side - otherwise they
                    // are opposite
                    Conformation conformation = first.bond(u) == second.bond(v) ?
                                                Conformation.TOGETHER : Conformation.OPPOSITE;

                    // get the stereo bond and build up the ligands for the
                    // stereo-element - linear search could be improved with
                    // map or API change to double bond element
                    IBond db = ac.getBond(ac.getAtom(u), ac.getAtom(v));

                    IBond[] ligands = new IBond[]{
                        ac.getBond(ac.getAtom(u), ac.getAtom(first.other(u))),
                        ac.getBond(ac.getAtom(v), ac.getAtom(second.other(v)))};

                    ac.addStereoElement(new DoubleBondStereochemistry(db, ligands, conformation));
                } else if (g.degree(v) == 2) {
                    List<Edge> edges = new ArrayList<>();
                    edges.add(e);
                    Edge f = findCumulatedEdge(g, v, e);
                    while (f != null) {
                        edges.add(f);
                        v = f.other(v);
                        f = findCumulatedEdge(g, v, f);
                    }
                    // only odd number of cumulated bonds here, otherwise is
                    // extended tetrahedral
                    if ((edges.size() & 0x1) == 0)
                        continue;
                    second = findDirectionalEdge(g, v);
                    if (second != null) {
                        int   cfg        = first.bond(u) == second.bond(v)
                                           ? IStereoElement.TOGETHER
                                           : IStereoElement.OPPOSITE;
                        Edge  middleEdge = edges.get(edges.size()/2);
                        IBond middleBond = ac.getBond(ac.getAtom(middleEdge.either()),
                                                      ac.getAtom(middleEdge.other(middleEdge.either())));
                        IBond[] ligands = new IBond[]{
                            ac.getBond(ac.getAtom(u), ac.getAtom(first.other(u))),
                            ac.getBond(ac.getAtom(v), ac.getAtom(second.other(v)))};

                        ac.addStereoElement(new ExtendedCisTrans(middleBond, ligands, cfg));
                    }
                }
            }
            // extension F[C@]=[C@@]F
            else {
                Configuration uConf = g.configurationOf(u);
                Configuration vConf = g.configurationOf(v);
                if (uConf.type() == Configuration.Type.DoubleBond &&
                    vConf.type() == Configuration.Type.DoubleBond) {

                    int[] nbrs = new int[6];
                    int[] uNbrs = g.neighbors(u);
                    int[] vNbrs = g.neighbors(v);

                    if (uNbrs.length < 2 || uNbrs.length > 3)
                        continue;
                    if (vNbrs.length < 2 || vNbrs.length > 3)
                        continue;

                    int idx   = 0;
                    System.arraycopy(uNbrs, 0, nbrs, idx, uNbrs.length);
                    idx += uNbrs.length;
                    if (uNbrs.length == 2) nbrs[idx++] = u;
                    System.arraycopy(vNbrs, 0, nbrs, idx, vNbrs.length);
                    idx += vNbrs.length;
                    if (vNbrs.length == 2) nbrs[idx] = v;
                    Arrays.sort(nbrs, 0, 3);
                    Arrays.sort(nbrs, 3, 6);

                    int vPos = Arrays.binarySearch(nbrs, 0, 3, v);
                    int uPos = Arrays.binarySearch(nbrs, 3, 6, u);

                    int uhi = 0, ulo = 0;
                    int vhi = 0, vlo = 0;

                    uhi = nbrs[(vPos + 1) % 3];
                    ulo = nbrs[(vPos + 2) % 3];
                    vhi = nbrs[3 + ((uPos + 1) % 3)];
                    vlo = nbrs[3 + ((uPos + 2) % 3)];

                    if (uConf.shorthand() == Configuration.CLOCKWISE) {
                        int tmp = uhi;
                        uhi = ulo;
                        ulo = tmp;
                    }
                    if (vConf.shorthand() == Configuration.ANTI_CLOCKWISE) {
                        int tmp = vhi;
                        vhi = vlo;
                        vlo = tmp;
                    }

                    DoubleBondStereochemistry.Conformation conf = null;
                    IBond[] bonds = new IBond[2];

                    if (uhi != u) {
                        bonds[0] = ac.getBond(ac.getAtom(u), ac.getAtom(uhi));
                        if (vhi != v) {
                            // System.err.println(uhi + "\\=/" + vhi);
                            conf = Conformation.TOGETHER;
                            bonds[1] = ac.getBond(ac.getAtom(v), ac.getAtom(vhi));
                        } else if (vlo != v) {
                            // System.err.println(uhi + "\\=\\" + vlo);
                            conf = Conformation.OPPOSITE;
                            bonds[1] = ac.getBond(ac.getAtom(v), ac.getAtom(vlo));
                        }
                    } else if (ulo != u) {
                        bonds[0] = ac.getBond(ac.getAtom(u), ac.getAtom(ulo));
                        if (vhi != v) {
                            // System.err.println(ulo + "/=/" + vhi);
                            conf = Conformation.OPPOSITE;
                            bonds[1] = ac.getBond(ac.getAtom(v), ac.getAtom(vhi));
                        } else if (vlo != v) {
                            // System.err.println(ulo + "/=\\" + vlo);
                            conf = Conformation.TOGETHER;
                            bonds[1] = ac.getBond(ac.getAtom(v), ac.getAtom(vlo));
                        }
                    }

                    ac.addStereoElement(new DoubleBondStereochemistry(ac.getBond(ac.getAtom(u), ac.getAtom(v)),
                                                                      bonds,
                                                                      conf));
                }
            }
        }
    }
1290570
private double[] calculateDistanceBetweenAtomAndBond(IAtom proton, IBond theBond) {
        Point3d middlePoint = theBond.get3DCenter();
        Point3d protonPoint = proton.getPoint3d();
        double[] values = new double[4];
        values[0] = middlePoint.distance(protonPoint);
        values[1] = middlePoint.x;
        values[2] = middlePoint.y;
        values[3] = middlePoint.z;
        return values;
    }
288114
def add_bond(self, key1, key2, bond):
        """"""
        self.graph.add_edge(key1, key2, bond=bond)
241380
private void recordUnidentifiableAtomLinkages(List<ModifiedCompound> modComps,
			List<Group> ligands) {

		// first put identified linkages in a map for fast query
		Set<StructureAtomLinkage> identifiedLinkages = new HashSet<StructureAtomLinkage>();
		for (ModifiedCompound mc : modComps) {
			identifiedLinkages.addAll(mc.getAtomLinkages());
		}

		// record
		// cross link
		int nRes = residues.size();
		for (int i=0; i<nRes-1; i++) {
			Group group1 = residues.get(i);
			for (int j=i+1; j<nRes; j++) {
				Group group2 = residues.get(j);
				List<Atom[]> linkages = StructureUtil.findAtomLinkages(
						group1, group2, true, bondLengthTolerance);
				for (Atom[] atoms : linkages) {
					StructureAtomLinkage link = StructureUtil.getStructureAtomLinkage(atoms[0],
							true, atoms[1], true);
					unidentifiableAtomLinkages.add(link);
				}
			}
		}

		// attachment
		int nLig = ligands.size();
		for (int i=0; i<nRes; i++) {
			Group group1 = residues.get(i);
			for (int j=0; j<nLig; j++) {
				Group group2 = ligands.get(j);
				if (group1.equals(group2)) { // overlap between residues and ligands
					continue;
				}
				List<Atom[]> linkages = StructureUtil.findAtomLinkages(
						group1, group2, false, bondLengthTolerance);
				for (Atom[] atoms : linkages) {
					StructureAtomLinkage link = StructureUtil.getStructureAtomLinkage(atoms[0],
							true, atoms[1], false);
					unidentifiableAtomLinkages.add(link);
				}
			}
		}
	}
39093
void effectiveCharges(IAtomContainer mol, int[][] adjList) {
        double[] tmp = new double[mol.getAtomCount()];
        for (int v = 0; v < tmp.length; v++) {
            IAtom atom = mol.getAtom(v);
            int intType = mmffParamSet.intType(atom.getAtomTypeName());

            // unknown
            if (intType == 0) {
                continue;
            }

            int crd = mmffParamSet.getCrd(intType);
            BigDecimal fcAdj = mmffParamSet.getFormalChargeAdjustment(intType);


            double adjust = fcAdj.doubleValue();
            tmp[v] = atom.getCharge();

            // sharing when no formal charge adjustment - needed to match 
            // phosphate examples from paper V but documented?
            if (adjust == 0) {
                for (int w : adjList[v]) {
                    if (mol.getAtom(w).getCharge() < 0) {
                        tmp[v] += mol.getAtom(w).getCharge() / (2.0 * adjList[w].length);
                    }
                }   
            }

            // positive charge sharing - undocumented but inferred from validation suite
            if (atom.getAtomTypeName().equals("NM")) {
                for (int w : adjList[v]) {
                    if (mol.getAtom(w).getCharge() > 0) {
                        tmp[v] -= mol.getAtom(w).getCharge() / 2;
                    }
                }
            }

            // negative charge sharing
            if (adjust != 0) {
                double q = 0;
                for (int w : adjList[v]) {
                    q += mol.getAtom(w).getCharge();
                }
                tmp[v] = ((1 - (crd * adjust)) * tmp[v]) + (adjust * q);
            }
        }

        for (int v = 0; v < tmp.length; v++) {
            mol.getAtom(v).setCharge(tmp[v]);
        }
    }
945469
public AtlasEdge getEdgeForLabel(AtlasVertex vertex, String edgeLabel) {
        return getEdgeForLabel(vertex, edgeLabel, AtlasEdgeDirection.OUT);
    }
700660
@Override
    public void setScale(IChemModel chemModel) {
        double bondLength = AverageBondLengthCalculator.calculateAverageBondLength(chemModel);
        double scale = this.calculateScaleForBondLength(bondLength);

        // store the scale so that other components can access it
        this.rendererModel.getParameter(Scale.class).setValue(scale);
    }
15117
def setup_hydrocarbon_ff(graph):
    """"""
    # A) Define parameters.
    # the bond parameters:
    bond_params = {
        (6, 1): 310*kcalmol/angstrom**2,
        (6, 6): 220*kcalmol/angstrom**2,
    }
    # for every (a, b), also add (b, a)
    for key, val in list(bond_params.items()):
        if key[0] != key[1]:
            bond_params[(key[1], key[0])] = val
    # the bend parameters
    bend_params = {
        (1, 6, 1): 35*kcalmol/rad**2,
        (1, 6, 6): 30*kcalmol/rad**2,
        (6, 6, 6): 60*kcalmol/rad**2,
    }
    # for every (a, b, c), also add (c, b, a)
    for key, val in list(bend_params.items()):
        if key[0] != key[2]:
            bend_params[(key[2], key[1], key[0])] = val

    # B) detect all internal coordinates and corresponding energy terms.
    terms = []
    # bonds
    for i0, i1 in graph.edges:
        K = bond_params[(graph.numbers[i0], graph.numbers[i1])]
        terms.append(BondStretchTerm(K, i0, i1))
    # bends (see b_bending_angles.py for the explanation)
    for i1 in range(graph.num_vertices):
        n = list(graph.neighbors[i1])
        for index, i0 in enumerate(n):
            for i2 in n[:index]:
                K = bend_params[(graph.numbers[i0], graph.numbers[i1], graph.numbers[i2])]
                terms.append(BendAngleTerm(K, i0, i1, i2))

    # C) Create and return the force field
    return ForceField(terms)
985556
static public SimpleGraph getMoleculeGraph(IAtomContainer molecule) {
        SimpleGraph graph = new SimpleGraph();
        for (int i = 0; i < molecule.getAtomCount(); i++) {
            IAtom atom = molecule.getAtom(i);
            graph.addVertex(atom);
        }

        for (int i = 0; i < molecule.getBondCount(); i++) {
            IBond bond = molecule.getBond(i);

            /*
             * int order = (int) bond.getOrder(); for (int j=0; j<order; j++) {
             * graph.addEdge(bond.getAtoms()[0], bond.getAtoms()[1]); }
             */
            graph.addEdge(bond.getBegin(), bond.getEnd());
        }
        return graph;
    }
1293477
function FCGeneralEdgeView() {
        type.EdgeView.apply(this, arguments);
        this.tailEndStyle = Core.ES_FLAT;
        this.headEndStyle = Core.ES_SOLID_ARROW;
        this.lineMode = Core.LM_SOLID;

        /** @member {EdgeLabelView} */
        this.nameLabel = new type.EdgeLabelView();
        this.nameLabel.hostEdge = this;
        this.nameLabel.edgePosition = Core.EP_MIDDLE;
        this.nameLabel.distance = 15;
        this.nameLabel.alpha = Math.PI / 2;
        this.addSubView(this.nameLabel);
    }
185542
Collection<Point2d[]> getCoordinates(IAtomContainer mol) {
        try {
            // create the library key to lookup an entry, we also store
            // the canonical out ordering
            int n = mol.getAtomCount();
            int[] ordering = new int[n];
            String smiles = cansmi(mol, ordering);

            final Collection<Point2d[]> coordSet = templateMap.get(smiles);
            final List<Point2d[]> orderedCoordSet = new ArrayList<>(coordSet.size());

            for (Point2d[] coords : coordSet) {
                Point2d[] orderedCoords = new Point2d[coords.length];
                for (int i = 0; i < n; i++) {
                    orderedCoords[i] = new Point2d(coords[ordering[i]]);
                }
                orderedCoordSet.add(orderedCoords);
            }
            return Collections.unmodifiableList(orderedCoordSet);
        } catch (CDKException e) {
            return Collections.emptyList();
        }
    }
535406
private static IAtom getOtherAtom(IAtomContainer mol, IAtom atom, IAtom other) {
        List<IBond> bonds = mol.getConnectedBondsList(atom);
        if (bonds.size() != 2)
            return null;
        if (bonds.get(0).contains(other))
            return bonds.get(1).getOrder() == IBond.Order.DOUBLE
                   ? bonds.get(1).getOther(atom) : null;
        return bonds.get(0).getOrder() == IBond.Order.DOUBLE
                    ? bonds.get(0).getOther(atom) : null;
    }
1106890
private void interiorLineExteriorLine_(int half_edge, int id_a, int id_b,
			int predicate) {
		if (m_matrix[predicate] == 1)
			return;

		int parentage = m_topo_graph.getHalfEdgeParentage(half_edge);

		if ((parentage & id_a) != 0 && (parentage & id_b) == 0)
			m_matrix[predicate] = 1;
	}