Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / src / jalview / gui / structurechooser / TDBResultAnalyser.java
index 09ff0aa..28861d9 100644 (file)
@@ -1,7 +1,25 @@
+/*
+ * 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.gui.structurechooser;
 
-import java.util.Locale;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
@@ -9,6 +27,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Locale;
 
 import jalview.datamodel.SequenceI;
 import jalview.fts.api.FTSData;
@@ -25,8 +44,8 @@ public class TDBResultAnalyser
    */
   private static List<String> EXP_CATEGORIES = Arrays
           .asList(new String[]
-          { "EXPERIMENTALLY DETERMINED", "DEEP-LEARNING", "TEMPLATE-BASED",
-              "AB-INITIO", "CONFORMATIONAL ENSEMBLE" });
+          { "EXPERIMENTALLY DETERMINED", "DEEP-LEARNING", "AB-INITIO",
+              "TEMPLATE-BASED", "CONFORMATIONAL ENSEMBLE" });
 
   private SequenceI seq;
 
@@ -42,6 +61,8 @@ public class TDBResultAnalyser
 
   private int idx_mqual;
 
+  private int idx_mqualtype;
+
   private int idx_resol;
 
   /**
@@ -72,6 +93,7 @@ public class TDBResultAnalyser
     idx_mprov = lastTdbRequest.getFieldIndex("Provider");
     idx_mqual = lastTdbRequest.getFieldIndex("Confidence");
     idx_resol = lastTdbRequest.getFieldIndex("Resolution");
+    idx_mqualtype = lastTdbRequest.getFieldIndex("Confidence Score Type");
   }
 
   /**
@@ -91,7 +113,7 @@ public class TDBResultAnalyser
     int idx = EXP_CATEGORIES.indexOf(upper_cat);
     if (idx == -1)
     {
-      System.out.println("Unknown category: '" + cat + "'");
+      jalview.bin.Console.outPrintln("Unknown category: '" + cat + "'");
       EXP_CATEGORIES.add(upper_cat);
       idx = EXP_CATEGORIES.size() - 1;
     }
@@ -111,18 +133,22 @@ public class TDBResultAnalyser
     // ignore anything outside the sequence region
     for (FTSData row : collectedResults)
     {
-      int up_s = (Integer) row.getSummaryData()[idx_ups];
-      int up_e = (Integer) row.getSummaryData()[idx_upe];
-      String provider = (String) row.getSummaryData()[idx_mprov];
-      String mcat = (String) row.getSummaryData()[idx_mcat];
-      // this makes sure all new categories are in the score array.
-      int scorecat = scoreCategory(mcat);
-      if (sourceFilter == null || sourceFilter.equals(provider))
+      if (row.getSummaryData() != null
+              && row.getSummaryData()[idx_ups] != null)
       {
-        if (seq == row.getSummaryData()[0] && up_e > seq.getStart()
-                && up_s < seq.getEnd())
+        int up_s = (Integer) row.getSummaryData()[idx_ups];
+        int up_e = (Integer) row.getSummaryData()[idx_upe];
+        String provider = (String) row.getSummaryData()[idx_mprov];
+        String mcat = (String) row.getSummaryData()[idx_mcat];
+        // this makes sure all new categories are in the score array.
+        int scorecat = scoreCategory(mcat);
+        if (sourceFilter == null || sourceFilter.equals(provider))
         {
-          filteredResponse.add(row);
+          if (seq == row.getSummaryData()[0] && up_e > seq.getStart()
+                  && up_s < seq.getEnd())
+          {
+            filteredResponse.add(row);
+          }
         }
       }
     }
@@ -145,6 +171,8 @@ public class TDBResultAnalyser
         int o2_cat = scoreCategory((String) o2data[idx_mcat]);
         String o2_prov = ((String) o2data[idx_mprov])
                 .toUpperCase(Locale.ROOT);
+        String o1_qualtype = (String) o1data[idx_mqualtype],
+                o2_qualtype = (String) o2data[idx_mqualtype];
 
         if (o1_cat == o2_cat)
         {
@@ -154,6 +182,7 @@ public class TDBResultAnalyser
             int o2_xtent = o2_e - o2_s;
             if (o1_xtent == o2_xtent)
             {
+              // EXPERIMENTAL DATA ALWAYS TRUMPS MODELS
               if (o1_cat == scoreCategory(EXP_CATEGORIES.get(0)))
               {
                 if (o1_prov.equals(o2_prov))
@@ -185,6 +214,19 @@ public class TDBResultAnalyser
               }
               else
               {
+                // RANK ON QUALITY - DOWNRANK THOSE WITH NO QUALITY MEASURE
+                if (eitherNull(idx_mqualtype, o1data, o2data))
+                {
+                  return nonNullFirst(idx_mqualtype, o1data, o2data);
+                }
+                // ONLY COMPARE LIKE QUALITY SCORES
+                if (!o1_qualtype.equals(o2_qualtype))
+                {
+                  // prefer LDDT measure over others
+                  return "pLDDT".equals(o1_qualtype) ? -1
+                          : "pLDDT".equals(o2_qualtype) ? 1 : 0;
+                }
+                // OR NO VALUE FOR THE QUALITY
                 if (eitherNull(idx_mqual, o1data, o2data))
                 {
                   return nonNullFirst(idx_mqual, o1data, o2data);
@@ -192,7 +234,8 @@ public class TDBResultAnalyser
                 // models, so rank on qmean - b
                 double o1_mq = (Double) o1data[idx_mqual];
                 double o2_mq = (Double) o2data[idx_mqual];
-                return (o2_mq < o1_mq) ? 1 : (o2_mq == o1_mq) ? 0 : -1;
+                int res = (o2_mq < o1_mq) ? 1 : (o2_mq == o1_mq) ? 0 : -1;
+                return ("pLDDT".equals(o1_qualtype)) ? -res : res;
               }
             }
             else
@@ -207,6 +250,12 @@ public class TDBResultAnalyser
         }
         else
         {
+          // if both are not experimental, then favour alphafold
+          if (o2_cat > 0 && o1_cat > 0)
+          {
+            return "ALPHAFOLD DB".equals(o1_prov) ? -1
+                    : "ALPHAFOLD DB".equals(o2_prov) ? 1 : 0;
+          }
           return o2_cat - o1_cat;
         }
       }