PATTY [Bush et al. J. Inf. Comput. Sci 33 (1993) 756-762]
    TODO: not yet implemented

    1:cation 2:anion 3:donor 4:acceptor
    5:polar 6:hydrophobe 7:others
542466
def assign_type(mol, force_recalc=False):
    
    if "PATTY" in mol.descriptors and not force_recalc:
        return
    mol.require("Phys_charge")
    for i, atom in mol.atoms_iter():
        # default is 7 (others)
        nbrcnt = mol.neighbor_count(i)
        if atom.charge > 0 or atom.charge_phys > 0 or \
                atom.charge_conj > 0 and not atom.n_oxide:
            atom.type = 1  # cation
        elif atom.charge < 0 or atom.charge_phys < 0 or \
                atom.charge_conj < 0 and not atom.n_oxide:
            atom.type = 2  # anion
        elif atom.symbol == "N":
            if nbrcnt in (1, 2):
                if atom.pi == 2:
                    atom.type = 3  # donor
                elif atom.pi == 1:
                    atom.type = 4  # acceptor
        elif atom.symbol == "O":
            if nbrcnt == 1 and not atom.pi:
                atom.type = 5  # polar
            else:
                atom.type = 4  # acceptor
        elif atom.symbol in ("C", "Si", "S", "Se", "P", "As"):
            ewg = False
            for n, bond in mol.neighbors(i).items():
                natom = mol.atom(n)
                if natom.symbol in ("N", "O", "S") and atom.pi \
                        and not (natom.pi == 2 and mol.neighbor_count(n) == 3):
                    # the sp2 adjacent to neg (but not conj tert amine) is 7
                    ewg = True
                    break
            if not ewg:
                atom.type = 6  # hydrophobes
        elif atom.symbol in ("F", "Cl", "Br", "I") and nbrcnt == 1:
            atom.type = 6  # typical halogens are hydrophobic
    mol.descriptors.add("PATTY")
125307
private boolean familyHalogen(IAtom atom) {
        String symbol = atom.getSymbol();
        return symbol.equals("F") || symbol.equals("Cl") || symbol.equals("Br") || symbol.equals("I");
    }
680871
@SuppressWarnings("PMD.CyclomaticComplexity")
    // high complexity but clean
    static int contribution(int elem, int x, int v) {
        switch (elem) {
            case 6:
                if (x == 3 && v == 4) return 1; // pi bond *-C=*
                break;
            case 7:
                if (x == 2 && v == 3) return 1; // pi bond *-N=*
                if (x == 3 && v == 4) return 1; // pi bond *-[N+H}=*
                if (x == 3 && v == 3) return 2; // lone pair *-N-*
                if (x == 2 && v == 2) return 2; // lone pair *-[N-]-*
                break;
            case 8:
            case 16:
                if (x == 2 && v == 2) return 2; // lone pair *-S-* and *-O-*
                break;
        }
        return -1;
    }
1354257
private int getAromaticCarbonsCount(IAtomContainer ac, IAtom atom) {
        List<IAtom> neighbours = ac.getConnectedAtomsList(atom);
        int carocounter = 0;
        for (IAtom neighbour : neighbours) {
            if (neighbour.getSymbol().equals("C") && neighbour.getFlag(CDKConstants.ISAROMATIC)) {
                carocounter += 1;
            }
        }
        return carocounter;
    }
