Clover icon

jalviewX

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

File AlignViewController.java

 

Coverage histogram

../../img/srcFileCovDistChart6.png
35% of files have more coverage

Code metrics

82
144
13
1
448
355
65
0.45
11.08
13
5

Classes

Class Line # Actions
AlignViewController 44 144 65 117
0.5104602651%
 

Contributing tests

This file is covered by 73 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.controller;
22   
23    import jalview.analysis.AlignmentSorter;
24    import jalview.api.AlignViewControllerGuiI;
25    import jalview.api.AlignViewControllerI;
26    import jalview.api.AlignViewportI;
27    import jalview.api.AlignmentViewPanel;
28    import jalview.api.FeatureRenderer;
29    import jalview.commands.OrderCommand;
30    import jalview.datamodel.AlignmentI;
31    import jalview.datamodel.ColumnSelection;
32    import jalview.datamodel.SequenceCollectionI;
33    import jalview.datamodel.SequenceFeature;
34    import jalview.datamodel.SequenceGroup;
35    import jalview.datamodel.SequenceI;
36    import jalview.io.DataSourceType;
37    import jalview.io.FeaturesFile;
38    import jalview.util.MessageManager;
39   
40    import java.awt.Color;
41    import java.util.BitSet;
42    import java.util.List;
43   
 
44    public class AlignViewController implements AlignViewControllerI
45    {
46    AlignViewportI viewport = null;
47   
48    AlignmentViewPanel alignPanel = null;
49   
50    /**
51    * the GUI container that is handling interactions with the user
52    */
53    private AlignViewControllerGuiI avcg;
54   
 
55  435 toggle public AlignViewController(AlignViewControllerGuiI alignFrame,
56    AlignViewportI vp, AlignmentViewPanel ap)
57    {
58  435 this.avcg = alignFrame;
59  435 this.viewport = vp;
60  435 this.alignPanel = ap;
61    }
62   
 
63  91 toggle @Override
64    public void setViewportAndAlignmentPanel(AlignViewportI vp,
65    AlignmentViewPanel ap)
66    {
67  91 this.alignPanel = ap;
68  91 this.viewport = vp;
69    }
70   
 
71  0 toggle @Override
72    public boolean makeGroupsFromSelection()
73    {
74  0 SequenceGroup sg = viewport.getSelectionGroup();
75  0 ColumnSelection cs = viewport.getColumnSelection();
76  0 SequenceGroup[] gps = null;
77  0 if (sg != null && (cs == null || cs.isEmpty()))
78    {
79  0 gps = jalview.analysis.Grouping.makeGroupsFrom(
80    viewport.getSequenceSelection(),
81    viewport.getAlignmentView(true)
82    .getSequenceStrings(viewport.getGapCharacter()),
83    viewport.getAlignment().getGroups());
84    }
85    else
86    {
87  0 if (cs != null)
88    {
89  0 gps = jalview.analysis.Grouping.makeGroupsFromCols(
90  0 (sg == null) ? viewport.getAlignment().getSequencesArray()
91    : sg.getSequences().toArray(new SequenceI[0]),
92    cs, viewport.getAlignment().getGroups());
93    }
94    }
95  0 if (gps != null)
96    {
97  0 viewport.getAlignment().deleteAllGroups();
98  0 viewport.clearSequenceColours();
99  0 viewport.setSelectionGroup(null);
100    // set view properties for each group
101  0 for (int g = 0; g < gps.length; g++)
102    {
103    // gps[g].setShowunconserved(viewport.getShowUnconserved());
104  0 gps[g].setshowSequenceLogo(viewport.isShowSequenceLogo());
105  0 viewport.getAlignment().addGroup(gps[g]);
106  0 Color col = new Color((int) (Math.random() * 255),
107    (int) (Math.random() * 255), (int) (Math.random() * 255));
108  0 col = col.brighter();
109  0 for (SequenceI sq : gps[g].getSequences(null))
110    {
111  0 viewport.setSequenceColour(sq, col);
112    }
113    }
114  0 return true;
115    }
116  0 return false;
117    }
118   
 
119  0 toggle @Override
120    public boolean createGroup()
121    {
122   
123  0 SequenceGroup sg = viewport.getSelectionGroup();
124  0 if (sg != null)
125    {
126  0 viewport.getAlignment().addGroup(sg);
127  0 return true;
128    }
129  0 return false;
130    }
131   
 
132  0 toggle @Override
133    public boolean unGroup()
134    {
135  0 SequenceGroup sg = viewport.getSelectionGroup();
136  0 if (sg != null)
137    {
138  0 viewport.getAlignment().deleteGroup(sg);
139  0 return true;
140    }
141  0 return false;
142    }
143   
 
144  0 toggle @Override
145    public boolean deleteGroups()
146    {
147  0 if (viewport.getAlignment().getGroups() != null
148    && viewport.getAlignment().getGroups().size() > 0)
149    {
150  0 viewport.getAlignment().deleteAllGroups();
151  0 viewport.clearSequenceColours();
152  0 viewport.setSelectionGroup(null);
153  0 return true;
154    }
155  0 return false;
156    }
157   
 
158  8 toggle @Override
159    public boolean markColumnsContainingFeatures(boolean invert,
160    boolean extendCurrent, boolean toggle, String featureType)
161    {
162    // JBPNote this routine could also mark rows, not just columns.
163    // need a decent query structure to allow all types of feature searches
164  8 BitSet bs = new BitSet();
165  8 SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null
166    || extendCurrent) ? viewport.getAlignment()
167    : viewport.getSelectionGroup();
168   
169  8 int nseq = findColumnsWithFeature(featureType, sqcol, bs);
170   
171  8 ColumnSelection cs = viewport.getColumnSelection();
172  8 if (cs == null)
173    {
174  0 cs = new ColumnSelection();
175    }
176   
177  8 if (bs.cardinality() > 0 || invert)
178    {
179  6 boolean changed = cs.markColumns(bs, sqcol.getStartRes(),
180    sqcol.getEndRes(), invert, extendCurrent, toggle);
181  6 if (changed)
182    {
183  5 viewport.setColumnSelection(cs);
184  5 alignPanel.paintAlignment(false, false);
185  5 int columnCount = invert
186    ? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
187    - bs.cardinality()
188    : bs.cardinality();
189  5 avcg.setStatus(MessageManager.formatMessage(
190    "label.view_controller_toggled_marked", new String[]
191  5 { toggle ? MessageManager.getString("label.toggled")
192    : MessageManager.getString("label.marked"),
193    String.valueOf(columnCount),
194  5 invert ? MessageManager
195    .getString("label.not_containing")
196    : MessageManager.getString("label.containing"),
197    featureType, Integer.valueOf(nseq).toString() }));
198  5 return true;
199    }
200    }
201    else
202    {
203  2 avcg.setStatus(MessageManager
204    .formatMessage("label.no_feature_of_type_found", new String[]
205    { featureType }));
206  2 if (!extendCurrent)
207    {
208  2 cs.clear();
209  2 alignPanel.paintAlignment(false, false);
210    }
211    }
212  3 return false;
213    }
214   
215    /**
216    * Sets a bit in the BitSet for each column (base 0) in the sequence
217    * collection which includes a visible feature of the specified feature type.
218    * Returns the number of sequences which have the feature visible in the
219    * selected range.
220    *
221    * @param featureType
222    * @param sqcol
223    * @param bs
224    * @return
225    */
 
