/** * @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)); } }
/** * Identify a set of modifications in a a list of chains. * * @param chains query {@link Chain}s. * @param potentialModifications query {@link ProteinModification}s. */ public void identify( final List<Chain> chains, final Set<ProteinModification> potentialModifications) { if (chains == null) { throw new IllegalArgumentException("Null structure."); } if (potentialModifications == null) { throw new IllegalArgumentException("Null potentialModifications."); } reset(); if (potentialModifications.isEmpty()) { return; } Map<String, Chain> mapChainIdChain = new HashMap<String, Chain>(chains.size()); residues = new ArrayList<Group>(); List<Group> ligands = new ArrayList<Group>(); Map<Component, Set<Group>> mapCompGroups = new HashMap<Component, Set<Group>>(); for (Chain chain : chains) { mapChainIdChain.put(chain.getChainID(), chain); List<Group> ress = StructureUtil.getAminoAcids(chain); // List<Group> ligs = chain.getAtomLigands(); List<Group> ligs = StructureTools.filterLigands(chain.getAtomGroups()); residues.addAll(ress); residues.removeAll(ligs); ligands.addAll(ligs); addModificationGroups(potentialModifications, ress, ligs, mapCompGroups); } if (residues.isEmpty()) { String pdbId = "?"; if (chains.size() > 0) { Structure struc = chains.get(0).getParent(); if (struc != null) pdbId = struc.getPDBCode(); } logger.warn( "No amino acids found for {}. Either you did not parse the PDB file with alignSEQRES records, or this record does not contain any amino acids.", pdbId); } List<ModifiedCompound> modComps = new ArrayList<ModifiedCompound>(); for (ProteinModification mod : potentialModifications) { ModificationCondition condition = mod.getCondition(); List<Component> components = condition.getComponents(); if (!mapCompGroups.keySet().containsAll(components)) { // not all components exist for this mod. continue; } int sizeComps = components.size(); if (sizeComps == 1) { processCrosslink1(mapCompGroups, modComps, mod, components); } else { processMultiCrosslink(mapCompGroups, modComps, mod, condition); } } if (recordAdditionalAttachments) { // identify additional groups that are not directly attached to amino acids. for (ModifiedCompound mc : modComps) { identifyAdditionalAttachments(mc, ligands, mapChainIdChain); } } mergeModComps(modComps); identifiedModifiedCompounds.addAll(modComps); // record unidentifiable linkage if (recordUnidentifiableModifiedCompounds) { recordUnidentifiableAtomLinkages(modComps, ligands); recordUnidentifiableModifiedResidues(modComps); } }