From: Jim Procter Date: Fri, 1 Sep 2017 16:22:42 +0000 (+0100) Subject: JAL-2694 StructureSelectionManager.getMapping takes a list of Chain IDs per sequence... X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=dcbbfa95b35e8316628a92ce3c2ba31c555d3faa;p=jalview.git JAL-2694 StructureSelectionManager.getMapping takes a list of Chain IDs per sequence to be bound to structure, and resolveChains adjusted accordingly. targetChains also dropped in StructureViewer constructor since resolveChains discovers extant chain mappings, and StructureSelectionManager infers any sequence/chain mappings that remain.
 one failing test in this commit --- 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;