226  16 toggle int findColumnsWithFeature(String featureType,
227    SequenceCollectionI sqcol, BitSet bs)
228    {
229  16 FeatureRenderer fr = alignPanel == null ? null : alignPanel
230    .getFeatureRenderer();
231   
232  16 final int startColumn = sqcol.getStartRes() + 1; // converted to base 1
233  16 final int endColumn = sqcol.getEndRes() + 1;
234  16 List<SequenceI> seqs = sqcol.getSequences();
235  16 int nseq = 0;
236  16 for (SequenceI sq : seqs)
237    {
238  48 if (sq != null)
239    {
240    // int ist = sq.findPosition(sqcol.getStartRes());
241  48 List<SequenceFeature> sfs = sq.findFeatures(startColumn,
242    endColumn, featureType);
243   
244  48 boolean found = false;
245  48 for (SequenceFeature sf : sfs)
246    {
247  17 if (fr.getColour(sf) == null)
248    {
249  3 continue;
250    }
251  14 if (!found)
252    {
253  14 nseq++;
254    }
255  14 found = true;
256   
257  14 int sfStartCol = sq.findIndex(sf.getBegin());
258  14 int sfEndCol = sq.findIndex(sf.getEnd());
259   
260  14 if (sf.isContactFeature())
261    {
262    /*
263    * 'contact' feature - check for 'start' or 'end'
264    * position within the selected region
265    */
266  1 if (sfStartCol >= startColumn && sfStartCol <= endColumn)
267    {
268  1 bs.set(sfStartCol - 1);
269    }
270  1 if (sfEndCol >= startColumn && sfEndCol <= endColumn)
271    {
272  1 bs.set(sfEndCol - 1);
273    }
274  1 continue;
275    }
276   
277    /*
278    * contiguous feature - select feature positions (if any)
279    * within the selected region
280    */
281  13 if (sfStartCol < startColumn)
282    {
283  1 sfStartCol = startColumn;
284    }
285    // not sure what the point of this is
286    // if (sfStartCol < ist)
287    // {
288    // sfStartCol = ist;
289    // }
290  13 if (sfEndCol > endColumn)
291    {
292  4 sfEndCol = endColumn;
293    }
294  55 for (; sfStartCol <= sfEndCol; sfStartCol++)
295    {
296  42 bs.set(sfStartCol - 1); // convert to base 0
297    }
298    }
299    }
300    }
301  16 return nseq;
302    }
303   
 