225334
function() {
        var tmp = [], //12
			src = [], //16
			dst = [], //16
			mat = this.toArray(),
			i = 0;

        for (i = 0; i < 4; i++) {
            var i4 = i << 2;
            src[i] = mat[i4];
            src[i + 4] = mat[i4 + 1];
            src[i + 8] = mat[i4 + 2];
            src[i + 12] = mat[i4 + 3];
        }

        // calculate pairs for first 8 elements (cofactors)
        tmp[0] = src[10] * src[15];
        tmp[1] = src[11] * src[14];
        tmp[2] = src[9] * src[15];
        tmp[3] = src[11] * src[13];
        tmp[4] = src[9] * src[14];
        tmp[5] = src[10] * src[13];
        tmp[6] = src[8] * src[15];
        tmp[7] = src[11] * src[12];
        tmp[8] = src[8] * src[14];
        tmp[9] = src[10] * src[12];
        tmp[10] = src[8] * src[13];
        tmp[11] = src[9] * src[12];

        // calculate first 8 elements (cofactors)
        var src0 = src[0],
			src1 = src[1],
			src2 = src[2],
			src3 = src[3],
			src4 = src[4],
			src5 = src[5],
			src6 = src[6],
			src7 = src[7];
		dst[0] = tmp[0] * src5 + tmp[3] * src6 + tmp[4] * src7;
		dst[0] -= tmp[1] * src5 + tmp[2] * src6 + tmp[5] * src7;
		dst[1] = tmp[1] * src4 + tmp[6] * src6 + tmp[9] * src7;
		dst[1] -= tmp[0] * src4 + tmp[7] * src6 + tmp[8] * src7;
		dst[2] = tmp[2] * src4 + tmp[7] * src5 + tmp[10] * src7;
		dst[2] -= tmp[3] * src4 + tmp[6] * src5 + tmp[11] * src7;
		dst[3] = tmp[5] * src4 + tmp[8] * src5 + tmp[11] * src6;
		dst[3] -= tmp[4] * src4 + tmp[9] * src5 + tmp[10] * src6;
		dst[4] = tmp[1] * src1 + tmp[2] * src2 + tmp[5] * src3;
		dst[4] -= tmp[0] * src1 + tmp[3] * src2 + tmp[4] * src3;
		dst[5] = tmp[0] * src0 + tmp[7] * src2 + tmp[8] * src3;
		dst[5] -= tmp[1] * src0 + tmp[6] * src2 + tmp[9] * src3;
		dst[6] = tmp[3] * src0 + tmp[6] * src1 + tmp[11] * src3;
		dst[6] -= tmp[2] * src0 + tmp[7] * src1 + tmp[10] * src3;
		dst[7] = tmp[4] * src0 + tmp[9] * src1 + tmp[10] * src2;
		dst[7] -= tmp[5] * src0 + tmp[8] * src1 + tmp[11] * src2;

        // calculate pairs for second 8 elements (cofactors)
		tmp[0] = src2 * src7;
		tmp[1] = src3 * src6;
		tmp[2] = src1 * src7;
		tmp[3] = src3 * src5;
		tmp[4] = src1 * src6;
		tmp[5] = src2 * src5;
		tmp[6] = src0 * src7;
		tmp[7] = src3 * src4;
		tmp[8] = src0 * src6;
		tmp[9] = src2 * src4;
		tmp[10] = src0 * src5;
		tmp[11] = src1 * src4;

        // calculate second 8 elements (cofactors)
		src0 = src[8];
		src1 = src[9];
		src2 = src[10];
		src3 = src[11];
		src4 = src[12];
		src5 = src[13];
		src6 = src[14];
		src7 = src[15];
		dst[8] = tmp[0] * src5 + tmp[3] * src6 + tmp[4] * src7;
		dst[8] -= tmp[1] * src5 + tmp[2] * src6 + tmp[5] * src7;
		dst[9] = tmp[1] * src4 + tmp[6] * src6 + tmp[9] * src7;
		dst[9] -= tmp[0] * src4 + tmp[7] * src6 + tmp[8] * src7;
		dst[10] = tmp[2] * src4 + tmp[7] * src5 + tmp[10] * src7;
		dst[10] -= tmp[3] * src4 + tmp[6] * src5 + tmp[11] * src7;
		dst[11] = tmp[5] * src4 + tmp[8] * src5 + tmp[11] * src6;
		dst[11] -= tmp[4] * src4 + tmp[9] * src5 + tmp[10] * src6;
		dst[12] = tmp[2] * src2 + tmp[5] * src3 + tmp[1] * src1;
		dst[12] -= tmp[4] * src3 + tmp[0] * src1 + tmp[3] * src2;
		dst[13] = tmp[8] * src3 + tmp[0] * src0 + tmp[7] * src2;
		dst[13] -= tmp[6] * src2 + tmp[9] * src3 + tmp[1] * src0;
		dst[14] = tmp[6] * src1 + tmp[11] * src3 + tmp[3] * src0;
		dst[14] -= tmp[10] * src3 + tmp[2] * src0 + tmp[7] * src1;
		dst[15] = tmp[10] * src2 + tmp[4] * src0 + tmp[9] * src1;
		dst[15] -= tmp[8] * src1 + tmp[11] * src2 + tmp[5] * src0;

		var det = 1.0 / (src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] * dst[3]);
		for (i = 0, k = 0; i < 4; i++) {
			var m = this.matrix[i];
			for (var j = 0; j < 4; j++) {
				m[j] = dst[k++] * det;
			}
		}
		return this;
    }
