From c06a9af4331b34a8537b28b5e749c442e1bc1682 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Wed, 7 Sep 2016 11:54:14 +0100 Subject: [PATCH] JAL-1803 first pass at updatePDBEntry * merge PDBEntry if same ID, existing is null or identical filename, and chaincode is unspecified or identical to new one. * merge propagates type, chainCode, filename, and all properties to parent. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Note TODOs: we don’t recognise and merge 1QIPA onto 1QIP (yet) --- src/jalview/datamodel/PDBEntry.java | 50 ++++++++++++++++++++++++++++ src/jalview/datamodel/Sequence.java | 60 +++++++++++++++++++++++++++++----- src/jalview/datamodel/SequenceI.java | 7 +++- 3 files changed, 108 insertions(+), 9 deletions(-) diff --git a/src/jalview/datamodel/PDBEntry.java b/src/jalview/datamodel/PDBEntry.java index 673c12a..1c1d192 100755 --- a/src/jalview/datamodel/PDBEntry.java +++ b/src/jalview/datamodel/PDBEntry.java @@ -245,4 +245,54 @@ public class PDBEntry { return id; } + + /** + * update entry with details from another entry concerning the same PDB + * ID/file spec. + * + * @param newEntry + * @return true if modifications were made + */ + public boolean updateFrom(PDBEntry newEntry) + { + boolean modified = false; + + if (getFile() == null) + { + // update file and type of file + modified |= newEntry.getFile() != null; + setFile(newEntry.getFile()); + } + if (newEntry.getType() != null && newEntry.getFile() != null + && newEntry.getFile().equals(getFile())) + { + setType(newEntry.getType()); + } + if (getChainCode() == null + || (getChainCode() != null && getChainCode().length() == 0 && newEntry + .getChainCode() != null)) + { + modified |= getChainCode() == null + || !newEntry.getChainCode().equals(getChainCode()); + setChainCode(newEntry.getChainCode()); + } + if (newEntry.getProperty() != null) + { + if (properties == null) + { + properties = new Hashtable(); + } + // TODO: getProperty -> Map + for (Object p : newEntry.getProperty().keySet()) + { + if (properties.get(p) == null + || !properties.get(p).equals(newEntry.getProperty().get(p))) + { + modified = true; + } + properties.put(p, newEntry.getProperty().get(p)); + } + } + return modified; + } } diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index 5886ae0..4f626a4 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -418,22 +418,66 @@ public class Sequence extends ASequence implements SequenceI { pdbIds = new Vector(); } - if (pdbIds.contains(entry)) - { - updatePDBEntry(pdbIds.get(pdbIds.indexOf(entry)), entry); - } - else + if (!updatedPDBEntry(pdbIds, entry)) { pdbIds.addElement(entry); } } - private static void updatePDBEntry(PDBEntry oldEntry, PDBEntry newEntry) + private static boolean updatedPDBEntry(List entries, + PDBEntry newEntry) { - if (newEntry.getFile() != null) + for (PDBEntry xtant : entries) { - oldEntry.setFile(newEntry.getFile()); + if (xtant.getFile() != null && newEntry.getFile() != null + && !xtant.getFile().equals(newEntry.getFile())) + { + // different structure data, so leave alone. + continue; + } + // loop through to check whether we can find a matching ID + + // either exact + if (!xtant.getId().equals(newEntry.getId())) + { + /* TODO: support stemming to group PDB IDs. + // or stemming, with exactly one alphanumeric character difference + if (xtant.getId().length() < newEntry.getId().length()) + { + if (!newEntry.getId().startsWith(xtant.getId())) + { + continue; + } + // newEntry may be chain specific PDBEntry + // TODO: copy/update details from newEntry to xtant + } + else + { + if (!xtant.getId().startsWith(newEntry.getId())) + { + continue; + } + // xtant may be chain specific PDBEntry + // TODO: copy/update missing details from newEntry + }*/ + continue; + } + if (xtant.getChainCode() != null && xtant.getChainCode().length() > 0 + && newEntry.getChainCode() != null + && !newEntry.getChainCode().equals(xtant.getChainCode())) + { + // don't overwrite - multiple chain mappings for a sequence yield + // multiple PDBEntries + // each with different chaincode + continue; + } + + xtant.updateFrom(newEntry); + + return true; } + // if we got to the end of the loop, nothing was updated. + return false; } /** diff --git a/src/jalview/datamodel/SequenceI.java b/src/jalview/datamodel/SequenceI.java index ec7520b..55c59db 100755 --- a/src/jalview/datamodel/SequenceI.java +++ b/src/jalview/datamodel/SequenceI.java @@ -289,7 +289,12 @@ public interface SequenceI extends ASequenceI public Vector getAllPDBEntries(); /** - * add entry to the vector of PDBIds, if it isn't in the list already + * add entry to the *normalised* vector of PDBIds. + * + * If a PDBEntry is passed with an entry.getID() string, as one already in the + * list, or one is added that appears to be the same but has a chain ID + * appended, then the existing PDBEntry will be updated with the new + * attributes. * * @param entry */ -- 1.7.10.2