Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.gui

File StructureViewer.java

 

Coverage histogram

../../img/srcFileCovDistChart5.png
40% of files have more coverage

Code metrics

44
104
15
2
391
256
44
0.42
6.93
7.5
2.93

Classes

Class Line # Actions
StructureViewer 46 104 44 86
0.4723926547.2%
StructureViewer.ViewerType 57 0 0 0
-1.0 -
 

Contributing tests

This file is covered by 5 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.gui;
22   
23    import jalview.api.structures.JalviewStructureDisplayI;
24    import jalview.bin.Cache;
25    import jalview.datamodel.PDBEntry;
26    import jalview.datamodel.SequenceI;
27    import jalview.datamodel.StructureViewerModel;
28    import jalview.structure.StructureSelectionManager;
29   
30    import java.awt.Rectangle;
31    import java.util.ArrayList;
32    import java.util.HashMap;
33    import java.util.LinkedHashMap;
34    import java.util.List;
35    import java.util.Map;
36    import java.util.Map.Entry;
37   
38    /**
39    * A proxy for handling structure viewers, that orchestrates adding selected
40    * structures, associated with sequences in Jalview, to an existing viewer, or
41    * opening a new one. Currently supports either Jmol or Chimera as the structure
42    * viewer.
43    *
44    * @author jprocter
45    */
 