972305
@Override
    public DescriptorValue calculate(IAtomContainer atomContainer) {
        int hBondAcceptors = 0;

        IAtomContainer ac;
        try {
            ac = (IAtomContainer) atomContainer.clone();
        } catch (CloneNotSupportedException e) {
            return getDummyDescriptorValue(e);
        }

        // aromaticity is detected prior to descriptor calculation if the respective parameter is set to true

        if (checkAromaticity) {
            try {
                AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(ac);
                Aromaticity.cdkLegacy().apply(ac);
            } catch (CDKException e) {
                return getDummyDescriptorValue(e);
            }
        }

        //org.openscience.cdk.interfaces.IAtom[] atoms = ac.getAtoms();
        // labelled for loop to allow for labelled continue statements within the loop
        atomloop: for (IAtom atom : ac.atoms()) {
            // looking for suitable nitrogen atoms
            if (atom.getSymbol().equals("N") && atom.getFormalCharge() <= 0) {

                // excluding nitrogens that are adjacent to an oxygen
                List<IBond> bonds = ac.getConnectedBondsList(atom);
                int nPiBonds = 0;
                for (IBond bond : bonds) {
                    if (bond.getOther(atom).getSymbol().equals("O")) continue atomloop;
                    if (IBond.Order.DOUBLE.equals(bond.getOrder())) nPiBonds++;
                }

                // if the nitrogen is aromatic and there are no pi bonds then it's
                // lone pair cannot accept any hydrogen bonds
                if (atom.getFlag(CDKConstants.ISAROMATIC) && nPiBonds == 0) continue;

                hBondAcceptors++;
            }
            // looking for suitable oxygen atoms
            else if (atom.getSymbol().equals("O") && atom.getFormalCharge() <= 0) {
                //excluding oxygens that are adjacent to a nitrogen or to an aromatic carbon
                List<IBond> neighbours = ac.getConnectedBondsList(atom);
                for (IBond bond : neighbours) {
                    IAtom neighbor = bond.getOther(atom);
                    if (neighbor.getSymbol().equals("N") ||
                        (neighbor.getSymbol().equals("C") &&
                         neighbor.isAromatic() &&
                         bond.getOrder() != IBond.Order.DOUBLE))
                        continue atomloop;;
                }
                hBondAcceptors++;
            }
        }

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                hBondAcceptors), getDescriptorNames());
    }
87029
private void calculate(List<String> paths, IAtomContainer mol) {
        AllPairsShortestPaths apsp     = new AllPairsShortestPaths(mol);
        int                   numAtoms = mol.getAtomCount();
        for (int i = 0; i < numAtoms; i++) {
            if (!include(mol.getAtom(i)))
                continue;
            for (int j = i + 1; j < numAtoms; j++) {
                if (!include(mol.getAtom(j))) continue;
                final int dist = apsp.from(i).distanceTo(j);
                if (dist > MAX_DISTANCE)
                    continue;
                final IAtom beg = mol.getAtom(i);
                final IAtom end = mol.getAtom(j);
                paths.add(encodePath(dist, beg, end));
                paths.add(encodePath(dist, end, beg));
                if (isHalogen(mol.getAtom(i)) || isHalogen(mol.getAtom(j))) {
                    paths.add(encodeHalPath(dist, beg, end));
                    paths.add(encodeHalPath(dist, end, beg));
                }
            }
        }
    }
