343e64d47e2ef5ae75ddf77e9b11f56371310f3b
[jalview.git] / src / jalview / workers / ConsensusThread.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.workers;
19
20 import jalview.analysis.AAFrequency;
21 import jalview.api.AlignCalcWorkerI;
22 import jalview.api.AlignViewportI;
23 import jalview.api.AlignmentViewPanel;
24 import jalview.datamodel.AlignmentAnnotation;
25 import jalview.datamodel.AlignmentI;
26 import jalview.datamodel.Annotation;
27 import jalview.schemes.ColourSchemeI;
28
29 import java.util.Hashtable;
30
31 public class ConsensusThread extends AlignCalcWorker implements
32         AlignCalcWorkerI
33 {
34   public ConsensusThread(AlignViewportI alignViewport,
35           AlignmentViewPanel alignPanel)
36   {
37     super(alignViewport, alignPanel);
38   }
39
40   @Override
41   public void run()
42   {
43     if (calcMan.isPending(this))
44     {
45       return;
46     }
47     calcMan.notifyStart(this);
48     long started = System.currentTimeMillis();
49     try
50     {
51       AlignmentAnnotation consensus = alignViewport
52               .getAlignmentConsensusAnnotation();
53       if (consensus == null || calcMan.isPending(this))
54       {
55         calcMan.workerComplete(this);
56         return;
57       }
58       while (!calcMan.notifyWorking(this))
59       {
60         // System.err.println("Thread (Consensus"+Thread.currentThread().getName()+") Waiting around.");
61         try
62         {
63           if (ap != null)
64           {
65             ap.paintAlignment(false);
66           }
67           Thread.sleep(200);
68         } catch (Exception ex)
69         {
70           ex.printStackTrace();
71         }
72       }
73       if (alignViewport.isClosed())
74       {
75         abortAndDestroy();
76       }
77       AlignmentI alignment = alignViewport.getAlignment();
78
79       int aWidth = -1;
80
81       if (alignment == null || (aWidth = alignment.getWidth()) < 0)
82       {
83         calcMan.workerComplete(this);
84         // .updatingConservation = false;
85         // AlignViewport.UPDATING_CONSERVATION = false;
86
87         return;
88       }
89       consensus = alignViewport.getAlignmentConsensusAnnotation();
90
91       consensus.annotations = null;
92       consensus.annotations = new Annotation[aWidth];
93       Hashtable[] hconsensus = alignViewport.getSequenceConsensusHash();
94       hconsensus = new Hashtable[aWidth];
95       try
96       {
97         AAFrequency.calculate(alignment.getSequencesArray(), 0,
98                 alignment.getWidth(), hconsensus, true);
99       } catch (ArrayIndexOutOfBoundsException x)
100       {
101         // this happens due to a race condition -
102         // alignment was edited at same time as calculation was running
103         //
104         // calcMan.workerCannotRun(this);
105         calcMan.workerComplete(this);
106         return;
107       }
108       alignViewport.setSequenceConsensusHash(hconsensus);
109       updateResultAnnotation(true);
110       ColourSchemeI globalColourScheme = alignViewport
111               .getGlobalColourScheme();
112       if (globalColourScheme != null)
113       {
114         globalColourScheme.setConsensus(hconsensus);
115       }
116
117     } catch (OutOfMemoryError error)
118     {
119       calcMan.workerCannotRun(this);
120
121       // consensus = null;
122       // hconsensus = null;
123       ap.raiseOOMWarning("calculating consensus", error);
124     }
125
126     calcMan.workerComplete(this);
127     if (ap != null)
128     {
129       ap.paintAlignment(true);
130     }
131   }
132
133   /**
134    * update the consensus annotation from the sequence profile data using
135    * current visualization settings.
136    */
137   @Override
138   public void updateAnnotation()
139   {
140     updateResultAnnotation(false);
141   }
142
143   public void updateResultAnnotation(boolean immediate)
144   {
145     AlignmentAnnotation consensus = alignViewport
146             .getAlignmentConsensusAnnotation();
147     Hashtable[] hconsensus = alignViewport.getSequenceConsensusHash();
148     if (immediate || !calcMan.isWorking(this) && consensus != null
149             && hconsensus != null)
150     {
151       AAFrequency.completeConsensus(consensus, hconsensus, 0,
152               hconsensus.length, alignViewport.getIgnoreGapsConsensus(),
153               alignViewport.isShowSequenceLogo());
154     }
155   }
156 }