+
+ ViewerType viewerType = getViewerType();
+
+ Map<PDBEntry, SequenceI[]> seqsForPdbs = getSequencesForPdbs(pdbs,
+ seqs);
+ PDBEntry[] pdbsForFile = seqsForPdbs.keySet().toArray(
+ new PDBEntry[seqsForPdbs.size()]);
+ SequenceI[][] theSeqs = seqsForPdbs.values().toArray(
+ new SequenceI[seqsForPdbs.size()][]);
+ if (sview != null)
+ {
+ sview.setAlignAddedStructures(superposeAdded);
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+
+ for (int pdbep = 0; pdbep < pdbsForFile.length; pdbep++)
+ {
+ PDBEntry pdb = pdbsForFile[pdbep];
+ if (!sview.addAlreadyLoadedFile(theSeqs[pdbep], null, ap,
+ pdb.getId()))
+ {
+ sview.addToExistingViewer(pdb, theSeqs[pdbep], null, ap,
+ pdb.getId());
+ }
+ }
+
+ sview.updateTitleAndMenus();
+ }
+ }).start();
+ return sview;
+ }
+
+ if (viewerType.equals(ViewerType.JMOL))
+ {
+ sview = new AppJmol(ap, superposeAdded, pdbsForFile, theSeqs);
+ }
+ else if (viewerType.equals(ViewerType.CHIMERA))
+ {
+ sview = new ChimeraViewFrame(pdbsForFile, superposeAdded, theSeqs,
+ ap);
+ }
+ else if (viewerType.equals(ViewerType.CHIMERAX))
+ {
+ sview = new ChimeraXViewFrame(pdbsForFile, superposeAdded, theSeqs,
+ ap);
+ }
+ else if (viewerType.equals(ViewerType.PYMOL))
+ {
+ sview = new PymolViewer(pdbsForFile, superposeAdded, theSeqs, ap);
+ }
+ else
+ {
+ Cache.log.error(UNKNOWN_VIEWER_TYPE + getViewerType().toString());
+ }
+ return sview;
+ }
+
+ /**
+ * 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 seqs
+ * @return
+ */
+ Map<PDBEntry, SequenceI[]> getSequencesForPdbs(PDBEntry[] pdbs,
+ SequenceI[] seqs)
+ {
+ if (pdbs == null || seqs == null || pdbs.length != seqs.length)
+ {
+ return null;
+ }
+
+ /*
+ * 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.length() == 0)
+ {
+ pdbFile = pdb.getId();
+ }
+ if (!pdbsSeen.containsKey(pdbFile))
+ {
+ pdbsSeen.put(pdbFile, pdb);
+ pdbSeqs.put(pdb, new ArrayList<SequenceI>());
+ }
+ else
+ {
+ pdb = pdbsSeen.get(pdbFile);
+ }
+ List<SequenceI> seqsForPdb = pdbSeqs.get(pdb);
+ if (!seqsForPdb.contains(seq))
+ {
+ seqsForPdb.add(seq);
+ }
+ }
+
+ /*
+ * convert to Map<PDBEntry, SequenceI[]>
+ */
+ Map<PDBEntry, SequenceI[]> result = new LinkedHashMap<>();
+ for (Entry<PDBEntry, List<SequenceI>> entry : pdbSeqs.entrySet())
+ {
+ List<SequenceI> theSeqs = entry.getValue();
+ result.put(entry.getKey(),
+ theSeqs.toArray(new SequenceI[theSeqs.size()]));
+ }
+
+ return result;