JAL-4369 invokeAndWait to avoid hang whilst calling getFiles if a Jmol redraw is...
[jalview.git] / src / jalview / workers / AlignmentComparisonThread.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.analysis.AAFrequency;
24 import jalview.analysis.Conservation;
25 import jalview.analysis.scoremodels.ScoreModels;
26 import jalview.api.AlignViewportI;
27 import jalview.api.AlignmentViewPanel;
28 import jalview.bin.Console;
29 import jalview.datamodel.AlignedCodonFrame;
30 import jalview.datamodel.AlignmentAnnotation;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.Annotation;
33 import jalview.datamodel.SequenceI;
34 import jalview.util.MappingUtils;
35
36 import java.util.ArrayList;
37 import java.util.ConcurrentModificationException;
38 import java.util.Hashtable;
39 import java.util.List;
40
41 /**
42  * A thread to compute the columnwise correspondence between aligned positions
43  * and their positions in a linked alignment
44  * 
45  * @author jprocter
46  *
47  */
48 public class AlignmentComparisonThread extends AlignCalcWorker
49 {
50
51   public AlignmentComparisonThread(AlignViewportI alignViewport,
52           AlignmentViewPanel alignPanel)
53   {
54     super(alignViewport, alignPanel);
55     comparisonAnnot = alignViewport.getComparisonAnnotation();
56   }
57
58   Annotation[] correspondence = new Annotation[1];
59   AlignmentAnnotation comparisonAnnot=null;
60   int alWidth;
61   private int maxCor=1;
62
63   @Override
64   public void run()
65   {
66     try
67     {
68       calcMan.notifyStart(this); // updatingConservation = true;
69
70       while ((calcMan != null) && (!calcMan.notifyWorking(this)))
71       {
72         try
73         {
74           if (ap != null)
75           {
76             // ap.paintAlignment(false);
77           }
78           Thread.sleep(200);
79         } catch (Exception ex)
80         {
81           ex.printStackTrace();
82         }
83       }
84       if ((alignViewport == null) || (calcMan == null)
85               || (alignViewport.isClosed()))
86       {
87         abortAndDestroy();
88         return;
89       }
90       List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
91
92       AlignmentI alignment = alignViewport.getAlignment();
93       AlignViewportI codingComplement = alignViewport.getCodingComplement();
94       if (alignment == null || (alWidth = alignment.getWidth()) < 0
95               || (codingComplement == null))
96       {
97         calcMan.workerComplete(this);
98         // .updatingConservation = false;
99         // AlignViewport.UPDATING_CONSERVATION = false;
100
101         return;
102       }
103       
104       comparisonAnnot.annotations=correspondence;
105       ourAnnot.add(comparisonAnnot);
106       ourAnnots = ourAnnot;
107
108       try
109       {
110         computeColumnCorrespondence(alignViewport, codingComplement);
111       } catch (Throwable x)
112       {
113         Console.error("Unexpected error computing similarity of alignments",x);
114         // probable race condition. just finish and return without any fuss.
115         calcMan.workerComplete(this);
116         return;
117       }
118       updateResultAnnotation(true);
119     } catch (OutOfMemoryError error)
120     {
121       ap.raiseOOMWarning("calculating conservation", error);
122       calcMan.disableWorker(this);
123       // alignViewport.conservation = null;
124       // this.alignViewport.quality = null;
125
126     }
127     calcMan.workerComplete(this);
128
129     if ((alignViewport == null) || (calcMan == null)
130             || (alignViewport.isClosed()))
131     {
132       abortAndDestroy();
133       return;
134     }
135     if (ap != null)
136     {
137       ap.paintAlignment(true, true);
138     }
139
140   }
141
142   private void computeColumnCorrespondence(AlignViewportI alignViewport,
143           AlignViewportI codingComplement)
144   {
145     List<SequenceI> us = alignViewport.getAlignment().getSequences();
146     List<AlignedCodonFrame> ourMappings = alignViewport.getAlignment()
147             .getCodonFrames();
148     List<SequenceI> them = codingComplement.getAlignment().getSequences();
149     List<AlignedCodonFrame> theirMappings = codingComplement.getAlignment()
150             .getCodonFrames();
151     if (us == null || them == null || us.isEmpty() || them.isEmpty())
152     {
153       return;
154     }
155
156     int colEnd = alignViewport.getAlignment().getWidth();
157     Annotation[] colCorrsp = new Annotation[colEnd];
158     maxCor=0;
159     for (int col = 0; col < colEnd; col++)
160     {
161       int[] theirWidth = MappingUtils.findMappedColumns(col, ourMappings,
162               us, them, alignViewport.getGapCharacter());
163       int wid =theirWidth != null ? Math.abs(theirWidth[1] - theirWidth[0])
164               : 0;
165       colCorrsp[col] = new Annotation(
166               wid);
167       maxCor = Math.max(maxCor, wid);
168     }
169     correspondence=colCorrsp;
170   }
171
172   private void updateResultAnnotation(boolean b)
173   {
174     if (b || !calcMan.isWorking(this) && correspondence!=null)
175     {
176       comparisonAnnot.annotations = correspondence;
177       comparisonAnnot.graphMax=(float)maxCor;
178       comparisonAnnot.validateRangeAndDisplay();
179       ap.paintAlignment(false, false);
180     }
181   }
182
183   @Override
184   public void updateAnnotation()
185   {
186     updateResultAnnotation(false);
187
188   }
189
190 }