672858
private boolean getPresenceOfHydroxy(IAtomContainer ac, IAtom atom) {
        IAtom neighbour0 = (IAtom) ac.getConnectedAtomsList(atom).get(0);
        List first = null;
        if (neighbour0.getSymbol().equals("C")) {
            first = ac.getConnectedAtomsList(neighbour0);
            for (int i = 0; i < first.size(); i++) {
                IAtom conAtom = (IAtom) first.get(i);
                if (conAtom.getSymbol().equals("O")) {
                    if (ac.getBond(neighbour0, conAtom).getOrder() == IBond.Order.SINGLE) {
                        if (ac.getConnectedBondsCount(conAtom) > 1 && getHydrogenCount(ac, conAtom) == 0) {
                            return false;
                        } else {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
1129588
@Override
    public DescriptorValue calculate(IAtomContainer container) {
        if (taeParams == null) return getDummyDescriptorValue(new CDKException("TAE parameters were not initialized"));
        if (!(container instanceof IBioPolymer))
            return getDummyDescriptorValue(new CDKException("The molecule should be of type IBioPolymer"));

        IBioPolymer peptide = (IBioPolymer) container;

        // I assume that we get single letter names
        //Collection aas = peptide.getMonomerNames();

        double[] desc = new double[ndesc];
        for (int i = 0; i < ndesc; i++)
            desc[i] = 0.0;

        List<IMonomer> monomers = getMonomers(peptide);

        for (Iterator<IMonomer> iterator = monomers.iterator(); iterator.hasNext();) {
            IMonomer monomer = iterator.next();

            String o = monomer.getMonomerName();

            if (o.length() == 0) continue;

            String olc = String.valueOf(o.toLowerCase().charAt(0));
            String tlc = (String) nametrans.get(olc);

            logger.debug("Converted " + olc + " to " + tlc);

            // get the params for this AA
            Double[] params = (Double[]) taeParams.get(tlc);

            for (int i = 0; i < ndesc; i++)
                desc[i] += params[i];
        }

        DoubleArrayResult retval = new DoubleArrayResult(ndesc);
        for (int i = 0; i < ndesc; i++)
            retval.add(desc[i]);

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), retval,
                getDescriptorNames());
    }
146640
private int[] neighbors(ITetrahedralChirality element, Map<IAtom, Integer> map) {
        IAtom[] atoms = element.getLigands();
        int[] vs = new int[atoms.length];
        for (int i = 0; i < atoms.length; i++)
            vs[i] = map.get(atoms[i]);
        return vs;
    }
145748
def is_transport_reaction_annotations(rxn):
    
    reactants = set([(k, tuple(v)) for met in rxn.reactants
                     for k, v in iteritems(met.annotation)
                     if met.id != "H"
                     and k is not None and k != 'sbo' and v is not None])
    products = set([(k, tuple(v)) for met in rxn.products
                    for k, v in iteritems(met.annotation)
                    if met.id != "H"
                    and k is not None and k != 'sbo' and v is not None])
    # Find intersection between reactant annotations and
    # product annotations to find common metabolites between them,
    # satisfying the requirements for a transport reaction. Reactions such
    # as those involving oxidoreductases (where no net transport of
    # Hydrogen is occurring, but rather just an exchange of electrons or
    # charges effecting a change in protonation) are excluded.
    transported_mets = reactants & products
    if len(transported_mets) > 0:
        return True
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);
                }
            }
        }
    }
