X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=blobdiff_plain;f=src%2Fjalview%2Fgui%2Fstructurechooser%2FTDBResultAnalyser.java;h=2408d7a2c8c248641896ca62447b20885b91d9c7;hp=f73f3978a8fd60dc0bc0670d878e2b571cba1ee8;hb=5a352aa2f3330ae269d9b70c4a7374c2518bfb2e;hpb=e36731274aafe1e930805c19a0f60372c4c6392a diff --git a/src/jalview/gui/structurechooser/TDBResultAnalyser.java b/src/jalview/gui/structurechooser/TDBResultAnalyser.java index f73f397..2408d7a 100644 --- a/src/jalview/gui/structurechooser/TDBResultAnalyser.java +++ b/src/jalview/gui/structurechooser/TDBResultAnalyser.java @@ -1,5 +1,27 @@ +/* + * 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 . + * 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; @@ -23,8 +45,8 @@ public class TDBResultAnalyser */ private static List EXP_CATEGORIES = Arrays .asList(new String[] - { "EXPERIMENTALLY DETERMINED", "DEEP LEARNING", - "TEMPLATE-BASED" }); + { "EXPERIMENTALLY DETERMINED", "DEEP-LEARNING", "TEMPLATE-BASED", + "AB-INITIO", "CONFORMATIONAL ENSEMBLE" }); private SequenceI seq; @@ -42,26 +64,56 @@ public class TDBResultAnalyser private int idx_resol; + /** + * selection model + */ + private String filter = null; + + /** + * limit to particular source + */ + private String sourceFilter = null; + + private int idx_mprov; + public TDBResultAnalyser(SequenceI seq, Collection collectedResults, - FTSRestRequest lastTdbRequest) + FTSRestRequest lastTdbRequest, String fieldToFilterBy, + String string) { this.seq = seq; this.collectedResults = collectedResults; this.lastTdbRequest = lastTdbRequest; + this.filter = fieldToFilterBy; + this.sourceFilter = string; idx_ups = lastTdbRequest.getFieldIndex("Uniprot Start"); idx_upe = lastTdbRequest.getFieldIndex("Uniprot End"); idx_mcat = lastTdbRequest.getFieldIndex("Model Category"); - idx_mqual = lastTdbRequest.getFieldIndex("Qmean"); + idx_mprov = lastTdbRequest.getFieldIndex("Provider"); + idx_mqual = lastTdbRequest.getFieldIndex("Confidence"); idx_resol = lastTdbRequest.getFieldIndex("Resolution"); } - private final int scoreCategory(String cat) + + /** + * maintain and resolve categories to 'trust order' TODO: change the trust + * scheme to something comprehensible. + * + * @param cat + * @return 0 for null cat, less than zero for others + */ + public final int scoreCategory(String cat) { - // TODO: make quicker - int idx = EXP_CATEGORIES.indexOf(cat.toUpperCase()); + if (cat == null) + { + return 0; + } + String upper_cat = cat.toUpperCase(Locale.ROOT); + int idx = EXP_CATEGORIES.indexOf(upper_cat); if (idx == -1) { System.out.println("Unknown category: '" + cat + "'"); + EXP_CATEGORIES.add(upper_cat); + idx = EXP_CATEGORIES.size() - 1; } return -EXP_CATEGORIES.size() - idx; } @@ -79,21 +131,29 @@ 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]; - - if (seq == row.getSummaryData()[0] && up_e > seq.getStart() - && up_s < seq.getEnd()) + if (row.getSummaryData() != null + && row.getSummaryData()[idx_ups] != null) { - filteredResponse.add(row); + 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 (seq == row.getSummaryData()[0] && up_e > seq.getStart() + && up_s < seq.getEnd()) + { + filteredResponse.add(row); + } + } } } // sort according to decreasing length, // increasing start Collections.sort(filteredResponse, new Comparator() { - - @Override public int compare(FTSData o1, FTSData o2) { @@ -102,9 +162,13 @@ public class TDBResultAnalyser int o1_s = (Integer) o1data[idx_ups]; int o1_e = (Integer) o1data[idx_upe]; int o1_cat = scoreCategory((String) o1data[idx_mcat]); + String o1_prov = ((String) o1data[idx_mprov]) + .toUpperCase(Locale.ROOT); int o2_s = (Integer) o2data[idx_ups]; int o2_e = (Integer) o2data[idx_upe]; int o2_cat = scoreCategory((String) o2data[idx_mcat]); + String o2_prov = ((String) o2data[idx_mprov]) + .toUpperCase(Locale.ROOT); if (o1_cat == o2_cat) { @@ -116,16 +180,42 @@ public class TDBResultAnalyser { if (o1_cat == scoreCategory(EXP_CATEGORIES.get(0))) { - // experimental structures, so rank on quality - double o1_res = (Double) o1data[idx_resol]; - double o2_res = (Double) o2data[idx_resol]; - return (o2_res < o1_res) ? 1 : (o2_res == o1_res) ? 0 : -1; + if (o1_prov.equals(o2_prov)) + { + if ("PDBE".equals(o1_prov)) + { + if (eitherNull(idx_resol, o1data, o2data)) + { + return nonNullFirst(idx_resol, o1data, o2data); + } + // experimental structures, so rank on quality + double o1_res = (Double) o1data[idx_resol]; + double o2_res = (Double) o2data[idx_resol]; + return (o2_res < o1_res) ? 1 + : (o2_res == o1_res) ? 0 : -1; + } + else + { + return 0; // no change in order + } + } + else + { + // PDBe always ranked above all other experimentally + // determined categories + return "PDBE".equals(o1_prov) ? -1 + : "PDBE".equals(o2_prov) ? 1 : 0; + } } else { - // models, so rank on qmean - float o1_mq = (Float) o1data[idx_mqual]; - float o2_mq = (Float) o2data[idx_mqual]; + if (eitherNull(idx_mqual, o1data, o2data)) + { + return nonNullFirst(idx_mqual, o1data, o2data); + } + // 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; } } @@ -145,6 +235,19 @@ public class TDBResultAnalyser } } + private int nonNullFirst(int idx_resol, Object[] o1data, + Object[] o2data) + { + return o1data[idx_resol] == o2data[idx_resol] ? 0 + : o1data[idx_resol] != null ? -1 : 1; + } + + private boolean eitherNull(int idx_resol, Object[] o1data, + Object[] o2data) + { + return (o1data[idx_resol] == null || o2data[idx_resol] == null); + } + @Override public boolean equals(Object obj) { @@ -155,48 +258,64 @@ public class TDBResultAnalyser } /** - * return list of structures to be marked as selected for this sequence according to given criteria - * @param filteredStructures - sorted, filtered structures from getFilteredResponse + * return list of structures to be marked as selected for this sequence + * according to given criteria + * + * @param filteredStructures + * - sorted, filtered structures from getFilteredResponse * */ public List selectStructures(List filteredStructures) { List selected = new ArrayList(); BitSet cover = new BitSet(); - cover.set(seq.getStart(),seq.getEnd()); + cover.set(seq.getStart(), seq.getEnd()); // walk down the list of structures, selecting some to add to selected - for (FTSData structure:filteredStructures) + // TODO: could do simple DP - double loop to select largest number of + // structures covering largest number of sites + for (FTSData structure : filteredStructures) { - Object[] odata=structure.getSummaryData(); + Object[] odata = structure.getSummaryData(); int o1_s = (Integer) odata[idx_ups]; int o1_e = (Integer) odata[idx_upe]; int o1_cat = scoreCategory((String) odata[idx_mcat]); BitSet scover = new BitSet(); // measure intersection - scover.set(o1_s,o1_e); + scover.set(o1_s, o1_e); scover.and(cover); - if (scover.cardinality()>4) + if (scover.cardinality() > 4) { selected.add(structure); // clear the range covered by this structure - cover.andNot(scover); + cover.andNot(scover); } } - // final step is to sort on length - this might help the superposition process - Collections.sort(selected,new Comparator() + if (selected.size() == 0) + { + return selected; + } + // final step is to sort on length - this might help the superposition + // process + Collections.sort(selected, new Comparator() { @Override public int compare(FTSData o1, FTSData o2) { Object[] o1data = o1.getSummaryData(); Object[] o2data = o2.getSummaryData(); - int o1_xt = ((Integer) o1data[idx_upe]) - ((Integer) o1data[idx_ups]); + int o1_xt = ((Integer) o1data[idx_upe]) + - ((Integer) o1data[idx_ups]); int o1_cat = scoreCategory((String) o1data[idx_mcat]); - int o2_xt = ((Integer) o2data[idx_upe]-(Integer) o2data[idx_ups]); + int o2_xt = ((Integer) o2data[idx_upe] - (Integer) o2data[idx_ups]); int o2_cat = scoreCategory((String) o2data[idx_mcat]); - return o2_xt-o1_xt; + return o2_xt - o1_xt; } }); + if (filter.equals( + ThreeDBStructureChooserQuerySource.FILTER_FIRST_BEST_COVERAGE)) + { + return selected.subList(0, 1); + } return selected; }