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