1075233
def find_metal_binding(self, lig_atoms, water_oxygens):
        
        a_set = []
        data = namedtuple('metal_binding', 'atom orig_atom atom_orig_idx type fgroup restype resnr reschain location')
        for oxygen in water_oxygens:
            a_set.append(data(atom=oxygen.oxy, atom_orig_idx=oxygen.oxy_orig_idx, type='O', fgroup='water',
                              restype=whichrestype(oxygen.oxy), resnr=whichresnumber(oxygen.oxy),
                              reschain=whichchain(oxygen.oxy), location='water', orig_atom=self.Mapper.id_to_atom(oxygen.oxy_orig_idx)))
        # #@todo Refactor code
        for a in lig_atoms:
            a_orig_idx = self.Mapper.mapid(a.idx, mtype='ligand', bsid=self.bsid)
            n_atoms = pybel.ob.OBAtomAtomIter(a.OBAtom)  # Neighboring atoms
            # All atomic numbers of neighboring atoms
            n_atoms_atomicnum = [n.GetAtomicNum() for n in pybel.ob.OBAtomAtomIter(a.OBAtom)]
            if a.atomicnum == 8:  # Oxygen
                if n_atoms_atomicnum.count('1') == 1 and len(n_atoms_atomicnum) == 2:  # Oxygen in alcohol (R-[O]-H)
                    a_set.append(data(atom=a, atom_orig_idx=a_orig_idx, type='O', fgroup='alcohol',
                                      restype=self.hetid, resnr=self.position, reschain=self.chain,
                                      location='ligand', orig_atom=self.Mapper.id_to_atom(a_orig_idx)))
                if True in [n.IsAromatic() for n in n_atoms] and not a.OBAtom.IsAromatic():  # Phenolate oxygen
                    a_set.append(data(atom=a, atom_orig_idx=a_orig_idx, type='O', fgroup='phenolate',
                                      restype=self.hetid, resnr=self.position, reschain=self.chain,
                                      location='ligand', orig_atom=self.Mapper.id_to_atom(a_orig_idx)))
            if a.atomicnum == 6:  # It's a carbon atom
                if n_atoms_atomicnum.count(8) == 2 and n_atoms_atomicnum.count(6) == 1:  # It's a carboxylate group
                    for neighbor in [n for n in n_atoms if n.GetAtomicNum() == 8]:
                        neighbor_orig_idx = self.Mapper.mapid(neighbor.GetIdx(), mtype='ligand', bsid=self.bsid)
                        a_set.append(data(atom=pybel.Atom(neighbor), atom_orig_idx=neighbor_orig_idx, type='O',
                                          fgroup='carboxylate',
                                          restype=self.hetid,
                                          resnr=self.position, reschain=self.chain,
                                          location='ligand', orig_atom=self.Mapper.id_to_atom(a_orig_idx)))
            if a.atomicnum == 15:  # It's a phosphor atom
                if n_atoms_atomicnum.count(8) >= 3:  # It's a phosphoryl
                    for neighbor in [n for n in n_atoms if n.GetAtomicNum() == 8]:
                        neighbor_orig_idx = self.Mapper.mapid(neighbor.GetIdx(), mtype='ligand', bsid=self.bsid)
                        a_set.append(data(atom=pybel.Atom(neighbor), atom_orig_idx=neighbor_orig_idx, type='O',
                                          fgroup='phosphoryl',
                                          restype=self.hetid,
                                          resnr=self.position, reschain=self.chain,
                                          location='ligand', orig_atom=self.Mapper.id_to_atom(a_orig_idx)))
                if n_atoms_atomicnum.count(8) == 2:  # It's another phosphor-containing group #@todo (correct name?)
                    for neighbor in [n for n in n_atoms if n.GetAtomicNum() == 8]:
                        neighbor_orig_idx = self.Mapper.mapid(neighbor.GetIdx(), mtype='ligand', bsid=self.bsid)
                        a_set.append(data(atom=pybel.Atom(neighbor), atom_orig_idx=neighbor_orig_idx, type='O',
                                          fgroup='phosphor.other', restype=self.hetid,
                                          resnr=self.position,
                                          reschain=self.chain, location='ligand', orig_atom=self.Mapper.id_to_atom(a_orig_idx)))
            if a.atomicnum == 7:  # It's a nitrogen atom
                if n_atoms_atomicnum.count(6) == 2:  # It's imidazole/pyrrole or similar
                    a_set.append(data(atom=a, atom_orig_idx=a_orig_idx, type='N', fgroup='imidazole/pyrrole',
                                      restype=self.hetid, resnr=self.position, reschain=self.chain,
                                      location='ligand', orig_atom=self.Mapper.id_to_atom(a_orig_idx)))
            if a.atomicnum == 16:  # It's a sulfur atom
                if True in [n.IsAromatic() for n in n_atoms] and not a.OBAtom.IsAromatic():  # Thiolate
                    a_set.append(data(atom=a, atom_orig_idx=a_orig_idx, type='S', fgroup='thiolate',
                                      restype=self.hetid, resnr=self.position, reschain=self.chain,
                                      location='ligand', orig_atom=self.Mapper.id_to_atom(a_orig_idx)))
                if set(n_atoms_atomicnum) == {26}:  # Sulfur in Iron sulfur cluster
                    a_set.append(data(atom=a, atom_orig_idx=a_orig_idx, type='S', fgroup='iron-sulfur.cluster',
                                      restype=self.hetid, resnr=self.position, reschain=self.chain,
                                      location='ligand', orig_atom=self.Mapper.id_to_atom(a_orig_idx)))

        return a_set
