Merge branch 'features/JAL-3417_sdppred_calcs' into features/r2_11_2_JAL-3417_sdppred
[jalview.git] / src / jalview / workers / AnnotationWorker.java
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.workers;
22
23 import jalview.api.AlignViewportI;
24 import jalview.api.AlignmentViewPanel;
25 import jalview.datamodel.AlignmentAnnotation;
26 import jalview.datamodel.AlignmentI;
27 import jalview.renderer.seqfeatures.FeatureRenderer;
28
29 import java.util.ArrayList;
30 import java.util.List;
31
32 /**
33  * A class to create and update one or more alignment annotations, given a
34  * 'calculator'. Intended to support a 'plug-in' annotation worker which
35  * implements the AnnotationProviderI interface.
36  */
37 class AnnotationWorker extends AlignCalcWorker
38 {
39   /*
40    * the provider of the annotation calculations
41    */
42   AnnotationProviderI counter;
43
44   /**
45    * Constructor
46    * 
47    * @param af
48    * @param counter
49    */
50   public AnnotationWorker(AlignViewportI viewport, AlignmentViewPanel panel,
51           AnnotationProviderI counter)
52   {
53     super(viewport, panel);
54     ourAnnots = new ArrayList<>();
55     this.counter = counter;
56     calcMan.registerWorker(this);
57   }
58
59   @Override
60   public void run()
61   {
62     try
63     {
64       calcMan.notifyStart(this);
65
66       while (!calcMan.notifyWorking(this))
67       {
68         try
69         {
70           Thread.sleep(200);
71         } catch (InterruptedException ex)
72         {
73           ex.printStackTrace();
74         }
75       }
76       if (alignViewport.isClosed())
77       {
78         abortAndDestroy();
79         return;
80       }
81
82       // removeAnnotation();
83       AlignmentI alignment = alignViewport.getAlignment();
84       if (alignment != null)
85       {
86         try
87         {
88           List<AlignmentAnnotation> anns = counter.calculateAnnotation(
89                   alignment, new FeatureRenderer(alignViewport));
90           for (AlignmentAnnotation ann : anns)
91           {
92             AlignmentAnnotation theAnn = alignment.findOrCreateAnnotation(
93                     ann.label, ann.getCalcId(), ann.autoCalculated,
94                     ann.sequenceRef,
95                     ann.groupRef);
96             theAnn.showAllColLabels = true;
97             theAnn.graph = AlignmentAnnotation.BAR_GRAPH;
98             theAnn.scaleColLabel = true;
99             theAnn.annotations = ann.annotations;
100             setGraphMinMax(theAnn, theAnn.annotations);
101             theAnn.validateRangeAndDisplay();
102             if (!ourAnnots.contains(theAnn))
103             {
104               ourAnnots.add(theAnn);
105             }
106             // alignment.addAnnotation(ann);
107           }
108         } catch (IndexOutOfBoundsException x)
109         {
110           // probable race condition. just finish and return without any fuss.
111           return;
112         }
113       }
114     } catch (OutOfMemoryError error)
115     {
116       ap.raiseOOMWarning("calculating annotations", error);
117       calcMan.disableWorker(this);
118     } finally
119     {
120       calcMan.workerComplete(this);
121     }
122
123     if (ap != null)
124     {
125       ap.adjustAnnotationHeight();
126       // TODO: only need to update colour and geometry if panel height changes
127       // and view is coloured by annotation, and the annotation is actually
128       // changed!
129       ap.paintAlignment(true, true);
130     }
131   }
132
133   @Override
134   public void updateAnnotation()
135   {
136     // do nothing
137   }
138
139   /**
140    * Answers true to indicate that if this worker's annotation is deleted from
141    * the display, the worker should also be removed. This prevents it running
142    * and recreating the annotation when the alignment changes.
143    */
144   @Override
145   public boolean isDeletable()
146   {
147     return true;
148   }
149 }