304  0 toggle @Override
305    public void sortAlignmentByFeatureDensity(List<String> typ)
306    {
307  0 sortBy(typ, "Sort by Density", AlignmentSorter.FEATURE_DENSITY);
308    }
309   
 
310  0 toggle protected void sortBy(List<String> typ, String methodText,
311    final String method)
312    {
313  0 FeatureRenderer fr = alignPanel.getFeatureRenderer();
314  0 if (typ == null && fr != null)
315    {
316  0 typ = fr.getDisplayedFeatureTypes();
317    }
318  0 List<String> gps = null;
319  0 if (fr != null)
320    {
321  0 gps = fr.getDisplayedFeatureGroups();
322    }
323  0 AlignmentI al = viewport.getAlignment();
324   
325  0 int start, stop;
326  0 SequenceGroup sg = viewport.getSelectionGroup();
327  0 if (sg != null)
328    {
329  0 start = sg.getStartRes();
330  0 stop = sg.getEndRes();
331    }
332    else
333    {
334  0 start = 0;
335  0 stop = al.getWidth();
336    }
337  0 SequenceI[] oldOrder = al.getSequencesArray();
338  0 AlignmentSorter.sortByFeature(typ, gps, start, stop, al, method);
339  0 avcg.addHistoryItem(new OrderCommand(methodText, oldOrder,
340    viewport.getAlignment()));
341  0 alignPanel.paintAlignment(true, false);
342   
343    }
344   
 
345  0 toggle @Override
346    public void sortAlignmentByFeatureScore(List<String> typ)
347    {
348  0 sortBy(typ, "Sort by Feature Score", AlignmentSorter.FEATURE_SCORE);
349    }
350   
 
351  2 toggle @Override
352    public boolean parseFeaturesFile(Object file, DataSourceType protocol,
353    boolean relaxedIdMatching)
354    {
355  2 boolean featuresAdded = false;
356  2 FeatureRenderer fr = alignPanel.getFeatureRenderer();
357  2 try
358    {
359  2 featuresAdded = new FeaturesFile(false, file, protocol).parse(
360    viewport.getAlignment().getDataset(), fr.getFeatureColours(),
361    fr.getFeatureFilters(), false, relaxedIdMatching);
362    } catch (Exception ex)
363    {
364  0 ex.printStackTrace();
365    }
366   
367  2 if (featuresAdded)
368    {
369  2 avcg.refreshFeatureUI(true);
370  2 if (fr != null)
371    {
372    // update the min/max ranges where necessary
373  2 fr.findAllFeatures(true);
374    }
375  2 if (avcg.getFeatureSettingsUI() != null)
376    {
377  0 avcg.getFeatureSettingsUI().discoverAllFeatureData();
378    }
379  2 alignPanel.paintAlignment(true, true);
380    }
381   
382  2 return featuresAdded;
383   
384    }
385   
 
386  1 toggle @Override
387    public boolean markHighlightedColumns(boolean invert,
388    boolean extendCurrent, boolean toggle)
389    {
390  1 if (!viewport.hasSearchResults())
391    {
392    // do nothing if no selection exists
393  0 return false;
394    }
395    // JBPNote this routine could also mark rows, not just columns.
396  1 BitSet bs = new BitSet();
397  1 SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null
398    || extendCurrent) ? viewport.getAlignment()
399    : viewport.getSelectionGroup();
400   
401    // this could be a lambda... - the remains of the method is boilerplate,
402    // except for the different messages for reporting selection.
403  1 int nseq = viewport.getSearchResults().markColumns(sqcol, bs);
404   
405  1 ColumnSelection cs = viewport.getColumnSelection();
406  1 if (cs == null)
407    {
408  0 cs = new ColumnSelection();
409    }
410   
411  1 if (bs.cardinality() > 0 || invert)
412    {
413  1 boolean changed = cs.markColumns(bs, sqcol.getStartRes(),
414    sqcol.getEndRes(), invert, extendCurrent, toggle);
415  1 if (changed)
416    {
417  1 viewport.setColumnSelection(cs);
418  1 alignPanel.paintAlignment(false, false);
419  1 int columnCount = invert
420    ? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
421    - bs.cardinality()
422    : bs.cardinality();
423  1 avcg.setStatus(MessageManager.formatMessage(
424    "label.view_controller_toggled_marked", new String[]
425  1 { toggle ? MessageManager.getString("label.toggled")
426    : MessageManager.getString("label.marked"),
427    String.valueOf(columnCount),
428  1 invert ? MessageManager
429    .getString("label.not_containing")
430    : MessageManager.getString("label.containing"),
431    "Highlight", Integer.valueOf(nseq).toString() }));
432  1 return true;
433    }
434    }
435    else
436    {
437  0 avcg.setStatus(MessageManager
438    .formatMessage("No highlighted regions marked"));
439  0 if (!extendCurrent)
440    {
441  0 cs.clear();
442  0 alignPanel.paintAlignment(false, false);
443    }
444    }
445  0 return false;
446    }
447   
448    }