From dcbbfa95b35e8316628a92ce3c2ba31c555d3faa Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Fri, 1 Sep 2017 17:22:42 +0100 Subject: [PATCH] =?utf8?q?JAL-2694=20StructureSelectionManager.getMapping=20?= =?utf8?q?takes=20a=20list=20of=20Chain=20IDs=20per=20sequence=20to=20be=20b?= =?utf8?q?ound=20to=20structure,=20and=20resolveChains=20adjusted=20accordin?= =?utf8?q?gly.=20targetChains=20also=20dropped=20in=20StructureViewer=20cons?= =?utf8?q?tructor=20since=20resolveChains=20discovers=20extant=20chain=20map?= =?utf8?q?pings,=20and=20StructureSelectionManager=20infers=20any=20sequence?= =?utf8?q?/chain=20mappings=20that=20remain.=E2=80=A8=20one=20failing=20test?= =?utf8?q?=20in=20this=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/MCview/AppletPDBCanvas.java | 4 +- src/MCview/PDBCanvas.java | 4 +- src/jalview/appletgui/AlignFrame.java | 4 +- src/jalview/appletgui/AppletJmol.java | 4 +- src/jalview/gui/AppJmol.java | 2 +- src/jalview/gui/ChimeraViewFrame.java | 2 +- src/jalview/gui/StructureViewerBase.java | 9 ++- .../structure/StructureSelectionManager.java | 62 +++++++++++++------- .../structures/models/AAStructureBindingModel.java | 57 +++++++++--------- test/jalview/structure/Mapping.java | 19 ++++-- .../structure/StructureSelectionManagerTest.java | 2 +- .../models/AAStructureBindingModelTest.java | 6 +- 12 files changed, 105 insertions(+), 70 deletions(-) diff --git a/src/MCview/AppletPDBCanvas.java b/src/MCview/AppletPDBCanvas.java index f94faba..7b03d7c 100644 --- a/src/MCview/AppletPDBCanvas.java +++ b/src/MCview/AppletPDBCanvas.java @@ -159,7 +159,9 @@ public class AppletPDBCanvas extends Panel try { - pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol); + pdb = ssm.setMapping(seq, + StructureSelectionManager.perChainList(chains), + pdbentry.getFile(), protocol); if (protocol == DataSourceType.PASTE) { diff --git a/src/MCview/PDBCanvas.java b/src/MCview/PDBCanvas.java index b2f2503..1914b4a 100644 --- a/src/MCview/PDBCanvas.java +++ b/src/MCview/PDBCanvas.java @@ -153,7 +153,9 @@ public class PDBCanvas extends JPanel try { - pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol); + pdb = ssm.setMapping(seq, + StructureSelectionManager.perChainList(chains), + pdbentry.getFile(), protocol); if (protocol.equals(jalview.io.DataSourceType.PASTE)) { diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index b48dec9..38e0b42 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -4133,7 +4133,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, { // register the association(s) and quit, don't create any windows. if (StructureSelectionManager.getStructureSelectionManager(applet) - .setMapping(seqs, chains, pdb.getFile(), protocol) == null) + .setMapping(seqs, + StructureSelectionManager.perChainList(chains), + pdb.getFile(), protocol) == null) { System.err.println("Failed to map " + pdb.getFile() + " (" + protocol + ") to any sequences"); diff --git a/src/jalview/appletgui/AppletJmol.java b/src/jalview/appletgui/AppletJmol.java index 49219b9..3456310 100644 --- a/src/jalview/appletgui/AppletJmol.java +++ b/src/jalview/appletgui/AppletJmol.java @@ -213,7 +213,9 @@ public class AppletJmol extends EmbmenuFrame implements { reader = StructureSelectionManager .getStructureSelectionManager(ap.av.applet) - .setMapping(seq, chains, pdbentry.getFile(), protocol); + .setMapping(seq, + StructureSelectionManager.perChainList(chains), + pdbentry.getFile(), protocol); // PROMPT USER HERE TO ADD TO NEW OR EXISTING VIEW? // FOR NOW, LETS JUST OPEN A NEW WINDOW } diff --git a/src/jalview/gui/AppJmol.java b/src/jalview/gui/AppJmol.java index a4597d3..dd67b03 100644 --- a/src/jalview/gui/AppJmol.java +++ b/src/jalview/gui/AppJmol.java @@ -175,7 +175,7 @@ public class AppJmol extends StructureViewerBase * If the PDB file is already loaded, the user may just choose to add to an * existing viewer (or cancel) */ - if (addAlreadyLoadedFile(seq, chains, ap, pdbId)) + if (addAlreadyLoadedFile(seq, ap, pdbId)) { return; } diff --git a/src/jalview/gui/ChimeraViewFrame.java b/src/jalview/gui/ChimeraViewFrame.java index ba360af..305df8a 100644 --- a/src/jalview/gui/ChimeraViewFrame.java +++ b/src/jalview/gui/ChimeraViewFrame.java @@ -219,7 +219,7 @@ public class ChimeraViewFrame extends StructureViewerBase * If the PDB file is already loaded, the user may just choose to add to an * existing viewer (or cancel) */ - if (addAlreadyLoadedFile(seq, chains, ap, pdbId)) + if (addAlreadyLoadedFile(seq, ap, pdbId)) { return; } diff --git a/src/jalview/gui/StructureViewerBase.java b/src/jalview/gui/StructureViewerBase.java index 3ba9947..8c8b81d 100644 --- a/src/jalview/gui/StructureViewerBase.java +++ b/src/jalview/gui/StructureViewerBase.java @@ -448,18 +448,17 @@ public abstract class StructureViewerBase extends GStructureViewer * and updates any viewers that have the PDB file * * @param seq - * @param chains * @param apanel * @param pdbFilename */ protected void addSequenceMappingsToStructure(SequenceI[] seq, - String[] chains, final AlignmentPanel apanel, String pdbFilename) + final AlignmentPanel apanel, String pdbFilename) { // TODO : Fix multiple seq to one chain issue here. /* * create the mappings */ - apanel.getStructureSelectionManager().setMapping(seq, chains, + apanel.getStructureSelectionManager().setMapping(seq, null, pdbFilename, DataSourceType.FILE); /* @@ -509,7 +508,7 @@ public abstract class StructureViewerBase extends GStructureViewer * @param pdbId * @return true if the user chooses to add to a viewer, or to cancel entirely */ - protected boolean addAlreadyLoadedFile(SequenceI[] seq, String[] chains, + protected boolean addAlreadyLoadedFile(SequenceI[] seq, final AlignmentPanel apanel, String pdbId) { boolean finished = false; @@ -535,7 +534,7 @@ public abstract class StructureViewerBase extends GStructureViewer } else if (option == JvOptionPane.YES_OPTION) { - addSequenceMappingsToStructure(seq, chains, apanel, alreadyMapped); + addSequenceMappingsToStructure(seq, apanel, alreadyMapped); finished = true; } } diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index a98738f..a8c6ecf 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -324,7 +324,8 @@ public class StructureSelectionManager * @return null or the structure data parsed as a pdb file */ synchronized public StructureFile setMapping(SequenceI[] sequence, - String[] targetChains, String pdbFile, DataSourceType protocol) + List[] targetChains, String pdbFile, + DataSourceType protocol) { return setMapping(true, sequence, targetChains, pdbFile, protocol); } @@ -350,7 +351,7 @@ public class StructureSelectionManager * @return null or the structure data parsed as a pdb file */ synchronized public StructureFile setMapping(boolean forStructureView, - SequenceI[] sequenceArray, String[] targetChainIds, + SequenceI[] sequenceArray, List[] targetChainIds, String pdbFile, DataSourceType sourceType) { /* @@ -416,7 +417,8 @@ public class StructureSelectionManager e.printStackTrace(); } - String targetChainId; + List targetChainId = new ArrayList(); + String _targetChainId; for (int s = 0; s < sequenceArray.length; s++) { boolean infChain = true; @@ -434,25 +436,28 @@ public class StructureSelectionManager } else if (seq.getName().indexOf("|") > -1) { - targetChainId = seq.getName() + targetChainId = new ArrayList(); + _targetChainId=seq.getName() .substring(seq.getName().lastIndexOf("|") + 1); - if (targetChainId.length() > 1) + if (_targetChainId.length() > 1) { - if (targetChainId.trim().length() == 0) + if (_targetChainId.trim().length() == 0) { - targetChainId = " "; + _targetChainId = " "; } else { // not a valid chain identifier - targetChainId = ""; + _targetChainId = ""; } } + targetChainId.add(_targetChainId); } else { - targetChainId = ""; + _targetChainId = ""; } + /* * Attempt pairwise alignment of the sequence with each chain in the PDB, @@ -468,7 +473,7 @@ public class StructureSelectionManager List maximalChainIds = new ArrayList<>(); for (PDBChain chain : pdb.getChains()) { - if (targetChainId.length() > 0 && !targetChainId.equals(chain.id) + if (targetChainId.size() > 0 && !targetChainId.contains(chain.id) && !infChain) { continue; // don't try to map chains don't match. @@ -483,7 +488,7 @@ public class StructureSelectionManager // as.calcScoreMatrix(); // as.traceAlignment(); - if (targetChainId.length() > 0 && chain.id.equals(targetChainId)) + if (targetChainId.size() > 0 && targetChainId.contains(chain.id)) { // Don't care - just pick this chain as the mapping maxChain = chain; @@ -536,19 +541,22 @@ public class StructureSelectionManager .getString("status.obtaining_mapping_with_sifts")); jalview.datamodel.Mapping sqmpping = maxAlignseq .getMappingFromS1(false); - if (targetChainId != null && !targetChainId.trim().isEmpty()) + if (targetChainId != null && !targetChainId.isEmpty()) { - StructureMapping siftsMapping; + List siftsMappings; try { - siftsMapping = getStructureMapping(seq, pdbFile, targetChainId, + siftsMappings = getStructureMapping(seq, pdbFile, targetChainId, pdb, maxChain, sqmpping, maxAlignseq); - seqToStrucMapping.add(siftsMapping); + for (StructureMapping siftsMapping : siftsMappings) + { + seqToStrucMapping.add(siftsMapping); maxChain.makeExactMapping(maxAlignseq, seq); maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this // "IEA:SIFTS" ? maxChain.transferResidueAnnotation(siftsMapping, sqmpping); ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0)); + } } catch (SiftsException e) { @@ -572,9 +580,9 @@ public class StructureSelectionManager { try { - StructureMapping siftsMapping = getStructureMapping(seq, - pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq); - foundSiftsMappings.add(siftsMapping); + foundSiftsMappings.addAll(getStructureMapping(seq, pdbFile, + Arrays.asList(new String[] + { chain.id }), pdb, chain, sqmpping, maxAlignseq)); } catch (SiftsException e) { System.err.println(e.getMessage()); @@ -646,12 +654,20 @@ public class StructureSelectionManager * @return * @throws SiftsException */ - private StructureMapping getStructureMapping(SequenceI seq, - String pdbFile, String targetChainId, StructureFile pdb, + private List getStructureMapping(SequenceI seq, + String pdbFile, List targetChainIdList, StructureFile pdb, PDBChain maxChain, jalview.datamodel.Mapping sqmpping, AlignSeq maxAlignseq) throws SiftsException { - StructureMapping curChainMapping = siftsClient + List currChainMappingList = new ArrayList(); + int p = 0; + do + { + String targetChainId = (targetChainIdList == null + || p >= targetChainIdList.size()) ? null + : targetChainIdList.get(p); + StructureMapping curChainMapping = siftsClient + .getSiftsStructureMapping(seq, pdbFile, targetChainId); try { @@ -659,12 +675,14 @@ public class StructureSelectionManager if (chain != null) { chain.transferResidueAnnotation(curChainMapping, sqmpping); + currChainMappingList.add(curChainMapping); } } catch (Exception e) { e.printStackTrace(); } - return curChainMapping; + } while (targetChainIdList != null && ++p < targetChainIdList.size()); + return currChainMappingList; } private List getNWMappings(SequenceI seq, diff --git a/src/jalview/structures/models/AAStructureBindingModel.java b/src/jalview/structures/models/AAStructureBindingModel.java index 2528286..b9dc58d 100644 --- a/src/jalview/structures/models/AAStructureBindingModel.java +++ b/src/jalview/structures/models/AAStructureBindingModel.java @@ -72,9 +72,9 @@ public abstract class AAStructureBindingModel private SequenceI[][] sequence; /* - * array of target chains for sequences - tied to pdbentry and sequence[] + * array of list of target chains for sequences - tied to pdbentry and sequence[] */ - private String[][] chains; + private List[][] chains; /* * datasource protocol for access to PDBEntrylatest @@ -164,20 +164,26 @@ public abstract class AAStructureBindingModel int chainmaps = 0; // JBPNote: JAL-2693 - this should be a list of chain mappings per // [pdbentry][sequence] - String[][] newchains = new String[pdbEntry.length][]; + List[][] newchains = new List[pdbEntry.length][]; int pe = 0; for (PDBEntry pdb : pdbEntry) { SequenceI[] seqsForPdb = sequence[pe]; if (seqsForPdb != null) { - newchains[pe] = new String[seqsForPdb.length]; + newchains[pe] = new List[seqsForPdb.length]; int se = 0; for (SequenceI asq : seqsForPdb) { - String chain = (chains != null && chains[pe] != null) + List chain = (chains != null && chains[pe] != null) ? chains[pe][se] : null; + if (chain == null) + { + chain = new ArrayList<>(); + } + newchains[pe][se] = chain; + SequenceI sq = (asq.getDatasetSequence() == null) ? asq : asq.getDatasetSequence(); if (sq.getAllPDBEntries() != null) @@ -190,14 +196,12 @@ public abstract class AAStructureBindingModel String chaincode = pdbentry.getChainCode(); if (chaincode != null && chaincode.length() > 0) { - chain = chaincode; + newchains[pe][se].add(chaincode); chainmaps++; - break; } } } } - newchains[pe][se] = chain; se++; } pe++; @@ -259,7 +263,7 @@ public abstract class AAStructureBindingModel return sequence; } - public String[][] getChains() + public List[][] getChains() { return chains; } @@ -280,7 +284,7 @@ public abstract class AAStructureBindingModel this.sequence = sequence; } - protected void setChains(String[][] chains) + protected void setChains(List[][] chains) { this.chains = chains; } @@ -354,12 +358,11 @@ public abstract class AAStructureBindingModel new Object[] { Integer.valueOf(pe).toString() })); } - final String nullChain = "TheNullChain"; - List s = new ArrayList(); - List c = new ArrayList(); + List s = new ArrayList<>(); + List> c = new ArrayList<>(); if (getChains() == null) { - setChains(new String[getPdbCount()][]); + setChains(new List[getPdbCount()][]); } if (getSequence()[pe] != null) { @@ -374,14 +377,14 @@ public abstract class AAStructureBindingModel } else { - c.add(nullChain); + c.add(new ArrayList()); } } else { if (tchain != null && tchain.length > 0) { - c.add(nullChain); + c.add(new ArrayList()); } } } @@ -393,7 +396,12 @@ public abstract class AAStructureBindingModel s.add(seq[i]); if (tchain != null && i < tchain.length) { - c.add(tchain[i] == null ? nullChain : tchain[i]); + List clist = new ArrayList(); + c.add(clist); + if (tchain[i] != null) + { + clist.add(tchain[i]); + } } } } @@ -401,14 +409,7 @@ public abstract class AAStructureBindingModel getSequence()[pe] = tmp; if (c.size() > 0) { - String[] tch = c.toArray(new String[c.size()]); - for (int i = 0; i < tch.length; i++) - { - if (tch[i] == nullChain) - { - tch[i] = null; - } - } + List[] tch = c.toArray(new List[c.size()]); getChains()[pe] = tch; } else @@ -425,8 +426,8 @@ public abstract class AAStructureBindingModel public synchronized PDBEntry[] addSequenceAndChain(PDBEntry[] pdbe, SequenceI[][] seq, String[][] chns) { - List v = new ArrayList(); - List rtn = new ArrayList(); + List v = new ArrayList<>(); + List rtn = new ArrayList<>(); for (int i = 0; i < getPdbCount(); i++) { v.add(getPdbEntry(i)); @@ -451,7 +452,7 @@ public abstract class AAStructureBindingModel { // expand the tied sequence[] and string[] arrays SequenceI[][] sqs = new SequenceI[getPdbCount()][]; - String[][] sch = new String[getPdbCount()][]; + List[][] sch = new List[getPdbCount()][]; System.arraycopy(getSequence(), 0, sqs, 0, getSequence().length); System.arraycopy(getChains(), 0, sch, 0, this.getChains().length); setSequence(sqs); diff --git a/test/jalview/structure/Mapping.java b/test/jalview/structure/Mapping.java index 85aea40..78f9cdf 100644 --- a/test/jalview/structure/Mapping.java +++ b/test/jalview/structure/Mapping.java @@ -34,6 +34,10 @@ import jalview.io.FileFormat; import jalview.io.FileLoader; import jalview.io.StructureFile; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.testng.Assert; import org.testng.AssertJUnit; import org.testng.annotations.BeforeClass; @@ -77,7 +81,9 @@ public class Mapping StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager(); StructureFile pmap = ssm.setMapping(true, new SequenceI[] { uprot }, - new String[] { "A" }, "test/jalview/ext/jmol/1QCF.pdb", + new List[] + { Arrays.asList(new String[] { "A" }) }, + "test/jalview/ext/jmol/1QCF.pdb", DataSourceType.FILE); assertTrue(pmap != null); SequenceI protseq = pmap.getSeqsAsArray()[0]; @@ -148,8 +154,9 @@ public class Mapping // Associate the 1GAQ pdb file with the subsequence 'imported' from another // source StructureFile pde = ssm.setMapping(true, new SequenceI[] { sq }, - new String[] - { "A" }, inFile = "examples/1gaq.txt", DataSourceType.FILE); + new List[] + { Arrays.asList(new String[] { "A" }) }, + inFile = "examples/1gaq.txt", DataSourceType.FILE); assertTrue("PDB File couldn't be found", pde != null); StructureMapping[] mp = ssm.getMapping(inFile); assertTrue("No mappings made.", mp != null && mp.length > 0); @@ -245,7 +252,8 @@ public class Mapping SequenceI newseq = seqf.getViewport().getAlignment().getSequenceAt(0); StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager(); StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq }, - new String[] { null }, "examples/3W5V.pdb", + new List[] + { Arrays.asList(new String[0]) }, "examples/3W5V.pdb", DataSourceType.FILE); if (pmap == null) { @@ -274,7 +282,8 @@ public class Mapping ssm.setProcessSecondaryStructure(true); ssm.setAddTempFacAnnot(true); StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq }, - new String[] { null }, "test/jalview/ext/jmol/1QCF.pdb", + new List[] + { new ArrayList() }, "test/jalview/ext/jmol/1QCF.pdb", DataSourceType.FILE); assertTrue(pmap != null); assertEquals("Original and copied sequence of different lengths.", diff --git a/test/jalview/structure/StructureSelectionManagerTest.java b/test/jalview/structure/StructureSelectionManagerTest.java index a7e52ff..8273651 100644 --- a/test/jalview/structure/StructureSelectionManagerTest.java +++ b/test/jalview/structure/StructureSelectionManagerTest.java @@ -134,7 +134,7 @@ public class StructureSelectionManagerTest sm.setProcessSecondaryStructure(true); sm.setAddTempFacAnnot(true); StructureFile pmap = sm.setMapping(true, new SequenceI[] { seq }, - new String[] { null }, "examples/1gaq.txt", DataSourceType.FILE); + null, "examples/1gaq.txt", DataSourceType.FILE); assertTrue(pmap != null); assertEquals(3, pmap.getSeqs().size()); diff --git a/test/jalview/structures/models/AAStructureBindingModelTest.java b/test/jalview/structures/models/AAStructureBindingModelTest.java index aea3687..fb5437e 100644 --- a/test/jalview/structures/models/AAStructureBindingModelTest.java +++ b/test/jalview/structures/models/AAStructureBindingModelTest.java @@ -237,12 +237,12 @@ public class AAStructureBindingModelTest } }; - String[][] chains = binder.getChains(); + List[][] chains = binder.getChains(); assertFalse(chains == null || chains[0] == null, "No chains discovered by binding"); assertEquals(2, chains[0].length); - assertEquals("A", chains[0][0]); - assertEquals("B", chains[0][1]); + assertEquals("A", chains[0][0].get(0)); + assertEquals("B", chains[0][1].get(0)); } AAStructureBindingModel testee; -- 1.7.10.2