124164
def find_hbd(self, all_atoms, hydroph_atoms):
        """"""
        donor_pairs = []
        data = namedtuple('hbonddonor', 'd d_orig_atom d_orig_idx h type')
        for donor in [a for a in all_atoms if a.OBAtom.IsHbondDonor() and a.idx not in self.altconf]:
            in_ring = False
            if not in_ring:
                for adj_atom in [a for a in pybel.ob.OBAtomAtomIter(donor.OBAtom) if a.IsHbondDonorH()]:
                    d_orig_idx = self.Mapper.mapid(donor.idx, mtype=self.mtype, bsid=self.bsid)
                    d_orig_atom = self.Mapper.id_to_atom(d_orig_idx)
                    donor_pairs.append(data(d=donor, d_orig_atom=d_orig_atom, d_orig_idx=d_orig_idx,
                                            h=pybel.Atom(adj_atom), type='regular'))
        for carbon in hydroph_atoms:
            for adj_atom in [a for a in pybel.ob.OBAtomAtomIter(carbon.atom.OBAtom) if a.GetAtomicNum() == 1]:
                d_orig_idx = self.Mapper.mapid(carbon.atom.idx, mtype=self.mtype, bsid=self.bsid)
                d_orig_atom = self.Mapper.id_to_atom(d_orig_idx)
                donor_pairs.append(data(d=carbon, d_orig_atom=d_orig_atom,
                                        d_orig_idx=d_orig_idx, h=pybel.Atom(adj_atom), type='weak'))
        return donor_pairs
73532
private void assignAsymIds(List<List<Chain>> polys, List<List<Chain>> nonPolys, List<List<Chain>> waters) {

		for (int i=0; i<polys.size(); i++) {
			String asymId = "A";

			for (Chain poly:polys.get(i)) {
				poly.setId(asymId);
				asymId = getNextAsymId(asymId);
			}
			for (Chain nonPoly:nonPolys.get(i)) {
				nonPoly.setId(asymId);
				asymId = getNextAsymId(asymId);
			}
			for (Chain water:waters.get(i)) {
				water.setId(asymId);
				asymId = getNextAsymId(asymId);
			}
		}
	}
1108134
def draw_salt_bridges(self,color="blue"):
		
		self.draw_saltbridges=""
		if self.saltbridges!=None:
			for bond in self.saltbridges.saltbridges_for_drawing:
				self.draw_saltbridges ="<g class='SaltBridges' transform='translate("+str((self.molecule.x_dim-self.molecule.molsize1)/2)+","+str((self.molecule.y_dim-self.molecule.molsize2)/2)+")'>'"
				atom = self.topology_data.universe.atoms[bond[0]-1] #zero-based index vs one-based index
				residue = (atom.resname, str(atom.resid), atom.segid)
				self.draw_saltbridges=self.draw_saltbridges+"<line x1='"+str(int(self.molecule.nearest_points_coords[residue][0]))+"' y1='"+str(int(self.molecule.nearest_points_coords[residue][1]))+"' x2='"+str(float(self.molecule.ligand_atom_coords_from_diagr[bond[1]][0]))+"' y2='"+str(float(self.molecule.ligand_atom_coords_from_diagr[bond[1]][1]))+"' style='stroke:white;stroke-width:15' />"
				self.draw_saltbridges=self.draw_saltbridges+"<line x1='"+str(int(self.molecule.nearest_points_coords[residue][0]))+"' y1='"+str(int(self.molecule.nearest_points_coords[residue][1]))+"' x2='"+str(float(self.molecule.ligand_atom_coords_from_diagr[bond[1]][0]))+"' y2='"+str(float(self.molecule.ligand_atom_coords_from_diagr[bond[1]][1]))+"' style='stroke:"+color+";stroke-width:4' />"
				self.draw_saltbridges= self.draw_saltbridges+"</g>"
573931
private int getHalogenCount(IAtomContainer ac, IAtom atom) {
        List<IAtom> neighbours = ac.getConnectedAtomsList(atom);
        int acounter = 0;
        for (IAtom neighbour : neighbours) {
            if (neighbour.getSymbol().equals("F") || neighbour.getSymbol().equals("I")
                    || neighbour.getSymbol().equals("Cl") || neighbour.getSymbol().equals("Br")) {
                acounter += 1;
            }
        }
        return acounter;
    }