04f7440dcf4b8225314e7412deb243887d29c3f4
[jalview.git] / src / jalview / workers / ConsensusThread.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 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.analysis.AAFrequency;
24 import jalview.api.AlignCalcWorkerI;
25 import jalview.api.AlignViewportI;
26 import jalview.api.AlignmentViewPanel;
27 import jalview.datamodel.AlignmentAnnotation;
28 import jalview.datamodel.AlignmentI;
29 import jalview.datamodel.Annotation;
30 import jalview.datamodel.SequenceI;
31 import jalview.schemes.ColourSchemeI;
32
33 import java.util.Hashtable;
34
35 public class ConsensusThread extends AlignCalcWorker implements
36         AlignCalcWorkerI
37 {
38   private long nseq=-1;
39
40   public ConsensusThread(AlignViewportI alignViewport,
41           AlignmentViewPanel alignPanel)
42   {
43     super(alignViewport, alignPanel);
44   }
45
46   @Override
47   public void run()
48   {
49     if (calcMan.isPending(this))
50     {
51       return;
52     }
53     calcMan.notifyStart(this);
54     long started = System.currentTimeMillis();
55     try
56     {
57       AlignmentAnnotation consensus = alignViewport
58               .getAlignmentConsensusAnnotation();
59       if (consensus == null || calcMan.isPending(this))
60       {
61         calcMan.workerComplete(this);
62         return;
63       }
64       while (!calcMan.notifyWorking(this))
65       {
66         // System.err.println("Thread (Consensus"+Thread.currentThread().getName()+") Waiting around.");
67         try
68         {
69           if (ap != null)
70           {
71             ap.paintAlignment(false);
72           }
73           Thread.sleep(200);
74         } catch (Exception ex)
75         {
76           ex.printStackTrace();
77         }
78       }
79       if (alignViewport.isClosed())
80       {
81         abortAndDestroy();
82       }
83       AlignmentI alignment = alignViewport.getAlignment();
84
85       int aWidth = -1;
86
87       if (alignment == null || (aWidth = alignment.getWidth()) < 0)
88       {
89         calcMan.workerComplete(this);
90         // .updatingConservation = false;
91         // AlignViewport.UPDATING_CONSERVATION = false;
92
93         return;
94       }
95       consensus = alignViewport.getAlignmentConsensusAnnotation();
96
97       consensus.annotations = null;
98       consensus.annotations = new Annotation[aWidth];
99       Hashtable[] hconsensus = alignViewport.getSequenceConsensusHash();
100       hconsensus = new Hashtable[aWidth];
101       try
102       {
103         SequenceI aseqs[] = alignment.getSequencesArray();
104         nseq = aseqs.length;
105         AAFrequency.calculate(aseqs, 0,
106                 alignment.getWidth(), hconsensus, true);
107       } catch (ArrayIndexOutOfBoundsException x)
108       {
109         // this happens due to a race condition -
110         // alignment was edited at same time as calculation was running
111         //
112         // calcMan.workerCannotRun(this);
113         calcMan.workerComplete(this);
114         return;
115       }
116       alignViewport.setSequenceConsensusHash(hconsensus);
117       updateResultAnnotation(true);
118       ColourSchemeI globalColourScheme = alignViewport
119               .getGlobalColourScheme();
120       if (globalColourScheme != null)
121       {
122         globalColourScheme.setConsensus(hconsensus);
123       }
124
125     } catch (OutOfMemoryError error)
126     {
127       calcMan.workerCannotRun(this);
128
129       // consensus = null;
130       // hconsensus = null;
131       ap.raiseOOMWarning("calculating consensus", error);
132     }
133
134     calcMan.workerComplete(this);
135     if (ap != null)
136     {
137       ap.paintAlignment(true);
138     }
139   }
140
141   /**
142    * update the consensus annotation from the sequence profile data using
143    * current visualization settings.
144    */
145   @Override
146   public void updateAnnotation()
147   {
148     updateResultAnnotation(false);
149   }
150
151   public void updateResultAnnotation(boolean immediate)
152   {
153     AlignmentAnnotation consensus = alignViewport
154             .getAlignmentConsensusAnnotation();
155     Hashtable[] hconsensus = alignViewport.getSequenceConsensusHash();
156     if (immediate || !calcMan.isWorking(this) && consensus != null
157             && hconsensus != null)
158     {
159       AAFrequency.completeConsensus(consensus, hconsensus, 0,
160               hconsensus.length, alignViewport.getIgnoreGapsConsensus(),
161               alignViewport.isShowSequenceLogo(), nseq);
162     }
163   }
164 }