import java.awt.Rectangle;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
/**
* proxy for handling structure viewers.
* @return
*/
public JalviewStructureDisplayI viewStructures(PDBEntry[] pdbs,
- SequenceI[][] seqsForPdbs, AlignmentPanel ap)
+ SequenceI[] seqsForPdbs, AlignmentPanel ap)
{
JalviewStructureDisplayI viewer = onlyOnePdb(pdbs, seqsForPdbs, ap);
if (viewer != null)
{
+ /*
+ * user added structure to an existing viewer - all done
+ */
return viewer;
}
- return viewStructures(getViewerType(), pdbs, seqsForPdbs, ap);
+
+ ViewerType viewerType = getViewerType();
+
+ // old way:
+ // PDBEntry[] pdbsForFile = getUniquePdbFiles(pdbs);
+
+ // new way:
+ Map<PDBEntry, SequenceI[]> seqsForPdb = getSequencesForPdbs(pdbs,
+ seqsForPdbs);
+ PDBEntry[] pdbsForFile = seqsForPdb.keySet().toArray(
+ new PDBEntry[seqsForPdb.size()]);
+ SequenceI[][] theSeqs = seqsForPdb.values().toArray(
+ new SequenceI[seqsForPdb.size()][]);
+ JalviewStructureDisplayI sview = null;
+ if (viewerType.equals(ViewerType.JMOL))
+ {
+ sview = new AppJmol(ap, pdbsForFile, theSeqs);
+ // ap.av.collateForPDB(pdbsForFile));
+ }
+ else if (viewerType.equals(ViewerType.CHIMERA))
+ {
+ sview = new ChimeraViewFrame(pdbsForFile, theSeqs, ap);
+ // ap.av.collateForPDB(pdbsForFile), ap);
+ }
+ else
+ {
+ Cache.log.error("Unknown structure viewer type "
+ + getViewerType().toString());
+ }
+ return sview;
}
/**
- * A strictly temporary method pending JAL-1761 refactoring. Determines if all
- * the passed PDB entries are the same (this is the case if selected sequences
- * to view structure for are chains of the same structure). If so, calls the
- * single-pdb version of viewStructures and returns the viewer, else returns
- * null.
+ * Converts the list of selected PDB entries (possibly including duplicates
+ * for multiple chains), and corresponding sequences, into a map of sequences
+ * for each distinct PDB file. Returns null if either argument is null, or
+ * their lengths do not match.
*
* @param pdbs
- * @param seqsForPdbs
- * @param ap
+ * @param seqs
* @return
*/
- private JalviewStructureDisplayI onlyOnePdb(PDBEntry[] pdbs,
- SequenceI[][] seqsForPdbs, AlignmentPanel ap)
+ static Map<PDBEntry, SequenceI[]> getSequencesForPdbs(PDBEntry[] pdbs,
+ SequenceI[] seqs)
{
- List<SequenceI> seqs = new ArrayList<SequenceI>();
- if (pdbs == null || pdbs.length == 0)
+ if (pdbs == null || seqs == null || pdbs.length != seqs.length)
{
return null;
}
- int i = 0;
- String firstFile = pdbs[0].getFile();
- for (PDBEntry pdb : pdbs)
+
+ /*
+ * we want only one 'representative' PDBEntry per distinct file name
+ * (there may be entries for distinct chains)
+ */
+ Map<String, PDBEntry> pdbsSeen = new HashMap<>();
+
+ /*
+ * LinkedHashMap preserves order of PDB entries (significant if they
+ * will get superimposed to the first structure)
+ */
+ Map<PDBEntry, List<SequenceI>> pdbSeqs = new LinkedHashMap<>();
+ for (int i = 0; i < pdbs.length; i++)
{
+ PDBEntry pdb = pdbs[i];
+ SequenceI seq = seqs[i];
String pdbFile = pdb.getFile();
- if (pdbFile == null || !pdbFile.equals(firstFile))
+ if (!pdbsSeen.containsKey(pdbFile))
{
- return null;
+ pdbsSeen.put(pdbFile, pdb);
+ pdbSeqs.put(pdb, new ArrayList<SequenceI>());
}
- SequenceI[] pdbseqs = seqsForPdbs[i++];
- if (pdbseqs != null)
+ else
{
- for (SequenceI sq : pdbseqs)
- {
- seqs.add(sq);
- }
+ pdb = pdbsSeen.get(pdbFile);
+ }
+ List<SequenceI> seqsForPdb = pdbSeqs.get(pdb);
+ if (!seqsForPdb.contains(seq))
+ {
+ seqsForPdb.add(seq);
}
}
- return viewStructures(pdbs[0], seqs.toArray(new SequenceI[seqs.size()]),
- ap);
- }
- public JalviewStructureDisplayI viewStructures(PDBEntry pdb,
- SequenceI[] seqsForPdb, AlignmentPanel ap)
- {
- return viewStructures(getViewerType(), pdb, seqsForPdb, ap);
- }
-
- protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
- PDBEntry[] pdbs, SequenceI[][] seqsForPdbs, AlignmentPanel ap)
- {
- PDBEntry[] pdbsForFile = getUniquePdbFiles(pdbs);
- JalviewStructureDisplayI sview = null;
- if (viewerType.equals(ViewerType.JMOL))
+ /*
+ * convert to Map<PDBEntry, SequenceI[]>
+ */
+ Map<PDBEntry, SequenceI[]> result = new LinkedHashMap<>();
+ for (Entry<PDBEntry, List<SequenceI>> entry : pdbSeqs.entrySet())
{
- sview = new AppJmol(ap, pdbsForFile,
- ap.av.collateForPDB(pdbsForFile));
+ List<SequenceI> theSeqs = entry.getValue();
+ result.put(entry.getKey(),
+ theSeqs.toArray(new SequenceI[theSeqs.size()]));
}
- else if (viewerType.equals(ViewerType.CHIMERA))
- {
- sview = new ChimeraViewFrame(pdbsForFile,
- ap.av.collateForPDB(pdbsForFile), ap);
- }
- else
- {
- Cache.log.error("Unknown structure viewer type "
- + getViewerType().toString());
- }
- return sview;
+
+ return result;
}
/**
- * Convert the array of PDBEntry into an array with no filename repeated
+ * A strictly temporary method pending JAL-1761 refactoring. Determines if all
+ * the passed PDB entries are the same (this is the case if selected sequences
+ * to view structure for are chains of the same structure). If so, calls the
+ * single-pdb version of viewStructures and returns the viewer, else returns
+ * null.
*
* @param pdbs
+ * @param seqsForPdbs
+ * @param ap
* @return
*/
- static PDBEntry[] getUniquePdbFiles(PDBEntry[] pdbs)
+ private JalviewStructureDisplayI onlyOnePdb(PDBEntry[] pdbs,
+ SequenceI[] seqsForPdbs, AlignmentPanel ap)
{
- if (pdbs == null)
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
+ if (pdbs == null || pdbs.length == 0)
{
return null;
}
- List<PDBEntry> uniques = new ArrayList<PDBEntry>();
- List<String> filesSeen = new ArrayList<String>();
- for (PDBEntry entry : pdbs)
+ int i = 0;
+ String firstFile = pdbs[0].getFile();
+ for (PDBEntry pdb : pdbs)
{
- String file = entry.getFile();
- if (file == null)
+ String pdbFile = pdb.getFile();
+ if (pdbFile == null || !pdbFile.equals(firstFile))
{
- uniques.add(entry);
+ return null;
}
- else if (!filesSeen.contains(file))
+ SequenceI pdbseq = seqsForPdbs[i++];
+ if (pdbseq != null)
{
- uniques.add(entry);
- filesSeen.add(file);
+ seqs.add(pdbseq);
}
}
- return uniques.toArray(new PDBEntry[uniques.size()]);
+ return viewStructures(pdbs[0], seqs.toArray(new SequenceI[seqs.size()]),
+ ap);
}
- protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
- PDBEntry pdb, SequenceI[] seqsForPdb, AlignmentPanel ap)
+ public JalviewStructureDisplayI viewStructures(PDBEntry pdb,
+ SequenceI[] seqsForPdb, AlignmentPanel ap)
{
+ ViewerType viewerType = getViewerType();
JalviewStructureDisplayI sview = null;
if (viewerType.equals(ViewerType.JMOL))
{