Vector<String> atomsPicked = new Vector<>();
- Hashtable<String, String> chainFile;
+ /*
+ * lookup map of { pdbId:chainId, pdbFilepath }
+ */
+ Map<String, String> chainFile;
/*
* the default or current model displayed if the model cannot be identified
@Override
public synchronized String[] getStructureFiles()
{
+ if (modelFileNames != null)
+ {
+ return modelFileNames;
+ }
if (viewer == null)
{
return new String[0];
}
- if (modelFileNames == null)
+ List<String> mset = new ArrayList<>();
+ int modelCount = viewer.ms.mc;
+ String filePath = null;
+ for (int i = 0; i < modelCount; ++i)
{
- List<String> mset = new ArrayList<>();
- int modelCount = viewer.ms.mc;
- String filePath = null;
- for (int i = 0; i < modelCount; ++i)
+ filePath = viewer.ms.getModelFileName(i);
+ if (!mset.contains(filePath))
{
- filePath = viewer.ms.getModelFileName(i);
- if (!mset.contains(filePath))
- {
- mset.add(filePath);
- }
+ mset.add(filePath);
}
- modelFileNames = mset.toArray(new String[mset.size()]);
}
+ modelFileNames = mset.toArray(new String[mset.size()]);
return modelFileNames;
}
@Override
public String getModelSpec(int pdbfnum)
{
- if (pdbfnum < 0 || pdbfnum >= getPdbCount())
- {
- return "";
- }
-
/*
* For now, the test for having sub-models is whether multiple Chimera
* models are mapped for the PDB file; the models are returned as a response
* to the Chimera command 'list models type molecule', see
* ChimeraManager.getModelList().
*/
- List<ChimeraModel> maps = chimeraMaps.get(getStructureFiles()[pdbfnum]);
+ String[] structureFiles = getStructureFiles();
+ if (pdbfnum < 0 || pdbfnum >= structureFiles.length)
+ {
+ return "";
+ }
+
+ List<ChimeraModel> maps = chimeraMaps.get(structureFiles[pdbfnum]);
boolean hasSubModels = maps != null && maps.size() > 1;
String spec = "#" + String.valueOf(pdbfnum);
return hasSubModels ? spec + ".1" : spec;
private boolean finishedInit = false;
- /**
- * current set of model filenames loaded in the Jmol instance
+ /*
+ * current set of model filenames loaded in the Jmol instance
+ * array index 0, 1, 2... corresponds to Jmol model numbers 1, 2, 3...
*/
protected String[] modelFileNames = null;
}
/**
- * Build a data structure which records contiguous subsequences by model and
- * chain. From this we can easily generate the Chimera or Jmol specific
+ * Build a data structure which records contiguous subsequences by colour, model
+ * and chain. From this we can easily generate the Chimera or Jmol specific
* selection expression.
*
* <pre>
--- /dev/null
+package jalview.ext.jmol;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.gui.AppJmolBinding;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureSelectionManager;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import junit.extensions.PA;
+
+public class JalviewJmolBindingTest
+{
+ private AlignFrame af;
+
+ @BeforeTest(alwaysRun = true)
+ public void setup()
+ {
+ af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
+ DataSourceType.FILE);
+ }
+
+ @Test(groups = "Functional")
+ public void testBuildShowStructuresCommand()
+ {
+ AlignViewport av = af.getViewport();
+ PDBEntry[] pdbs = new PDBEntry[] {};
+ SequenceI seq1 = av.getAlignment().findSequenceMatch("FER1_SPIOL")[0];
+ assertNotNull(seq1);
+ SequenceI seq2 = av.getAlignment().findSequenceMatch("FER2_ARATH")[0];
+ assertNotNull(seq2);
+ StructureSelectionManager ssm = new StructureSelectionManager();
+ SequenceI[][] seqs = new SequenceI[][] { { seq1 }, { seq2 } };
+ AppJmolBinding testee = new AppJmolBinding(null, ssm, pdbs, seqs,
+ null);
+
+ /*
+ * map FER1_SPIOL residues 51-100 to residues 1-50 (atoms 1-250) in 1A70
+ * and residues 110-147 to structure residues 60-97
+ * (in fact there is no gap, added here for test purposes)
+ */
+ HashMap<Integer, int[]> map = new HashMap<>();
+ for (int pos = 51; pos <= 100; pos++)
+ {
+ map.put(pos, new int[] { pos - 50, 5 * (pos - 50) });
+ }
+ for (int pos = 110; pos <= 147; pos++)
+ {
+ map.put(pos, new int[] { pos - 50, 5 * (pos - 50) });
+ }
+ StructureMapping sm1 = new StructureMapping(seq1, "1a70.pdb", "1A70",
+ "A", map, null);
+ ssm.addStructureMapping(sm1);
+
+ /*
+ * map FER2_ARATH residues 53-148 to residues 2-97 in 4ZHO
+ */
+ map = new HashMap<>();
+ for (int pos = 53; pos <= 148; pos++)
+ {
+ map.put(pos, new int[] { pos - 51, 5 * (pos - 51) });
+ }
+ StructureMapping sm2 = new StructureMapping(seq2, "4zho.pdb", "4ZHO",
+ "B", map, null);
+ ssm.addStructureMapping(sm2);
+
+ /*
+ * show everything
+ */
+ String cmd = testee.buildShowStructuresCommand(av, true);
+ assertEquals(cmd, "display *; cartoon only; zoom 0");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, "display *; cartoon only");
+
+ /*
+ * stub out modelFileNames - array index is Jmol
+ * model number - 1
+ */
+ PA.setValue(testee, "modelFileNames",
+ new String[]
+ { "1a70.pdb", "4zho.pdb" });
+
+ /*
+ * stub out lookup map from pdb:chain to filename
+ */
+ Map<String, String> chainFiles = new HashMap<>();
+ PA.setValue(testee, "chainFile", chainFiles);
+ chainFiles.put("1A70:A", "1a70.pdb");
+ chainFiles.put("1A70:B", "1a70.pdb");
+ chainFiles.put("4ZHO:B", "4zho.pdb");
+ chainFiles.put("4ZHO:C", "4zho.pdb");
+
+ /*
+ * show all except for selected chains to hide
+ */
+ List<String> chainsToHide = (List<String>) PA.getValue(testee,
+ "chainsToHide");
+ chainsToHide.add("1A70:B");
+ chainsToHide.add("4ZHO:C");
+ cmd = testee.buildShowStructuresCommand(av, true);
+ assertEquals(cmd,
+ "display *; hide add :B/1.1,:C/2.1; cartoon only; zoom 0");
+
+ /*
+ * show alignment only, no chains hidden
+ */
+ chainsToHide.clear();
+ testee.setShowAlignmentOnly(true);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd,
+ "hide *;display (1-50,60-97)&:A/1.1,2-97:B/2.1; select displayed; cartoon only");
+
+ /*
+ * now with a chain hidden
+ */
+ chainsToHide.add("4ZHO:C");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ String expected = "hide *;display (1-50,60-97)&:A/1.1,2-97:B/2.1; select displayed; hide add :C/2.1; cartoon only";
+ assertEquals(cmd, expected);
+
+ /*
+ * hide columns in the mapped region - should not change the command (yet)
+ */
+ int fromCol = seq1.findIndex(60); // structure residue 10
+ int toCol = seq1.findIndex(70); // structure residue 20
+ av.hideColumns(fromCol - 1, toCol - 1);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, expected);
+
+ /*
+ * select 'hide hidden columns'
+ * command should now exclude these in both mapped sequences
+ */
+ testee.setHideHiddenRegions(true);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ expected = "hide *;display (1-9,21-50,60-97)&:A/1.1,(2-10,22-97)&:B/2.1; select displayed; hide add :C/2.1; cartoon only";
+ assertEquals(cmd, expected);
+
+ /*
+ * deselect 'show alignment only'
+ * hide hidden columns is now ignored
+ */
+ testee.setShowAlignmentOnly(false);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, "display *; hide add :C/2.1; cartoon only");
+ }
+}
--- /dev/null
+package jalview.ext.rbvi.chimera;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.gui.ChimeraViewFrame;
+import jalview.gui.JalviewChimeraBindingModel;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureSelectionManager;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel;
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
+import junit.extensions.PA;
+
+public class JalviewChimeraBindingTest
+{
+ private AlignFrame af;
+
+ @BeforeTest(alwaysRun = true)
+ public void setup()
+ {
+ af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
+ DataSourceType.FILE);
+ }
+
+ @Test(groups = "Functional")
+ public void testBuildShowStructuresCommand()
+ {
+ AlignViewport av = af.getViewport();
+ PDBEntry[] pdbs = new PDBEntry[] {};
+ StructureSelectionManager ssm = new StructureSelectionManager();
+ SequenceI seq1 = av.getAlignment().findSequenceMatch("FER1_SPIOL")[0];
+ assertNotNull(seq1);
+ SequenceI seq2 = av.getAlignment().findSequenceMatch("FER2_ARATH")[0];
+ assertNotNull(seq2);
+ SequenceI[][] seqs = new SequenceI[][] { { seq1 }, { seq2 } };
+ JalviewChimeraBindingModel testee = new JalviewChimeraBindingModel(
+ new ChimeraViewFrame(),
+ ssm, pdbs, seqs, null);
+
+ /*
+ * with no structures mapped
+ */
+ String cmd = testee.buildShowStructuresCommand(av, true);
+ assertEquals(cmd, "~display; ribbon; focus");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, "~display; ribbon");
+
+ /*
+ * stub out a structure with chains A and B
+ */
+ Map<String, List<ChimeraModel>> chimeraMaps = (Map<String, List<ChimeraModel>>) PA
+ .getValue(testee, "chimeraMaps");
+ ChimeraModel model0 = new ChimeraModel("1A70", ModelType.PDB_MODEL, 0,
+ 0);
+ chimeraMaps.put("1a70.pdb", Arrays.asList(model0));
+ ChimeraModel model1 = new ChimeraModel("4ZHO", ModelType.PDB_MODEL, 1,
+ 0);
+ chimeraMaps.put("4zho.pdb", Arrays.asList(model1));
+
+ Map<String, String> chainFiles = (Map<String, String>) PA
+ .getValue(testee, "chainFile");
+ chainFiles.put("1A70:A", "1a70.pdb");
+ chainFiles.put("1A70:B", "1a70.pdb");
+ chainFiles.put("4ZHO:B", "4zho.pdb");
+ chainFiles.put("4ZHO:C", "4zho.pdb");
+
+ /*
+ * map FER1_SPIOL residues 51-100 to residues 1-50 (atoms 1-250) in 1A70
+ * and residues 110-147 to structure residues 60-97
+ * (in fact there is no gap, added here for test purposes)
+ */
+ HashMap<Integer, int[]> map = new HashMap<>();
+ for (int pos = 51; pos <= 100; pos++)
+ {
+ map.put(pos, new int[] { pos - 50, 5 * (pos - 50) });
+ }
+ for (int pos = 110; pos <= 147; pos++)
+ {
+ map.put(pos, new int[] { pos - 50, 5 * (pos - 50) });
+ }
+ StructureMapping sm1 = new StructureMapping(seq1, "1a70.pdb", "1A70",
+ "A", map, null);
+ ssm.addStructureMapping(sm1);
+
+ /*
+ * map FER2_ARATH residues 53-148 to residues 2-97 in 4ZHO
+ */
+ map = new HashMap<>();
+ for (int pos = 53; pos <= 148; pos++)
+ {
+ map.put(pos, new int[] { pos - 51, 5 * (pos - 51) });
+ }
+ StructureMapping sm2 = new StructureMapping(seq2, "4zho.pdb", "4ZHO",
+ "B", map, null);
+ ssm.addStructureMapping(sm2);
+
+ /*
+ * select chain A only (hide chain B)
+ */
+ List<String> chainsToHide = (List<String>) PA.getValue(testee, "chainsToHide");
+ chainsToHide.add("1A70:B");
+ chainsToHide.add("4ZHO:C");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, "~display; ribbon; ~ribbon #0:.B; ~ribbon #1:.C");
+
+ /*
+ * show alignment only, no chains hidden
+ */
+ chainsToHide.clear();
+ testee.setShowAlignmentOnly(true);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd,
+ "~display; ~ribbon; ribbon #0:1-50.A,60-97.A|#1:2-97.B");
+
+ /*
+ * now with a chain hidden
+ */
+ chainsToHide.add("4ZHO:C");
+ cmd = testee.buildShowStructuresCommand(av, false);
+ String expected = "~display; ~ribbon; ribbon #0:1-50.A,60-97.A|#1:2-97.B; ~ribbon #1:.C";
+ assertEquals(cmd, expected);
+
+ /*
+ * hide columns in the mapped region - should not change the command (yet)
+ */
+ int fromCol = seq1.findIndex(60); // structure residue 10
+ int toCol = seq1.findIndex(70); // structure residue 20
+ av.hideColumns(fromCol - 1, toCol - 1);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, expected);
+
+ /*
+ * select 'hide hidden columns'
+ * command should now exclude these in both mapped sequences
+ */
+ testee.setHideHiddenRegions(true);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ expected = "~display; ~ribbon; ribbon #0:1-9.A,21-50.A,60-97.A|#1:2-10.B,22-97.B; ~ribbon #1:.C";
+ assertEquals(cmd, expected);
+
+ /*
+ * deselect 'show alignment only'
+ * hide hidden columns is now ignored
+ */
+ testee.setShowAlignmentOnly(false);
+ cmd = testee.buildShowStructuresCommand(av, false);
+ assertEquals(cmd, "~display; ribbon; ~ribbon #1:.C");
+ }
+}