46    public class StructureViewer
47    {
48    private static final String UNKNOWN_VIEWER_TYPE = "Unknown structure viewer type ";
49   
50    StructureSelectionManager ssm;
51   
52    /**
53    * decide if new structures are aligned to existing ones
54    */
55    private boolean superposeAdded = true;
56   
 
57    public enum ViewerType
58    {
59    JMOL, CHIMERA
60    };
61   
62    /**
63    * Constructor
64    *
65    * @param structureSelectionManager
66    */
 
67  12 toggle public StructureViewer(StructureSelectionManager structureSelectionManager)
68    {
69  12 ssm = structureSelectionManager;
70    }
71   
72    /**
73    * Factory to create a proxy for modifying existing structure viewer
74    *
75    */
 
76  1 toggle public static StructureViewer reconfigure(
77    JalviewStructureDisplayI display)
78    {
79  1 StructureViewer sv = new StructureViewer(display.getBinding().getSsm());
80  1 sv.sview = display;
81  1 return sv;
82    }
83   
 
84  0 toggle @Override
85    public String toString()
86    {
87  0 if (sview != null)
88    {
89  0 return sview.toString();
90    }
91  0 return "New View";
92    }
 
93  2 toggle public ViewerType getViewerType()
94    {
95  2 String viewType = Cache.getDefault(Preferences.STRUCTURE_DISPLAY,
96    ViewerType.JMOL.name());
97  2 return ViewerType.valueOf(viewType);
98    }
99   
 
100  2 toggle public void setViewerType(ViewerType type)
101    {
102  2 Cache.setProperty(Preferences.STRUCTURE_DISPLAY, type.name());
103    }
104   
105    /**
106    * View multiple PDB entries, each with associated sequences
107    *
108    * @param pdbs
109    * @param seqs
110    * @param ap
111    * @return
112    */
 
113  0 toggle public JalviewStructureDisplayI viewStructures(PDBEntry[] pdbs,
114    SequenceI[] seqs, AlignmentPanel ap)
115    {
116  0 JalviewStructureDisplayI viewer = onlyOnePdb(pdbs, seqs, ap);
117  0 if (viewer != null)
118    {
119    /*
120    * user added structure to an existing viewer - all done
121    */
122  0 return viewer;
123    }
124   
125  0 ViewerType viewerType = getViewerType();
126   
127  0 Map<PDBEntry, SequenceI[]> seqsForPdbs = getSequencesForPdbs(pdbs,
128    seqs);
129  0 PDBEntry[] pdbsForFile = seqsForPdbs.keySet().toArray(
130    new PDBEntry[seqsForPdbs.size()]);
131  0 SequenceI[][] theSeqs = seqsForPdbs.values().toArray(
132    new SequenceI[seqsForPdbs.size()][]);
133  0 if (sview != null)
134    {
135  0 sview.setAlignAddedStructures(superposeAdded);
136  0 new Thread(new Runnable()
137    {
 
138  0 toggle @Override
139    public void run()
140    {
141   
142  0 for (int pdbep = 0; pdbep < pdbsForFile.length; pdbep++)
143    {
144  0 PDBEntry pdb = pdbsForFile[pdbep];
145  0 if (!sview.addAlreadyLoadedFile(theSeqs[pdbep], null, ap,
146    pdb.getId()))
147    {
148  0 sview.addToExistingViewer(pdb, theSeqs[pdbep], null, ap,
149    pdb.getId());
150    }
151    }
152   
153  0 sview.updateTitleAndMenus();
154    }
155    }).start();
156  0 return sview;
157    }
158   
159  0 if (viewerType.equals(ViewerType.JMOL))
160    {
161  0 sview = new AppJmol(ap, superposeAdded, pdbsForFile, theSeqs);
162    }
163  0 else if (viewerType.equals(ViewerType.CHIMERA))
164    {
165  0 sview = new ChimeraViewFrame(pdbsForFile, superposeAdded, theSeqs,
166    ap);
167    }
168    else
169    {
170  0 Cache.log.error(UNKNOWN_VIEWER_TYPE + getViewerType().toString());
171    }
172  0 return sview;
173    }
174   
175    /**
176    * Converts the list of selected PDB entries (possibly including duplicates
177    * for multiple chains), and corresponding sequences, into a map of sequences
178    * for each distinct PDB file. Returns null if either argument is null, or
179    * their lengths do not match.
180    *
181    * @param pdbs
182    * @param seqs
183    * @return
184    */
 
185  2 toggle Map<PDBEntry, SequenceI[]> getSequencesForPdbs(PDBEntry[] pdbs,
186    SequenceI[] seqs)
187    {
188  2 if (pdbs == null || seqs == null || pdbs.length != seqs.length)
189    {
190  1 return null;
191    }
192   
193    /*
194    * we want only one 'representative' PDBEntry per distinct file name
195    * (there may be entries for distinct chains)
196    */
197  1 Map<String, PDBEntry> pdbsSeen = new HashMap<>();
198   
199    /*
200    * LinkedHashMap preserves order of PDB entries (significant if they
201    * will get superimposed to the first structure)
202    */
203  1 Map<PDBEntry, List<SequenceI>> pdbSeqs = new LinkedHashMap<>();
204  8 for (int i = 0; i < pdbs.length; i++)
205    {
206  7 PDBEntry pdb = pdbs[i];
207  7 SequenceI seq = seqs[i];
208  7 String pdbFile = pdb.getFile();
209  7 if (pdbFile == null || pdbFile.length() == 0)
210    {
211  3 pdbFile = pdb.getId();
212    }
213  7 if (!pdbsSeen.containsKey(pdbFile))
214    {
215  4 pdbsSeen.put(pdbFile, pdb);
216  4 pdbSeqs.put(pdb, new ArrayList<SequenceI>());
217    }
218    else
219    {
220  3 pdb = pdbsSeen.get(pdbFile);
221    }
222  7 List<SequenceI> seqsForPdb = pdbSeqs.get(pdb);
223  7 if (!seqsForPdb.contains(seq))
224    {
225  7 seqsForPdb.add(seq);
226    }
227    }
228   
229    /*
230    * convert to Map<PDBEntry, SequenceI[]>
231    */
232  1 Map<PDBEntry, SequenceI[]> result = new LinkedHashMap<>();
233  1 for (Entry<PDBEntry, List<SequenceI>> entry : pdbSeqs.entrySet())
234    {
235  4 List<SequenceI> theSeqs = entry.getValue();
236  4 result.put(entry.getKey(),
237    theSeqs.toArray(new SequenceI[theSeqs.size()]));
238    }
239   
240  1 return result;
241    }
242   
243    /**
244    * A strictly temporary method pending JAL-1761 refactoring. Determines if all
245    * the passed PDB entries are the same (this is the case if selected sequences
246    * to view structure for are chains of the same structure). If so, calls the
247    * single-pdb version of viewStructures and returns the viewer, else returns
248    * null.
249    *
250    * @param pdbs
251    * @param seqsForPdbs
252    * @param ap
253    * @return
254    */
 
255  0 toggle private JalviewStructureDisplayI onlyOnePdb(PDBEntry[] pdbs,
256    SequenceI[] seqsForPdbs, AlignmentPanel ap)
257    {
258  0 List<SequenceI> seqs = new ArrayList<>();
259  0 if (pdbs == null || pdbs.length == 0)
260    {
261  0 return null;
262    }
263  0 int i = 0;
264  0 String firstFile = pdbs[0].getFile();
265  0 for (PDBEntry pdb : pdbs)
266    {
267  0 String pdbFile = pdb.getFile();
268  0 if (pdbFile == null || !pdbFile.equals(firstFile))
269    {
270  0 return null;
271    }
272  0 SequenceI pdbseq = seqsForPdbs[i++];
273  0 if (pdbseq != null)
274    {
275  0 seqs.add(pdbseq);
276    }
277    }
278  0 return viewStructures(pdbs[0], seqs.toArray(new SequenceI[seqs.size()]),
279    ap);
280    }
281   
282    JalviewStructureDisplayI sview = null;
283   
 
284  3 toggle public JalviewStructureDisplayI viewStructures(PDBEntry pdb,
285    SequenceI[] seqsForPdb, AlignmentPanel ap)
286    {
287  3 if (sview != null)
288    {
289  1 sview.setAlignAddedStructures(superposeAdded);
290  1 String pdbId = pdb.getId();
291  1 if (!sview.addAlreadyLoadedFile(seqsForPdb, null, ap, pdbId))
292    {
293  1 sview.addToExistingViewer(pdb, seqsForPdb, null, ap, pdbId);
294    }
295  1 sview.updateTitleAndMenus();
296  1 sview.raiseViewer();
297  1 return sview;
298    }
299  2 ViewerType viewerType = getViewerType();
300  2 if (viewerType.equals(ViewerType.JMOL))
301    {
302  2 sview = new AppJmol(pdb, seqsForPdb, null, ap);
303    }
304  0 else if (viewerType.equals(ViewerType.CHIMERA))
305    {
306  0 sview = new ChimeraViewFrame(pdb, seqsForPdb, null, ap);
307    }
308    else
309    {
310  0 Cache.log.error(UNKNOWN_VIEWER_TYPE + getViewerType().toString());
311    }
312  2 return sview;
313    }
314   
315    /**
316    * Create a new panel controlling a structure viewer.
317    *
318    * @param type
319    * @param pdbf
320    * @param id
321    * @param sq
322    * @param alignPanel
323    * @param viewerData
324    * @param fileloc
325    * @param rect
326    * @param vid
327    * @return
328    */
 
329  8 toggle public JalviewStructureDisplayI createView(ViewerType type, String[] pdbf,
330    String[] id, SequenceI[][] sq, AlignmentPanel alignPanel,
331    StructureViewerModel viewerData, String fileloc, Rectangle rect,
332    String vid)
333    {
334  8 final boolean useinViewerSuperpos = viewerData.isAlignWithPanel();
335  8 final boolean usetoColourbyseq = viewerData.isColourWithAlignPanel();
336  8 final boolean viewerColouring = viewerData.isColourByViewer();
337   
338  8 switch (type)
339    {
340  8 case JMOL:
341  8 sview = new AppJmol(pdbf, id, sq, alignPanel, usetoColourbyseq,
342    useinViewerSuperpos, viewerColouring, fileloc, rect, vid);
343  8 break;
344  0 case CHIMERA:
345  0 Cache.log.error(
346    "Unsupported structure viewer type " + type.toString());
347  0 break;
348  0 default:
349  0 Cache.log.error(UNKNOWN_VIEWER_TYPE + type.toString());
350    }
351  8 return sview;
352    }
353   
 
354  3 toggle public boolean isBusy()
355    {
356  3 if (sview != null)
357    {
358  3 if (!sview.hasMapping())
359    {
360  2 return true;
361    }
362    }
363  1 return false;
364    }
365   
366    /**
367    *
368    * @param pDBid
369    * @return true if view is already showing PDBid
370    */
 
371  0 toggle public boolean hasPdbId(String pDBid)
372    {
373  0 if (sview == null)
374    {
375  0 return false;
376    }
377   
378  0 return sview.getBinding().hasPdbId(pDBid);
379    }
380   
 
381  0 toggle public boolean isVisible()
382    {
383  0 return sview != null && sview.isVisible();
384    }
385   
 
386  0 toggle public void setSuperpose(boolean alignAddedStructures)
387    {
388  0 superposeAdded = alignAddedStructures;
389    }
390   
391    }