--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.workers;
+
+import jalview.analysis.AAFrequency;
+import jalview.analysis.Conservation;
+import jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceI;
+import jalview.util.MappingUtils;
+
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * A thread to compute the columnwise correspondence between aligned positions
+ * and their positions in a linked alignment
+ *
+ * @author jprocter
+ *
+ */
+public class AlignmentComparisonThread extends AlignCalcWorker
+{
+
+ public AlignmentComparisonThread(AlignViewportI alignViewport,
+ AlignmentViewPanel alignPanel)
+ {
+ super(alignViewport, alignPanel);
+ }
+
+ Annotation[] correspondence = new Annotation[] {};
+ AlignmentAnnotation comparisonAnnot=null;
+ int alWidth;
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ calcMan.notifyStart(this); // updatingConservation = true;
+
+ while ((calcMan != null) && (!calcMan.notifyWorking(this)))
+ {
+ try
+ {
+ if (ap != null)
+ {
+ // ap.paintAlignment(false);
+ }
+ Thread.sleep(200);
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ if ((alignViewport == null) || (calcMan == null)
+ || (alignViewport.isClosed()))
+ {
+ abortAndDestroy();
+ return;
+ }
+ List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
+
+ AlignmentI alignment = alignViewport.getAlignment();
+ AlignViewportI codingComplement = alignViewport.getCodingComplement();
+ if (alignment == null || (alWidth = alignment.getWidth()) < 0
+ || (codingComplement == null))
+ {
+ calcMan.workerComplete(this);
+ // .updatingConservation = false;
+ // AlignViewport.UPDATING_CONSERVATION = false;
+
+ return;
+ }
+ comparisonAnnot = alignViewport.getAlignment().findOrCreateAnnotation("Comparison", "CORRESPONDENCE", true, null, null);
+ comparisonAnnot.annotations=correspondence;
+ ourAnnot.add(comparisonAnnot);
+ ourAnnots = ourAnnot;
+
+ try
+ {
+ computeColumnCorrespondence(alignViewport, codingComplement);
+ } catch (IndexOutOfBoundsException x)
+ {
+ // probable race condition. just finish and return without any fuss.
+ calcMan.workerComplete(this);
+ return;
+ }
+ updateResultAnnotation(true);
+ } catch (OutOfMemoryError error)
+ {
+ ap.raiseOOMWarning("calculating conservation", error);
+ calcMan.disableWorker(this);
+ // alignViewport.conservation = null;
+ // this.alignViewport.quality = null;
+
+ }
+ calcMan.workerComplete(this);
+
+ if ((alignViewport == null) || (calcMan == null)
+ || (alignViewport.isClosed()))
+ {
+ abortAndDestroy();
+ return;
+ }
+ if (ap != null)
+ {
+ ap.paintAlignment(true, true);
+ }
+
+ }
+
+ private void computeColumnCorrespondence(AlignViewportI alignViewport,
+ AlignViewportI codingComplement)
+ {
+ List<SequenceI> us = alignViewport.getAlignment().getSequences();
+ List<AlignedCodonFrame> ourMappings = alignViewport.getAlignment()
+ .getCodonFrames();
+ List<SequenceI> them = codingComplement.getAlignment().getSequences();
+ List<AlignedCodonFrame> theirMappings = codingComplement.getAlignment()
+ .getCodonFrames();
+ if (us == null || them == null || us.isEmpty() || them.isEmpty())
+ {
+ return;
+ }
+
+ int colEnd = alignViewport.getAlignment().getWidth();
+ Annotation[] colCorrsp = new Annotation[colEnd];
+ for (int col = 0; col < colEnd; col++)
+ {
+ int[] theirWidth = MappingUtils.findMappedColumns(col, ourMappings,
+ us, them, alignViewport.getGapCharacter());
+ colCorrsp[col] = new Annotation(
+ theirWidth != null ? Math.abs(theirWidth[1] - theirWidth[0])
+ : 0);
+ }
+ correspondence=colCorrsp;
+ }
+
+ private void updateResultAnnotation(boolean b)
+ {
+ if (b || !calcMan.isWorking(this) && correspondence!=null)
+ {
+ comparisonAnnot.annotations = correspondence;
+ comparisonAnnot.validateRangeAndDisplay();
+ }
+ }
+
+ @Override
+ public void updateAnnotation()
+ {
+ updateResultAnnotation(false);
+
+ }
+
+}