Merge branch 'feature/JAL-4159_pasimap' into develop
[jalview.git] / src / jalview / analysis / Connectivity.java
diff --git a/src/jalview/analysis/Connectivity.java b/src/jalview/analysis/Connectivity.java
new file mode 100644 (file)
index 0000000..c65c170
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * 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.analysis;
+
+import jalview.datamodel.SequenceI;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.viewmodel.AlignmentViewport;
+
+import java.util.Hashtable;
+
+/**
+ * @Author MorellThomas
+ */
+
+public class Connectivity
+{
+  public static Hashtable<SequenceI, Integer> getConnectivityForAlignmentView(
+          AlignmentViewport av, float[][] scores, byte dim)
+  {
+    boolean isSelection = av.getSelectionGroup() != null
+            && av.getSelectionGroup().getSize() > 0;
+    SequenceI[] sequences;
+    if (isSelection)
+    {
+      sequences = (SequenceI[]) av.getAlignmentView(isSelection)
+              .getAlignmentAndHiddenColumns(av.getGapCharacter())[0];
+    }
+    else
+    {
+      sequences = av.getAlignment().getSequencesArray();
+    }
+
+    return Connectivity.getConnectivity(sequences, scores, dim);
+  }
+
+  /**
+   * Returns the number of unique connections for each sequence only connections
+   * with a score of above 0 count
+   * 
+   * @param av
+   *          sequences
+   * @param scores
+   *          alignment scores
+   *
+   * @return connectivity
+   */
+  public static Hashtable<SequenceI, Integer> getConnectivity(
+          SequenceI[] sequences, float[][] scores, byte dim)
+          throws RuntimeException
+  {
+    Hashtable<SequenceI, Integer> connectivity = new Hashtable<SequenceI, Integer>();
+    // for each unique connection
+    for (int i = 0; i < sequences.length; i++)
+    {
+      connectivity.putIfAbsent(sequences[i], 0);
+      for (int j = 0; j < i; j++)
+      {
+        connectivity.putIfAbsent(sequences[j], 0);
+        int iOld = connectivity.get(sequences[i]);
+        int jOld = connectivity.get(sequences[j]);
+        // count the connection if its score is not NaN
+        // System.out.println(String.format("%s - %s : %f",
+        // sequences[i].getName(), sequences[j].getName(), scores[i][j]));
+        if (!Float.isNaN(scores[i][j]))
+        {
+          connectivity.put(sequences[i], ++iOld);
+          connectivity.put(sequences[j], ++jOld);
+        }
+      }
+    }
+
+    // if a sequence has too few connections, abort
+    connectivity.forEach((sequence, connection) -> {
+      System.out.println(
+              String.format("%s: %d", sequence.getName(), connection));
+      if (connection < dim)
+      {
+        JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+                String.format(
+                        "Insufficient number of connections for %s (%d, should be %d or more)",
+                        sequence.getName(), connection, dim),
+                "Connectivity Error", JvOptionPane.WARNING_MESSAGE);
+        throw new ConnectivityException(sequence.getName(), connection,
+                dim);
+      }
+    });
+
+    return connectivity;
+  }
+
+}