From 1128674a17df402a2219d278ab332c291cb93443 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Mon, 23 Jan 2023 23:57:06 +0000 Subject: [PATCH] JAL-629 Attempts to add PAE to structure. --headless working. Make HTML output single threaded in headless mode. Delete an editor temp file. --- src/jalview/bin/ArgParser.java | 10 +- src/jalview/bin/Commands.java | 47 +- src/jalview/bin/Jalview.java | 12 +- src/jalview/gui/LineartOptions.java | 6 +- src/jalview/io/HTMLOutput.java | 10 +- .../structure/StructureSelectionManager.java | 10 + .../structure/StructureSelectionManager.java~ | 1327 -------------------- src/jalview/ws/dbsources/EBIAlfaFold.java | 162 ++- 8 files changed, 204 insertions(+), 1380 deletions(-) delete mode 100644 src/jalview/structure/StructureSelectionManager.java~ diff --git a/src/jalview/bin/ArgParser.java b/src/jalview/bin/ArgParser.java index 0697193..4cdfd19 100644 --- a/src/jalview/bin/ArgParser.java +++ b/src/jalview/bin/ArgParser.java @@ -706,7 +706,9 @@ public class ArgParser */ public static class SubVal { - protected int index = 0; + private static int NOTSET = -1; + + protected int index = NOTSET; protected String keyName = null; @@ -752,5 +754,11 @@ public class ArgParser this.content = item; } } + + public boolean notSet() + { + // notSet is true if content present but nonsensical + return index == NOTSET && keyName == null && keyValue == null; + } } } \ No newline at end of file diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index 77ca018..c05194d 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -32,6 +32,7 @@ import jalview.io.HtmlSvgOutput; import jalview.io.IdentifyFile; import jalview.structure.StructureImportSettings; import jalview.structure.StructureImportSettings.TFType; +import jalview.structure.StructureSelectionManager; import jalview.util.HttpUtils; import jalview.util.MessageManager; import jalview.util.Platform; @@ -51,10 +52,17 @@ public class Commands { argParser = ap; headless = h; + + if (headless) + { + System.setProperty("java.awt.headless", "true"); + } + if (argParser != null && argParser.linkedIds() != null) { for (String id : argParser.linkedIds()) { + Console.debug("##### id=" + id); Commands cmds = new Commands(); if (id == null) { @@ -67,10 +75,11 @@ public class Commands cmds.processImages(id); } - if (argParser.getBool(Arg.QUIT)) - { - Jalview.getInstance().quit(); - } + } + if (argParser.getBool(Arg.QUIT)) + { + Jalview.getInstance().quit(); + // Desktop.instance.quit(); } } @@ -87,6 +96,8 @@ public class Commands protected void processUnlinked(String id) { + Map m = argParser.linkedArgs(id); + processLinked(id); } @@ -104,7 +115,6 @@ public class Commands FileFormatI format = null; DataSourceType protocol = null; */ - if (ArgParser.getArgValues(m, Arg.OPEN) != null) { long progress = -1; @@ -289,6 +299,16 @@ public class Commands // store the AlignFrame for this id afMap.put(id, af); + + // is it its own structure file? + if (format.isStructureFile()) + { + StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + SequenceI seq = af.alignPanel.getAlignment().getSequenceAt(0); + ssm.computeMapping(false, new SequenceI[] { seq }, null, + openFile, DataSourceType.FILE, null); + } } else { @@ -328,11 +348,24 @@ public class Commands { SubVal subVal = ArgParser.getSubVal(val); File paeFile = new File(subVal.content); - if ("structid".equals(subVal.index)) + String structId = "structid".equals(subVal.keyName) + ? subVal.keyValue + : null; + if (subVal.notSet()) + { + // take structid from pdbfilename + } + if ("structfile".equals(subVal.keyName)) + { + EBIAlfaFold.addAlphaFoldPAEToStructure( + af.getCurrentView().getAlignment(), paeFile, + subVal.index, subVal.keyValue, false); + } + else if ("structid".equals(subVal.keyName)) { EBIAlfaFold.addAlphaFoldPAEToStructure( af.getCurrentView().getAlignment(), paeFile, - subVal.index, subVal.keyValue); + subVal.index, subVal.keyValue, true); } else { diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index 6f000dd..1f01125 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -57,6 +57,7 @@ import com.threerings.getdown.util.LaunchUtil; //import edu.stanford.ejalbert.launching.IBrowserLaunching; import groovy.lang.Binding; import groovy.util.GroovyScriptEngine; +import jalview.bin.ArgParser.Arg; import jalview.ext.so.SequenceOntology; import jalview.gui.AlignFrame; import jalview.gui.Desktop; @@ -319,13 +320,18 @@ public class Jalview * @j2sIgnore */ { + if (argparser.isSet(Arg.HEADLESS)) + { + headless = argparser.getBool(Arg.HEADLESS); + } + if (aparser.contains("help") || aparser.contains("h")) { showUsage(); System.exit(0); } - if (aparser.contains("nodisplay") || aparser.contains("nogui") - || aparser.contains("headless")) + if (headless || aparser.contains("nodisplay") + || aparser.contains("nogui") || aparser.contains("headless")) { System.setProperty("java.awt.headless", "true"); headless = true; @@ -557,6 +563,8 @@ public class Jalview }.start(); } + if (argparser.isSet(Arg.HEADLESS)) + headless = argparser.getBool(Arg.HEADLESS); Commands.processArgs(argparser, headless); String file = null, data = null; diff --git a/src/jalview/gui/LineartOptions.java b/src/jalview/gui/LineartOptions.java index d55733c..62ad108 100644 --- a/src/jalview/gui/LineartOptions.java +++ b/src/jalview/gui/LineartOptions.java @@ -20,9 +20,6 @@ */ package jalview.gui; -import jalview.bin.Cache; -import jalview.util.MessageManager; - import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -35,6 +32,9 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; +import jalview.bin.Cache; +import jalview.util.MessageManager; + /** * A dialog where the user may choose Text or Lineart rendering, and optionally * save this as a preference ("Don't ask me again") diff --git a/src/jalview/io/HTMLOutput.java b/src/jalview/io/HTMLOutput.java index eb44180..2745420 100644 --- a/src/jalview/io/HTMLOutput.java +++ b/src/jalview/io/HTMLOutput.java @@ -29,6 +29,7 @@ import java.util.Objects; import jalview.api.AlignExportSettingsI; import jalview.bin.Cache; +import jalview.bin.Jalview; import jalview.datamodel.AlignExportSettingsAdapter; import jalview.datamodel.AlignmentExportData; import jalview.gui.AlignmentPanel; @@ -329,7 +330,14 @@ public abstract class HTMLOutput implements Runnable e.printStackTrace(); return; } - new Thread(this).start(); + if (Jalview.isHeadlessMode()) + { + this.run(); + } + else + { + new Thread(this).start(); + } } diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index 24320b5..594b3a3 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -1594,4 +1594,14 @@ public class StructureSelectionManager } } + public Map getPdbFileNameIdMap() + { + return pdbFileNameId; + } + + public Map getPdbIdFileNameMap() + { + return pdbIdFileName; + } + } diff --git a/src/jalview/structure/StructureSelectionManager.java~ b/src/jalview/structure/StructureSelectionManager.java~ deleted file mode 100644 index 5b06097..0000000 --- a/src/jalview/structure/StructureSelectionManager.java~ +++ /dev/null @@ -1,1327 +0,0 @@ -/* - * 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.structure; - -import jalview.analysis.AlignSeq; -import jalview.api.StructureSelectionManagerProvider; -import jalview.commands.CommandI; -import jalview.commands.EditCommand; -import jalview.commands.OrderCommand; -import jalview.datamodel.AlignedCodonFrame; -import jalview.datamodel.AlignmentAnnotation; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.Annotation; -import jalview.datamodel.PDBEntry; -import jalview.datamodel.SearchResults; -import jalview.datamodel.SequenceI; -import jalview.gui.IProgressIndicator; -import jalview.io.AppletFormatAdapter; -import jalview.io.StructureFile; -import jalview.util.MappingUtils; -import jalview.util.MessageManager; -import jalview.ws.sifts.SiftsClient; -import jalview.ws.sifts.SiftsException; -import jalview.ws.sifts.SiftsSettings; - -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -import MCview.Atom; -import MCview.PDBChain; -import MCview.PDBfile; - -public class StructureSelectionManager -{ - public final static String NEWLINE = System.lineSeparator(); - - static IdentityHashMap instances; - - private List mappings = new ArrayList(); - - private boolean processSecondaryStructure = false; - - private boolean secStructServices = false; - - private boolean addTempFacAnnot = false; - - private SiftsClient siftsClient = null; - - /* - * Set of any registered mappings between (dataset) sequences. - */ - private List seqmappings = new ArrayList(); - - private List commandListeners = new ArrayList(); - - private List sel_listeners = new ArrayList(); - - /** - * @return true if will try to use external services for processing secondary - * structure - */ - public boolean isSecStructServices() - { - return secStructServices; - } - - /** - * control use of external services for processing secondary structure - * - * @param secStructServices - */ - public void setSecStructServices(boolean secStructServices) - { - this.secStructServices = secStructServices; - } - - /** - * flag controlling addition of any kind of structural annotation - * - * @return true if temperature factor annotation will be added - */ - public boolean isAddTempFacAnnot() - { - return addTempFacAnnot; - } - - /** - * set flag controlling addition of structural annotation - * - * @param addTempFacAnnot - */ - public void setAddTempFacAnnot(boolean addTempFacAnnot) - { - this.addTempFacAnnot = addTempFacAnnot; - } - - /** - * - * @return if true, the structure manager will attempt to add secondary - * structure lines for unannotated sequences - */ - - public boolean isProcessSecondaryStructure() - { - return processSecondaryStructure; - } - - /** - * Control whether structure manager will try to annotate mapped sequences - * with secondary structure from PDB data. - * - * @param enable - */ - public void setProcessSecondaryStructure(boolean enable) - { - processSecondaryStructure = enable; - } - - /** - * debug function - write all mappings to stdout - */ - public void reportMapping() - { - if (mappings.isEmpty()) - { - System.err.println("reportMapping: No PDB/Sequence mappings."); - } - else - { - System.err.println("reportMapping: There are " + mappings.size() - + " mappings."); - int i = 0; - for (StructureMapping sm : mappings) - { - System.err.println("mapping " + i++ + " : " + sm.pdbfile); - } - } - } - - /** - * map between the PDB IDs (or structure identifiers) used by Jalview and the - * absolute filenames for PDB data that corresponds to it - */ - Map pdbIdFileName = new HashMap(); - - Map pdbFileNameId = new HashMap(); - - public void registerPDBFile(String idForFile, String absoluteFile) - { - pdbIdFileName.put(idForFile, absoluteFile); - pdbFileNameId.put(absoluteFile, idForFile); - } - - public String findIdForPDBFile(String idOrFile) - { - String id = pdbFileNameId.get(idOrFile); - return id; - } - - public String findFileForPDBId(String idOrFile) - { - String id = pdbIdFileName.get(idOrFile); - return id; - } - - public boolean isPDBFileRegistered(String idOrFile) - { - return pdbFileNameId.containsKey(idOrFile) - || pdbIdFileName.containsKey(idOrFile); - } - - private static StructureSelectionManager nullProvider = null; - - public static StructureSelectionManager getStructureSelectionManager( - StructureSelectionManagerProvider context) - { - if (context == null) - { - if (nullProvider == null) - { - if (instances != null) - { - throw new Error( - MessageManager - .getString("error.implementation_error_structure_selection_manager_null"), - new NullPointerException(MessageManager - .getString("exception.ssm_context_is_null"))); - } - else - { - nullProvider = new StructureSelectionManager(); - } - return nullProvider; - } - } - if (instances == null) - { - instances = new java.util.IdentityHashMap(); - } - StructureSelectionManager instance = instances.get(context); - if (instance == null) - { - if (nullProvider != null) - { - instance = nullProvider; - } - else - { - instance = new StructureSelectionManager(); - } - instances.put(context, instance); - } - return instance; - } - - /** - * flag controlling whether SeqMappings are relayed from received sequence - * mouse over events to other sequences - */ - boolean relaySeqMappings = true; - - /** - * Enable or disable relay of seqMapping events to other sequences. You might - * want to do this if there are many sequence mappings and the host computer - * is slow - * - * @param relay - */ - public void setRelaySeqMappings(boolean relay) - { - relaySeqMappings = relay; - } - - /** - * get the state of the relay seqMappings flag. - * - * @return true if sequence mouse overs are being relayed to other mapped - * sequences - */ - public boolean isRelaySeqMappingsEnabled() - { - return relaySeqMappings; - } - - Vector listeners = new Vector(); - - /** - * register a listener for alignment sequence mouseover events - * - * @param svl - */ - public void addStructureViewerListener(Object svl) - { - if (!listeners.contains(svl)) - { - listeners.addElement(svl); - } - } - - /** - * Returns the file name for a mapped PDB id (or null if not mapped). - * - * @param pdbid - * @return - */ - public String alreadyMappedToFile(String pdbid) - { - for (StructureMapping sm : mappings) - { - if (sm.getPdbId().equals(pdbid)) - { - return sm.pdbfile; - } - } - return null; - } - - /** - * Import structure data and register a structure mapping for broadcasting - * colouring, mouseovers and selection events (convenience wrapper). - * - * @param sequence - * - one or more sequences to be mapped to pdbFile - * @param targetChains - * - optional chain specification for mapping each sequence to pdb - * (may be nill, individual elements may be nill) - * @param pdbFile - * - structure data resource - * @param protocol - * - how to resolve data from resource - * @return null or the structure data parsed as a pdb file - */ - synchronized public StructureFile setMapping(SequenceI[] sequence, - String[] targetChains, String pdbFile, String protocol, - IProgressIndicator progress) - { - return computeMapping(true, sequence, targetChains, pdbFile, protocol, - progress); - } - - - /** - * create sequence structure mappings between each sequence and the given - * pdbFile (retrieved via the given protocol). - * - * @param forStructureView - * when true, record the mapping for use in mouseOvers - * - * @param sequenceArray - * - one or more sequences to be mapped to pdbFile - * @param targetChainIds - * - optional chain specification for mapping each sequence to pdb - * (may be null, individual elements may be null) - * @param pdbFile - * - structure data resource - * @param protocol - * - how to resolve data from resource - * @return null or the structure data parsed as a pdb file - */ - synchronized public StructureFile setMapping(boolean forStructureView, - SequenceI[] sequenceArray, String[] targetChainIds, - String pdbFile, - String protocol) - { - return computeMapping(forStructureView, sequenceArray, targetChainIds, - pdbFile, protocol, null); - } - - synchronized public StructureFile computeMapping( - boolean forStructureView, SequenceI[] sequenceArray, - String[] targetChainIds, String pdbFile, String protocol, - IProgressIndicator progress) - { - long progressSessionId = System.currentTimeMillis() * 3; - /* - * There will be better ways of doing this in the future, for now we'll use - * the tried and tested MCview pdb mapping - */ - boolean parseSecStr = processSecondaryStructure; - if (isPDBFileRegistered(pdbFile)) - { - for (SequenceI sq : sequenceArray) - { - SequenceI ds = sq; - while (ds.getDatasetSequence() != null) - { - ds = ds.getDatasetSequence(); - } - ; - if (ds.getAnnotation() != null) - { - for (AlignmentAnnotation ala : ds.getAnnotation()) - { - // false if any annotation present from this structure - // JBPNote this fails for jmol/chimera view because the *file* is - // passed, not the structure data ID - - if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile))) - { - parseSecStr = false; - } - } - } - } - } - StructureFile pdb = null; - boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts(); - try - { - - if (pdbFile != null && isCIFFile(pdbFile)) - { - pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr, - secStructServices, pdbFile, protocol); - } - else - { - pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices, - pdbFile, protocol); - } - - if (pdb.getId() != null && pdb.getId().trim().length() > 0 - && AppletFormatAdapter.FILE.equals(protocol)) - { - registerPDBFile(pdb.getId().trim(), pdbFile); - } - } catch (Exception ex) - { - ex.printStackTrace(); - return null; - } - - try - { - if (isMapUsingSIFTs) - { - siftsClient = new SiftsClient(pdb); - } - } catch (SiftsException e) - { - isMapUsingSIFTs = false; - e.printStackTrace(); - } - - String targetChainId; - for (int s = 0; s < sequenceArray.length; s++) - { - boolean infChain = true; - final SequenceI seq = sequenceArray[s]; - if (targetChainIds != null && targetChainIds[s] != null) - { - infChain = false; - targetChainId = targetChainIds[s]; - } - else if (seq.getName().indexOf("|") > -1) - { - targetChainId = seq.getName().substring( - seq.getName().lastIndexOf("|") + 1); - if (targetChainId.length() > 1) - { - if (targetChainId.trim().length() == 0) - { - targetChainId = " "; - } - else - { - // not a valid chain identifier - targetChainId = ""; - } - } - } - else - { - targetChainId = ""; - } - - /* - * Attempt pairwise alignment of the sequence with each chain in the PDB, - * and remember the highest scoring chain - */ - int max = -10; - AlignSeq maxAlignseq = null; - String maxChainId = " "; - PDBChain maxChain = null; - boolean first = true; - for (PDBChain chain : pdb.getChains()) - { - if (targetChainId.length() > 0 && !targetChainId.equals(chain.id) - && !infChain) - { - continue; // don't try to map chains don't match. - } - // TODO: correctly determine sequence type for mixed na/peptide - // structures - final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP; - AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence, - type); - // equivalent to: - // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type); - // as.calcScoreMatrix(); - // as.traceAlignment(); - - if (first || as.maxscore > max - || (as.maxscore == max && chain.id.equals(targetChainId))) - { - first = false; - maxChain = chain; - max = as.maxscore; - maxAlignseq = as; - maxChainId = chain.id; - } - } - if (maxChain == null) - { - continue; - } - - if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE)) - { - pdbFile = "INLINE" + pdb.getId(); - } - ArrayList seqToStrucMapping = new ArrayList(); - if (isMapUsingSIFTs) - { -<<<<<<< Updated upstream - setProgressBar(null); - setProgressBar(MessageManager - .getString("status.obtaining_mapping_with_sifts")); -======= - if (progress!=null) { - progress.setProgressBar("Obtaining mapping with SIFTS", - progressSessionId); - } ->>>>>>> Stashed changes - jalview.datamodel.Mapping sqmpping = maxAlignseq - .getMappingFromS1(false); - if (targetChainId != null && !targetChainId.trim().isEmpty()) - { - StructureMapping siftsMapping; - try - { - siftsMapping = getStructureMapping(seq, pdbFile, targetChainId, - pdb, maxChain, sqmpping, maxAlignseq); - seqToStrucMapping.add(siftsMapping); - maxChain.makeExactMapping(maxAlignseq, seq); - maxChain.transferRESNUMFeatures(seq, null); - maxChain.transferResidueAnnotation(siftsMapping, sqmpping); - } catch (SiftsException e) - { - // fall back to NW alignment - System.err.println(e.getMessage()); - StructureMapping nwMapping = getNWMappings(seq, pdbFile, - targetChainId, maxChain, pdb, maxAlignseq); - seqToStrucMapping.add(nwMapping); - } - } - else - { - ArrayList foundSiftsMappings = new ArrayList(); - for (PDBChain chain : pdb.getChains()) - { - try - { - StructureMapping siftsMapping = getStructureMapping(seq, - pdbFile, - chain.id, pdb, chain, sqmpping, maxAlignseq); - foundSiftsMappings.add(siftsMapping); - } catch (SiftsException e) - { - System.err.println(e.getMessage()); - } - } - if (!foundSiftsMappings.isEmpty()) - { - seqToStrucMapping.addAll(foundSiftsMappings); - maxChain.makeExactMapping(maxAlignseq, seq); - maxChain.transferRESNUMFeatures(seq, null); - maxChain.transferResidueAnnotation(foundSiftsMappings.get(0), - sqmpping); - } - else - { - StructureMapping nwMapping = getNWMappings(seq, pdbFile, - maxChainId, maxChain, pdb, maxAlignseq); - seqToStrucMapping.add(nwMapping); - } - } - } - else - { -<<<<<<< Updated upstream - setProgressBar(null); - setProgressBar(MessageManager - .getString("status.obtaining_mapping_with_nw_alignment")); -======= - if (progress != null) - { - progress.setProgressBar("Obtaining mapping with NW alignment", - progressSessionId); - } ->>>>>>> Stashed changes - seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId, - maxChain, pdb, maxAlignseq)); - } - if (forStructureView) - { - mappings.addAll(seqToStrucMapping); - } - if (progress != null) - { - progress.setProgressBar(null, progressSessionId); - } - } - return pdb; - } - - private boolean isCIFFile(String filename) - { - String fileExt = filename.substring(filename.lastIndexOf(".") + 1, - filename.length()); - return "cif".equalsIgnoreCase(fileExt); - } - - private StructureMapping getStructureMapping(SequenceI seq, - String pdbFile, String targetChainId, StructureFile pdb, - PDBChain maxChain, jalview.datamodel.Mapping sqmpping, - AlignSeq maxAlignseq) throws SiftsException - { - StructureMapping curChainMapping = siftsClient - .getSiftsStructureMapping(seq, pdbFile, targetChainId); - try - { - PDBChain chain = pdb.findChain(targetChainId); - if (chain != null) - { - chain.transferResidueAnnotation(curChainMapping, sqmpping); - } - } catch (Exception e) - { - e.printStackTrace(); - } - return curChainMapping; - } - - private StructureMapping getNWMappings(SequenceI seq, - String pdbFile, - String maxChainId, PDBChain maxChain, StructureFile pdb, - AlignSeq maxAlignseq) - { - final StringBuilder mappingDetails = new StringBuilder(128); - mappingDetails.append(NEWLINE).append( - "Sequence \u27f7 Structure mapping details"); - mappingDetails.append(NEWLINE); - mappingDetails - .append("Method: inferred with Needleman & Wunsch alignment"); - mappingDetails.append(NEWLINE).append("PDB Sequence is :") - .append(NEWLINE).append("Sequence = ") - .append(maxChain.sequence.getSequenceAsString()); - mappingDetails.append(NEWLINE).append("No of residues = ") - .append(maxChain.residues.size()).append(NEWLINE) - .append(NEWLINE); - PrintStream ps = new PrintStream(System.out) - { - @Override - public void print(String x) - { - mappingDetails.append(x); - } - - @Override - public void println() - { - mappingDetails.append(NEWLINE); - } - }; - - maxAlignseq.printAlignment(ps); - - mappingDetails.append(NEWLINE).append("PDB start/end "); - mappingDetails.append(String.valueOf(maxAlignseq.seq2start)) - .append(" "); - mappingDetails.append(String.valueOf(maxAlignseq.seq2end)); - mappingDetails.append(NEWLINE).append("SEQ start/end "); - mappingDetails.append( - String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1))) - .append(" "); - mappingDetails.append(String.valueOf(maxAlignseq.seq1end - + (seq.getStart() - 1))); - mappingDetails.append(NEWLINE); - maxChain.makeExactMapping(maxAlignseq, seq); - jalview.datamodel.Mapping sqmpping = maxAlignseq - .getMappingFromS1(false); - maxChain.transferRESNUMFeatures(seq, null); - - HashMap mapping = new HashMap(); - int resNum = -10000; - int index = 0; - char insCode = ' '; - - do - { - Atom tmp = maxChain.atoms.elementAt(index); - if ((resNum != tmp.resNumber || insCode != tmp.insCode) - && tmp.alignmentMapping != -1) - { - resNum = tmp.resNumber; - insCode = tmp.insCode; - if (tmp.alignmentMapping >= -1) - { - mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber, - tmp.atomIndex }); - } - } - - index++; - } while (index < maxChain.atoms.size()); - - StructureMapping nwMapping = new StructureMapping(seq, pdbFile, - pdb.getId(), maxChainId, mapping, mappingDetails.toString()); - maxChain.transferResidueAnnotation(nwMapping, sqmpping); - return nwMapping; - } - - public void removeStructureViewerListener(Object svl, String[] pdbfiles) - { - listeners.removeElement(svl); - if (svl instanceof SequenceListener) - { - for (int i = 0; i < listeners.size(); i++) - { - if (listeners.elementAt(i) instanceof StructureListener) - { - ((StructureListener) listeners.elementAt(i)) - .releaseReferences(svl); - } - } - } - - if (pdbfiles == null) - { - return; - } - - /* - * Remove mappings to the closed listener's PDB files, but first check if - * another listener is still interested - */ - List pdbs = new ArrayList(Arrays.asList(pdbfiles)); - - StructureListener sl; - for (int i = 0; i < listeners.size(); i++) - { - if (listeners.elementAt(i) instanceof StructureListener) - { - sl = (StructureListener) listeners.elementAt(i); - for (String pdbfile : sl.getPdbFile()) - { - pdbs.remove(pdbfile); - } - } - } - - /* - * Rebuild the mappings set, retaining only those which are for 'other' PDB - * files - */ - if (pdbs.size() > 0) - { - List tmp = new ArrayList(); - for (StructureMapping sm : mappings) - { - if (!pdbs.contains(sm.pdbfile)) - { - tmp.add(sm); - } - } - - mappings = tmp; - } - } - - /** - * Propagate mouseover of a single position in a structure - * - * @param pdbResNum - * @param chain - * @param pdbfile - */ - public void mouseOverStructure(int pdbResNum, String chain, String pdbfile) - { - AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0); - List atoms = Collections.singletonList(atomSpec); - mouseOverStructure(atoms); - } - - /** - * Propagate mouseover or selection of multiple positions in a structure - * - * @param atoms - */ - public void mouseOverStructure(List atoms) - { - if (listeners == null) - { - // old or prematurely sent event - return; - } - boolean hasSequenceListener = false; - for (int i = 0; i < listeners.size(); i++) - { - if (listeners.elementAt(i) instanceof SequenceListener) - { - hasSequenceListener = true; - } - } - if (!hasSequenceListener) - { - return; - } - - SearchResults results = new SearchResults(); - for (AtomSpec atom : atoms) - { - SequenceI lastseq = null; - int lastipos = -1; - for (StructureMapping sm : mappings) - { - if (sm.pdbfile.equals(atom.getPdbFile()) - && sm.pdbchain.equals(atom.getChain())) - { - int indexpos = sm.getSeqPos(atom.getPdbResNum()); - if (lastipos != indexpos && lastseq != sm.sequence) - { - results.addResult(sm.sequence, indexpos, indexpos); - lastipos = indexpos; - lastseq = sm.sequence; - // construct highlighted sequence list - for (AlignedCodonFrame acf : seqmappings) - { - acf.markMappedRegion(sm.sequence, indexpos, results); - } - } - } - } - } - for (Object li : listeners) - { - if (li instanceof SequenceListener) - { - ((SequenceListener) li).highlightSequence(results); - } - } - } - - /** - * highlight regions associated with a position (indexpos) in seq - * - * @param seq - * the sequence that the mouse over occurred on - * @param indexpos - * the absolute position being mouseovered in seq (0 to seq.length()) - * @param seqPos - * the sequence position (if -1, seq.findPosition is called to - * resolve the residue number) - */ - public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos, - VamsasSource source) - { - boolean hasSequenceListeners = handlingVamsasMo - || !seqmappings.isEmpty(); - SearchResults results = null; - if (seqPos == -1) - { - seqPos = seq.findPosition(indexpos); - } - for (int i = 0; i < listeners.size(); i++) - { - Object listener = listeners.elementAt(i); - if (listener == source) - { - // TODO listener (e.g. SeqPanel) is never == source (AlignViewport) - // Temporary fudge with SequenceListener.getVamsasSource() - continue; - } - if (listener instanceof StructureListener) - { - highlightStructure((StructureListener) listener, seq, seqPos); - } - else - { - if (listener instanceof SequenceListener) - { - final SequenceListener seqListener = (SequenceListener) listener; - if (hasSequenceListeners - && seqListener.getVamsasSource() != source) - { - if (relaySeqMappings) - { - if (results == null) - { - results = MappingUtils.buildSearchResults(seq, seqPos, - seqmappings); - } - if (handlingVamsasMo) - { - results.addResult(seq, seqPos, seqPos); - - } - if (!results.isEmpty()) - { - seqListener.highlightSequence(results); - } - } - } - } - else if (listener instanceof VamsasListener && !handlingVamsasMo) - { - ((VamsasListener) listener).mouseOverSequence(seq, indexpos, - source); - } - else if (listener instanceof SecondaryStructureListener) - { - ((SecondaryStructureListener) listener).mouseOverSequence(seq, - indexpos, seqPos); - } - } - } - } - - /** - * Send suitable messages to a StructureListener to highlight atoms - * corresponding to the given sequence position(s) - * - * @param sl - * @param seq - * @param positions - */ - public void highlightStructure(StructureListener sl, SequenceI seq, - int... positions) - { - if (!sl.isListeningFor(seq)) - { - return; - } - int atomNo; - List atoms = new ArrayList(); - for (StructureMapping sm : mappings) - { - if (sm.sequence == seq - || sm.sequence == seq.getDatasetSequence() - || (sm.sequence.getDatasetSequence() != null && sm.sequence - .getDatasetSequence() == seq.getDatasetSequence())) - { - for (int index : positions) - { - atomNo = sm.getAtomNum(index); - - if (atomNo > 0) - { - atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm - .getPDBResNum(index), atomNo)); - } - } - } - } - sl.highlightAtoms(atoms); - } - - /** - * true if a mouse over event from an external (ie Vamsas) source is being - * handled - */ - boolean handlingVamsasMo = false; - - long lastmsg = 0; - - /** - * as mouseOverSequence but only route event to SequenceListeners - * - * @param sequenceI - * @param position - * in an alignment sequence - */ - public void mouseOverVamsasSequence(SequenceI sequenceI, int position, - VamsasSource source) - { - handlingVamsasMo = true; - long msg = sequenceI.hashCode() * (1 + position); - if (lastmsg != msg) - { - lastmsg = msg; - mouseOverSequence(sequenceI, position, -1, source); - } - handlingVamsasMo = false; - } - - public Annotation[] colourSequenceFromStructure(SequenceI seq, - String pdbid) - { - return null; - // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3, - // UNTIL THE COLOUR BY ANNOTATION IS REWORKED - /* - * Annotation [] annotations = new Annotation[seq.getLength()]; - * - * StructureListener sl; int atomNo = 0; for (int i = 0; i < - * listeners.size(); i++) { if (listeners.elementAt(i) instanceof - * StructureListener) { sl = (StructureListener) listeners.elementAt(i); - * - * for (int j = 0; j < mappings.length; j++) { - * - * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid) - * && mappings[j].pdbfile.equals(sl.getPdbFile())) { - * System.out.println(pdbid+" "+mappings[j].getPdbId() +" - * "+mappings[j].pdbfile); - * - * java.awt.Color col; for(int index=0; index 0) { col = sl.getColour(atomNo, - * mappings[j].getPDBResNum(index), mappings[j].pdbchain, - * mappings[j].pdbfile); } - * - * annotations[index] = new Annotation("X",null,' ',0,col); } return - * annotations; } } } } - * - * return annotations; - */ - } - - public void structureSelectionChanged() - { - } - - public void sequenceSelectionChanged() - { - } - - public void sequenceColoursChanged(Object source) - { - StructureListener sl; - for (int i = 0; i < listeners.size(); i++) - { - if (listeners.elementAt(i) instanceof StructureListener) - { - sl = (StructureListener) listeners.elementAt(i); - sl.updateColours(source); - } - } - } - - public StructureMapping[] getMapping(String pdbfile) - { - List tmp = new ArrayList(); - for (StructureMapping sm : mappings) - { - if (sm.pdbfile.equals(pdbfile)) - { - tmp.add(sm); - } - } - return tmp.toArray(new StructureMapping[tmp.size()]); - } - - /** - * Returns a readable description of all mappings for the given pdbfile to any - * of the given sequences - * - * @param pdbfile - * @param seqs - * @return - */ - public String printMappings(String pdbfile, List seqs) - { - if (pdbfile == null || seqs == null || seqs.isEmpty()) - { - return ""; - } - - StringBuilder sb = new StringBuilder(64); - for (StructureMapping sm : mappings) - { - if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence)) - { - sb.append(sm.mappingDetails); - sb.append(NEWLINE); - // separator makes it easier to read multiple mappings - sb.append("====================="); - sb.append(NEWLINE); - } - } - sb.append(NEWLINE); - - return sb.toString(); - } - - /** - * Remove the given mapping - * - * @param acf - */ - public void deregisterMapping(AlignedCodonFrame acf) - { - if (acf != null) - { - boolean removed = seqmappings.remove(acf); - if (removed && seqmappings.isEmpty()) - { // debug - System.out.println("All mappings removed"); - } - } - } - - /** - * Add each of the given codonFrames to the stored set, if not aready present. - * - * @param mappings - */ - public void registerMappings(List mappings) - { - if (mappings != null) - { - for (AlignedCodonFrame acf : mappings) - { - registerMapping(acf); - } - } - } - - /** - * Add the given mapping to the stored set, unless already stored. - */ - public void registerMapping(AlignedCodonFrame acf) - { - if (acf != null) - { - if (!seqmappings.contains(acf)) - { - seqmappings.add(acf); - } - } - } - - /** - * Resets this object to its initial state by removing all registered - * listeners, codon mappings, PDB file mappings - */ - public void resetAll() - { - if (mappings != null) - { - mappings.clear(); - } - if (seqmappings != null) - { - seqmappings.clear(); - } - if (sel_listeners != null) - { - sel_listeners.clear(); - } - if (listeners != null) - { - listeners.clear(); - } - if (commandListeners != null) - { - commandListeners.clear(); - } - if (view_listeners != null) - { - view_listeners.clear(); - } - if (pdbFileNameId != null) - { - pdbFileNameId.clear(); - } - if (pdbIdFileName != null) - { - pdbIdFileName.clear(); - } - } - - public void addSelectionListener(SelectionListener selecter) - { - if (!sel_listeners.contains(selecter)) - { - sel_listeners.add(selecter); - } - } - - public void removeSelectionListener(SelectionListener toremove) - { - if (sel_listeners.contains(toremove)) - { - sel_listeners.remove(toremove); - } - } - - public synchronized void sendSelection( - jalview.datamodel.SequenceGroup selection, - jalview.datamodel.ColumnSelection colsel, SelectionSource source) - { - for (SelectionListener slis : sel_listeners) - { - if (slis != source) - { - slis.selection(selection, colsel, source); - } - } - } - - Vector view_listeners = new Vector(); - - public synchronized void sendViewPosition( - jalview.api.AlignmentViewPanel source, int startRes, int endRes, - int startSeq, int endSeq) - { - - if (view_listeners != null && view_listeners.size() > 0) - { - Enumeration listeners = view_listeners - .elements(); - while (listeners.hasMoreElements()) - { - AlignmentViewPanelListener slis = listeners.nextElement(); - if (slis != source) - { - slis.viewPosition(startRes, endRes, startSeq, endSeq, source); - } - ; - } - } - } - - /** - * release all references associated with this manager provider - * - * @param jalviewLite - */ - public static void release(StructureSelectionManagerProvider jalviewLite) - { - // synchronized (instances) - { - if (instances == null) - { - return; - } - StructureSelectionManager mnger = (instances.get(jalviewLite)); - if (mnger != null) - { - instances.remove(jalviewLite); - try - { - mnger.finalize(); - } catch (Throwable x) - { - } - } - } - } - - public void registerPDBEntry(PDBEntry pdbentry) - { - if (pdbentry.getFile() != null - && pdbentry.getFile().trim().length() > 0) - { - registerPDBFile(pdbentry.getId(), pdbentry.getFile()); - } - } - - public void addCommandListener(CommandListener cl) - { - if (!commandListeners.contains(cl)) - { - commandListeners.add(cl); - } - } - - public boolean hasCommandListener(CommandListener cl) - { - return this.commandListeners.contains(cl); - } - - public boolean removeCommandListener(CommandListener l) - { - return commandListeners.remove(l); - } - - /** - * Forward a command to any command listeners (except for the command's - * source). - * - * @param command - * the command to be broadcast (in its form after being performed) - * @param undo - * if true, the command was being 'undone' - * @param source - */ - public void commandPerformed(CommandI command, boolean undo, - VamsasSource source) - { - for (CommandListener listener : commandListeners) - { - listener.mirrorCommand(command, undo, this, source); - } - } - - /** - * Returns a new CommandI representing the given command as mapped to the - * given sequences. If no mapping could be made, or the command is not of a - * mappable kind, returns null. - * - * @param command - * @param undo - * @param mapTo - * @param gapChar - * @return - */ - public CommandI mapCommand(CommandI command, boolean undo, - final AlignmentI mapTo, char gapChar) - { - if (command instanceof EditCommand) - { - return MappingUtils.mapEditCommand((EditCommand) command, undo, - mapTo, gapChar, seqmappings); - } - else if (command instanceof OrderCommand) - { - return MappingUtils.mapOrderCommand((OrderCommand) command, undo, - mapTo, seqmappings); - } - return null; - } - - public List getSequenceMappings() - { - return seqmappings; - } - -} diff --git a/src/jalview/ws/dbsources/EBIAlfaFold.java b/src/jalview/ws/dbsources/EBIAlfaFold.java index 859ac05..e5f1243 100644 --- a/src/jalview/ws/dbsources/EBIAlfaFold.java +++ b/src/jalview/ws/dbsources/EBIAlfaFold.java @@ -36,6 +36,7 @@ import com.stevesoft.pat.Regex; import jalview.api.FeatureSettingsModelI; import jalview.bin.Console; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.ContactMatrixI; @@ -49,6 +50,7 @@ import jalview.io.FileFormat; import jalview.io.FileFormatI; import jalview.io.FormatAdapter; import jalview.io.PDBFeatureSettings; +import jalview.structure.StructureMapping; import jalview.structure.StructureSelectionManager; import jalview.util.MessageManager; import jalview.util.Platform; @@ -257,48 +259,85 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy public static void addAlphaFoldPAEToSequence(AlignmentI pdbAlignment, File pae, int index, String seqId) { - FileInputStream pae_input = null; + addAlphaFoldPAE(pdbAlignment, pae, index, seqId, false, false); + } + + public static void addAlphaFoldPAEToStructure(AlignmentI pdbAlignment, + File pae, int index, String structIdOrFile, boolean isStructId) + { + addAlphaFoldPAE(pdbAlignment, pae, index, structIdOrFile, true, + isStructId); + } + + public static void addAlphaFoldPAE(AlignmentI pdbAlignment, File pae, + int index, String id, boolean isStruct, boolean isStructId) + { + FileInputStream paeInput = null; try { - pae_input = new FileInputStream(pae); + paeInput = new FileInputStream(pae); } catch (FileNotFoundException e) { Console.error( "Could not find pAE file '" + pae.getAbsolutePath() + "'", e); + return; } - try + if (isStruct) { - if (!importPaeJSONAsContactMatrix(pdbAlignment, pae_input, index, - seqId)) + StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + if (ssm != null) { - Console.warn("Could not import contact matrix from '" - + pae.getAbsolutePath() + "'"); - } - } catch (IOException e1) - { - Console.error("Error when importing pAE file '" - + pae.getAbsolutePath() + "'", e1); - } catch (ParseException e2) - { - Console.error( - "Error when parsing pAE file '" + pae.getAbsolutePath() + "'", - e2); - } + String structFile = isStructId ? ssm.findFileForPDBId(id) : id; + Console.debug("##### AHA! structFile = " + structFile); + Console.debug("##### structFile " + + (ssm.isPDBFileRegistered(structFile) ? "IS " : "is NOT ") + + "registered."); - } + StructureMapping[] smArray = ssm.getMapping(structFile); + Console.debug("##### AHA! smArray obtained with " + smArray.length + + " elements"); - public static void addAlphaFoldPAEToStructure(AlignmentI pdbAlignment, - File pae, int index, String structId) - { - StructureSelectionManager ssm = StructureSelectionManager - .getStructureSelectionManager(Desktop.instance); - if (ssm != null) + try + { + if (!importPaeJSONAsContactMatrixToStructure(smArray, paeInput)) + { + Console.warn("Could not import contact matrix from '" + + pae.getAbsolutePath() + "' to structure."); + } + } catch (IOException e1) + { + Console.error("Error when importing pAE file '" + + pae.getAbsolutePath() + "'", e1); + } catch (ParseException e2) + { + Console.error("Error when parsing pAE file '" + + pae.getAbsolutePath() + "'", e2); + } + } + + } + else { - /* - ssm.setAddTempFacAnnot(showTemperatureFactor); - ssm.setProcessSecondaryStructure(showSecondaryStructure); - */ + // attach to sequence?! + try + { + if (!importPaeJSONAsContactMatrixToSequence(pdbAlignment, paeInput, + index, id)) + { + Console.warn("Could not import contact matrix from '" + + pae.getAbsolutePath() + "' to sequence."); + } + } catch (IOException e1) + { + Console.error("Error when importing pAE file '" + + pae.getAbsolutePath() + "'", e1); + } catch (ParseException e2) + { + Console.error("Error when parsing pAE file '" + + pae.getAbsolutePath() + "'", e2); + } } } @@ -314,24 +353,18 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy * @throws IOException * @throws Exception */ - public static boolean importPaeJSONAsContactMatrix( + public static boolean importPaeJSONAsContactMatrixToSequence( AlignmentI pdbAlignment, InputStream pae_input) throws IOException, ParseException { - return importPaeJSONAsContactMatrix(pdbAlignment, pae_input, 0, null); + return importPaeJSONAsContactMatrixToSequence(pdbAlignment, pae_input, + 0, null); } - public static boolean importPaeJSONAsContactMatrix( + public static boolean importPaeJSONAsContactMatrixToSequence( AlignmentI pdbAlignment, InputStream pae_input, int index, String seqId) throws IOException, ParseException { - - List pae_obj = (List) Platform.parseJSON(pae_input); - if (pae_obj == null) - { - Console.debug("JSON file did not parse properly."); - return false; - } SequenceI sequence = null; /* debugging */ SequenceI[] seqs = pdbAlignment.getSequencesArray(); @@ -369,6 +402,13 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy sequence = sequences[0]; // just use the first sequence with this seqId } } + + List pae_obj = (List) Platform.parseJSON(pae_input); + if (pae_obj == null) + { + Console.debug("JSON file did not parse properly."); + return false; + } ContactMatrixI matrix = new PAEContactMatrix(sequence, (Map) pae_obj.get(0)); @@ -377,6 +417,50 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy return true; } + public static boolean importPaeJSONAsContactMatrixToStructure( + StructureMapping[] smArray, InputStream paeInput) + throws IOException, ParseException + { + boolean someDone = false; + Console.debug("##### smArray.length=" + smArray.length); + for (StructureMapping sm : smArray) + { + Console.debug("##### sm[n]=" + sm.getPdbId()); + boolean thisDone = importPaeJSONAsContactMatrixToStructure(sm, + paeInput); + Console.debug("##### thisDone = " + thisDone); + someDone |= thisDone; + } + return someDone; + } + + public static boolean importPaeJSONAsContactMatrixToStructure( + StructureMapping sm, InputStream paeInput) + throws IOException, ParseException + { + + List pae_obj = (List) Platform.parseJSON(paeInput); + if (pae_obj == null) + { + Console.debug("JSON file did not parse properly."); + return false; + } + + ContactMatrixI matrix = new PAEContactMatrix(sm.getSequence(), + (Map) pae_obj.get(0)); + + AlignmentAnnotation cmannot = sm.getSequence().addContactList(matrix); + // sm.getSequence().addAlignmentAnnotation(cmannot); + sm.transfer(cmannot); + // return true; + + StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + List acfList = ssm.getSequenceMappings(); + + return true; + } + /** * general purpose structure importer - designed to yield alignment useful for * transfer of annotation to associated sequences -- 1.7.10.2