/** * identify additional groups that are not directly attached to amino acids. * * @param mc {@link ModifiedCompound}. * @param chain a {@link Chain}. * @return a list of added groups. */ private void identifyAdditionalAttachments( ModifiedCompound mc, List<Group> ligands, Map<String, Chain> mapChainIdChain) { if (ligands.isEmpty()) { return; } // TODO: should the additional groups only be allowed to the identified // ligands or both amino acids and ligands? Currently only on ligands // ligands to amino acid bonds for same modification of unknown category // will be combined in mergeModComps() // TODO: how about chain-chain links? List<Group> identifiedGroups = new ArrayList<Group>(); for (StructureGroup num : mc.getGroups(false)) { Group group; try { // String numIns = "" + num.getResidueNumber(); // if (num.getInsCode() != null) { // numIns += num.getInsCode(); // } ResidueNumber resNum = new ResidueNumber(); resNum.setChainId(num.getChainId()); resNum.setSeqNum(num.getResidueNumber()); resNum.setInsCode(num.getInsCode()); // group = chain.getGroupByPDB(numIns); group = mapChainIdChain.get(num.getChainId()).getGroupByPDB(resNum); } catch (StructureException e) { logger.error("Exception: ", e); // should not happen continue; } identifiedGroups.add(group); } int start = 0; int n = identifiedGroups.size(); while (n > start) { for (Group group1 : ligands) { for (int i = start; i < n; i++) { Group group2 = identifiedGroups.get(i); if (!identifiedGroups.contains(group1)) { List<Atom[]> linkedAtoms = StructureUtil.findAtomLinkages(group1, group2, false, bondLengthTolerance); if (!linkedAtoms.isEmpty()) { for (Atom[] atoms : linkedAtoms) { mc.addAtomLinkage( StructureUtil.getStructureAtomLinkage(atoms[0], false, atoms[1], false)); } identifiedGroups.add(group1); break; } } } } start = n; n = identifiedGroups.size(); } }
/** * Assembly the matched linkages. * * @param matchedAtomsOfLinkages * @param mod * @param condition * @param ret ModifiedCompound will be stored here. */ private void assembleLinkages( List<List<Atom[]>> matchedAtomsOfLinkages, ProteinModification mod, List<ModifiedCompound> ret) { ModificationCondition condition = mod.getCondition(); List<ModificationLinkage> modLinks = condition.getLinkages(); int nLink = matchedAtomsOfLinkages.size(); int[] indices = new int[nLink]; Set<ModifiedCompound> identifiedCompounds = new HashSet<ModifiedCompound>(); while (indices[0] < matchedAtomsOfLinkages.get(0).size()) { List<Atom[]> atomLinkages = new ArrayList<Atom[]>(nLink); for (int iLink = 0; iLink < nLink; iLink++) { Atom[] atoms = matchedAtomsOfLinkages.get(iLink).get(indices[iLink]); atomLinkages.add(atoms); } if (matchLinkages(modLinks, atomLinkages)) { // matched int n = atomLinkages.size(); List<StructureAtomLinkage> linkages = new ArrayList<StructureAtomLinkage>(n); for (int i = 0; i < n; i++) { Atom[] linkage = atomLinkages.get(i); StructureAtomLinkage link = StructureUtil.getStructureAtomLinkage( linkage[0], residues.contains(linkage[0].getGroup()), linkage[1], residues.contains(linkage[1].getGroup())); linkages.add(link); } ModifiedCompound mc = new ModifiedCompoundImpl(mod, linkages); if (!identifiedCompounds.contains(mc)) { ret.add(mc); identifiedCompounds.add(mc); } } // indices++ (e.g. [0,0,1]=>[0,0,2]=>[1,2,0]) int i = nLink - 1; while (i >= 0) { if (i == 0 || indices[i] < matchedAtomsOfLinkages.get(i).size() - 1) { indices[i]++; break; } else { indices[i] = 0; i--; } } } }
/** Get matched atoms for all linkages. */ private List<List<Atom[]>> getMatchedAtomsOfLinkages( ModificationCondition condition, Map<Component, Set<Group>> mapCompGroups) { List<ModificationLinkage> linkages = condition.getLinkages(); int nLink = linkages.size(); List<List<Atom[]>> matchedAtomsOfLinkages = new ArrayList<List<Atom[]>>(nLink); for (int iLink = 0; iLink < nLink; iLink++) { ModificationLinkage linkage = linkages.get(iLink); Component comp1 = linkage.getComponent1(); Component comp2 = linkage.getComponent2(); // boolean isAA1 = comp1.; // boolean isAA2 = comp2.getType()==true; Set<Group> groups1 = mapCompGroups.get(comp1); Set<Group> groups2 = mapCompGroups.get(comp2); List<Atom[]> list = new ArrayList<Atom[]>(); List<String> potentialNamesOfAtomOnGroup1 = linkage.getPDBNameOfPotentialAtomsOnComponent1(); for (String name : potentialNamesOfAtomOnGroup1) { if (name.equals("*")) { // wildcard potentialNamesOfAtomOnGroup1 = null; // search all atoms break; } } List<String> potentialNamesOfAtomOnGroup2 = linkage.getPDBNameOfPotentialAtomsOnComponent2(); for (String name : potentialNamesOfAtomOnGroup2) { if (name.equals("*")) { // wildcard potentialNamesOfAtomOnGroup2 = null; // search all atoms break; } } for (Group g1 : groups1) { for (Group g2 : groups2) { if (g1.equals(g2)) { continue; } // only for wildcard match of two residues boolean ignoreNCLinkage = potentialNamesOfAtomOnGroup1 == null && potentialNamesOfAtomOnGroup2 == null && residues.contains(g1) && residues.contains(g2); Atom[] atoms = StructureUtil.findNearestAtomLinkage( g1, g2, potentialNamesOfAtomOnGroup1, potentialNamesOfAtomOnGroup2, ignoreNCLinkage, bondLengthTolerance); if (atoms != null) { list.add(atoms); } } } if (list.isEmpty()) { // broken linkage break; } matchedAtomsOfLinkages.add(list); } return matchedAtomsOfLinkages; }
/** * @param modifications a set of {@link ProteinModification}s. * @param residues * @param ligands * @param saveTo save result to * @return map from component to list of corresponding residues in the chain. */ private void addModificationGroups( final Set<ProteinModification> modifications, final List<Group> residues, final List<Group> ligands, final Map<Component, Set<Group>> saveTo) { if (residues == null || ligands == null || modifications == null) { throw new IllegalArgumentException("Null argument(s)."); } Map<Component, Set<Component>> mapSingleMultiComps = new HashMap<Component, Set<Component>>(); for (ProteinModification mod : modifications) { ModificationCondition condition = mod.getCondition(); for (Component comp : condition.getComponents()) { for (String pdbccId : comp.getPdbccIds()) { Component single = Component.of(Collections.singleton(pdbccId), comp.isNTerminal(), comp.isCTerminal()); Set<Component> mult = mapSingleMultiComps.get(single); if (mult == null) { mult = new HashSet<Component>(); mapSingleMultiComps.put(single, mult); } mult.add(comp); } } } { // ligands Set<Component> ligandsWildCard = mapSingleMultiComps.get(Component.of("*")); for (Group group : ligands) { String pdbccId = group.getPDBName().trim(); Set<Component> comps = mapSingleMultiComps.get(Component.of(pdbccId)); for (Component comp : unionComponentSet(ligandsWildCard, comps)) { Set<Group> gs = saveTo.get(comp); if (gs == null) { gs = new LinkedHashSet<Group>(); saveTo.put(comp, gs); } gs.add(group); } } } { // residues if (residues.isEmpty()) { return; } Set<Component> residuesWildCard = mapSingleMultiComps.get(Component.of("*")); // for all residues for (Group group : residues) { String pdbccId = group.getPDBName().trim(); Set<Component> comps = mapSingleMultiComps.get(Component.of(pdbccId)); for (Component comp : unionComponentSet(residuesWildCard, comps)) { Set<Group> gs = saveTo.get(comp); if (gs == null) { gs = new LinkedHashSet<Group>(); saveTo.put(comp, gs); } gs.add(group); } } // for N-terminal int nRes = residues.size(); int iRes = 0; Group res; do { // for all ligands on N terminal and the first residue res = residues.get(iRes++); Set<Component> nTermWildCard = mapSingleMultiComps.get(Component.of("*", true, false)); Set<Component> comps = mapSingleMultiComps.get(Component.of(res.getPDBName(), true, false)); for (Component comp : unionComponentSet(nTermWildCard, comps)) { Set<Group> gs = saveTo.get(comp); if (gs == null) { gs = new LinkedHashSet<Group>(); saveTo.put(comp, gs); } gs.add(res); } } while (iRes < nRes && ligands.contains(res)); // for C-terminal iRes = residues.size() - 1; do { // for all ligands on C terminal and the last residue res = residues.get(iRes--); Set<Component> cTermWildCard = mapSingleMultiComps.get(Component.of("*", false, true)); Set<Component> comps = mapSingleMultiComps.get(Component.of(res.getPDBName(), false, true)); for (Component comp : unionComponentSet(cTermWildCard, comps)) { Set<Group> gs = saveTo.get(comp); if (gs == null) { gs = new LinkedHashSet<Group>(); saveTo.put(comp, gs); } gs.add(res); } } while (iRes >= 0 && ligands.contains(res)); } }