JAL-961, JAL-1115 - pending test to ensure only one worker waits around for another...
[jalview.git] / src / jalview / workers / ConsensusThread.java
1 package jalview.workers;
2
3 import jalview.analysis.AAFrequency;
4 import jalview.api.AlignCalcWorkerI;
5 import jalview.api.AlignViewportI;
6 import jalview.api.AlignmentViewPanel;
7 import jalview.datamodel.AlignmentAnnotation;
8 import jalview.datamodel.AlignmentI;
9 import jalview.datamodel.Annotation;
10 import jalview.schemes.ColourSchemeI;
11
12 import java.util.Hashtable;
13
14 public class ConsensusThread extends AlignCalcWorker implements AlignCalcWorkerI
15 {
16   public ConsensusThread(AlignViewportI alignViewport,
17           AlignmentViewPanel alignPanel)
18   {
19     super(alignViewport, alignPanel);
20   }
21
22   @Override
23   public void run()
24   {
25     if (calcMan.isPending(this))
26     {
27       return;
28     }
29     calcMan.notifyStart(this);
30     long started=System.currentTimeMillis();
31     try
32     {
33       AlignmentAnnotation consensus = alignViewport.getAlignmentConsensusAnnotation();
34       if (consensus==null || calcMan.isPending(this))  {
35         calcMan.workerComplete(this);
36         return;
37       }
38       while (!calcMan.notifyWorking(this))
39       {
40         // System.err.println("Thread (Consensus"+Thread.currentThread().getName()+") Waiting around.");
41         try
42         {
43           if (ap != null)
44           {
45            ap.paintAlignment(false);
46           }
47           Thread.sleep(200);
48         } catch (Exception ex)
49         {
50           ex.printStackTrace();
51         }
52       }
53       if (alignViewport.isClosed())
54       {
55         abortAndDestroy();
56       }
57       AlignmentI alignment = alignViewport.getAlignment();
58
59       int aWidth = -1;
60
61       if (alignment == null || (aWidth = alignment.getWidth()) < 0)
62       {
63         calcMan.workerComplete(this);
64         // .updatingConservation = false;
65         // AlignViewport.UPDATING_CONSERVATION = false;
66
67         return;
68       }
69       consensus = alignViewport
70               .getAlignmentConsensusAnnotation();
71
72       consensus.annotations = null;
73       consensus.annotations = new Annotation[aWidth];
74       Hashtable[] hconsensus = alignViewport.getSequenceConsensusHash();
75       hconsensus = new Hashtable[aWidth];
76       try {
77        AAFrequency.calculate(alignment.getSequencesArray(), 0,
78               alignment.getWidth(), hconsensus, true);
79       } catch (ArrayIndexOutOfBoundsException x){
80         // this happens due to a race condition -
81         // alignment was edited at same time as calculation was running
82         //
83 //        calcMan.workerCannotRun(this);
84         calcMan.workerComplete(this);
85         return;
86       }
87       alignViewport.setSequenceConsensusHash(hconsensus);
88       updateResultAnnotation(true);
89       ColourSchemeI globalColourScheme = alignViewport
90               .getGlobalColourScheme();
91       if (globalColourScheme != null)
92       {
93         globalColourScheme.setConsensus(hconsensus);
94       }
95
96     } catch (OutOfMemoryError error)
97     {
98       calcMan.workerCannotRun(this);
99
100       // consensus = null;
101       // hconsensus = null;
102       ap.raiseOOMWarning("calculating consensus", error);
103     }
104
105     calcMan.workerComplete(this);
106     if (ap != null)
107     {
108       ap.paintAlignment(true);
109     }
110   }
111
112   /**
113    * update the consensus annotation from the sequence profile data using
114    * current visualization settings.
115    */
116   @Override
117   public void updateAnnotation()
118   {
119     updateResultAnnotation(false);
120   }
121
122   public void updateResultAnnotation(boolean immediate)
123   {
124     AlignmentAnnotation consensus = alignViewport
125             .getAlignmentConsensusAnnotation();
126     Hashtable[] hconsensus = alignViewport.getSequenceConsensusHash();
127     if (immediate || !calcMan.isWorking(this) && consensus!=null && hconsensus!=null)
128     {
129       AAFrequency.completeConsensus(consensus, hconsensus, 0,
130             hconsensus.length, alignViewport.getIgnoreGapsConsensus(),
131             alignViewport.isShowSequenceLogo());
132     }
133   }
134 }