2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.structure;
23 import jalview.analysis.AlignSeq;
24 import jalview.api.StructureSelectionManagerProvider;
25 import jalview.commands.CommandI;
26 import jalview.commands.EditCommand;
27 import jalview.commands.OrderCommand;
28 import jalview.datamodel.AlignedCodonFrame;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.Annotation;
32 import jalview.datamodel.PDBEntry;
33 import jalview.datamodel.SearchResults;
34 import jalview.datamodel.SearchResultsI;
35 import jalview.datamodel.SequenceI;
36 import jalview.ext.jmol.JmolParser;
37 import jalview.gui.IProgressIndicator;
38 import jalview.io.DataSourceType;
39 import jalview.io.StructureFile;
40 import jalview.util.MappingUtils;
41 import jalview.util.MessageManager;
42 import jalview.ws.phyre2.Phyre2Client;
43 import jalview.ws.sifts.SiftsClient;
44 import jalview.ws.sifts.SiftsException;
45 import jalview.ws.sifts.SiftsSettings;
47 import java.io.PrintStream;
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.Collections;
51 import java.util.Enumeration;
52 import java.util.HashMap;
53 import java.util.IdentityHashMap;
54 import java.util.List;
56 import java.util.Vector;
59 import MCview.PDBChain;
60 import MCview.PDBfile;
62 public class StructureSelectionManager
64 public final static String NEWLINE = System.lineSeparator();
66 static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
68 private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
70 private boolean processSecondaryStructure = false;
72 private boolean secStructServices = false;
74 private boolean addTempFacAnnot = false;
76 private IProgressIndicator progressIndicator;
78 private SiftsClient siftsClient = null;
80 private long progressSessionId;
84 * Set of any registered mappings between (dataset) sequences.
86 private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
88 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
90 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
92 private List<String> phyre2ModelTemplates = new ArrayList<String>();
95 * @return true if will try to use external services for processing secondary
98 public boolean isSecStructServices()
100 return secStructServices;
104 * control use of external services for processing secondary structure
106 * @param secStructServices
108 public void setSecStructServices(boolean secStructServices)
110 this.secStructServices = secStructServices;
114 * flag controlling addition of any kind of structural annotation
116 * @return true if temperature factor annotation will be added
118 public boolean isAddTempFacAnnot()
120 return addTempFacAnnot;
124 * set flag controlling addition of structural annotation
126 * @param addTempFacAnnot
128 public void setAddTempFacAnnot(boolean addTempFacAnnot)
130 this.addTempFacAnnot = addTempFacAnnot;
135 * @return if true, the structure manager will attempt to add secondary
136 * structure lines for unannotated sequences
139 public boolean isProcessSecondaryStructure()
141 return processSecondaryStructure;
145 * Control whether structure manager will try to annotate mapped sequences
146 * with secondary structure from PDB data.
150 public void setProcessSecondaryStructure(boolean enable)
152 processSecondaryStructure = enable;
156 * debug function - write all mappings to stdout
158 public void reportMapping()
160 if (mappings.isEmpty())
162 System.err.println("reportMapping: No PDB/Sequence mappings.");
166 System.err.println("reportMapping: There are " + mappings.size()
169 for (StructureMapping sm : mappings)
171 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
177 * map between the PDB IDs (or structure identifiers) used by Jalview and the
178 * absolute filenames for PDB data that corresponds to it
180 Map<String, String> pdbIdFileName = new HashMap<String, String>();
182 Map<String, String> pdbFileNameId = new HashMap<String, String>();
184 public void registerPDBFile(String idForFile, String absoluteFile)
186 pdbIdFileName.put(idForFile, absoluteFile);
187 pdbFileNameId.put(absoluteFile, idForFile);
190 public String findIdForPDBFile(String idOrFile)
192 String id = pdbFileNameId.get(idOrFile);
196 public String findFileForPDBId(String idOrFile)
198 String id = pdbIdFileName.get(idOrFile);
202 public boolean isPDBFileRegistered(String idOrFile)
204 return pdbFileNameId.containsKey(idOrFile)
205 || pdbIdFileName.containsKey(idOrFile);
208 private static StructureSelectionManager nullProvider = null;
210 public static StructureSelectionManager getStructureSelectionManager(
211 StructureSelectionManagerProvider context)
215 if (nullProvider == null)
217 if (instances != null)
221 .getString("error.implementation_error_structure_selection_manager_null"),
222 new NullPointerException(MessageManager
223 .getString("exception.ssm_context_is_null")));
227 nullProvider = new StructureSelectionManager();
232 if (instances == null)
234 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
236 StructureSelectionManager instance = instances.get(context);
237 if (instance == null)
239 if (nullProvider != null)
241 instance = nullProvider;
245 instance = new StructureSelectionManager();
247 instances.put(context, instance);
253 * flag controlling whether SeqMappings are relayed from received sequence
254 * mouse over events to other sequences
256 boolean relaySeqMappings = true;
259 * Enable or disable relay of seqMapping events to other sequences. You might
260 * want to do this if there are many sequence mappings and the host computer
265 public void setRelaySeqMappings(boolean relay)
267 relaySeqMappings = relay;
271 * get the state of the relay seqMappings flag.
273 * @return true if sequence mouse overs are being relayed to other mapped
276 public boolean isRelaySeqMappingsEnabled()
278 return relaySeqMappings;
281 Vector listeners = new Vector();
284 * register a listener for alignment sequence mouseover events
288 public void addStructureViewerListener(Object svl)
290 if (!listeners.contains(svl))
292 listeners.addElement(svl);
297 * Returns the file name for a mapped PDB id (or null if not mapped).
302 public String alreadyMappedToFile(String pdbid)
304 for (StructureMapping sm : mappings)
306 if (sm.getPdbId().equals(pdbid))
315 * Import structure data and register a structure mapping for broadcasting
316 * colouring, mouseovers and selection events (convenience wrapper).
319 * - one or more sequences to be mapped to pdbFile
320 * @param targetChains
321 * - optional chain specification for mapping each sequence to pdb
322 * (may be nill, individual elements may be nill)
324 * - structure data resource
326 * - how to resolve data from resource
327 * @return null or the structure data parsed as a pdb file
329 synchronized public StructureFile setMapping(SequenceI[] sequence,
330 String[] targetChains, String pdbFile, DataSourceType protocol,
331 IProgressIndicator progress)
333 return computeMapping(true, sequence, targetChains, pdbFile, protocol,
339 * create sequence structure mappings between each sequence and the given
340 * pdbFile (retrieved via the given protocol).
342 * @param forStructureView
343 * when true, record the mapping for use in mouseOvers
345 * @param sequenceArray
346 * - one or more sequences to be mapped to pdbFile
347 * @param targetChainIds
348 * - optional chain specification for mapping each sequence to pdb
349 * (may be null, individual elements may be null)
351 * - structure data resource
353 * - how to resolve data from resource
354 * @return null or the structure data parsed as a pdb file
356 synchronized public StructureFile setMapping(boolean forStructureView,
357 SequenceI[] sequenceArray, String[] targetChainIds,
358 String pdbFile, DataSourceType protocol)
360 return computeMapping(forStructureView, sequenceArray, targetChainIds,
361 pdbFile, protocol, null);
364 synchronized public StructureFile computeMapping(
365 boolean forStructureView, SequenceI[] sequenceArray,
366 String[] targetChainIds, String pdbFile, DataSourceType protocol,
367 IProgressIndicator progress)
369 long progressSessionId = System.currentTimeMillis() * 3;
371 * There will be better ways of doing this in the future, for now we'll use
372 * the tried and tested MCview pdb mapping
374 boolean parseSecStr = processSecondaryStructure;
375 if (isPDBFileRegistered(pdbFile))
377 for (SequenceI sq : sequenceArray)
380 while (ds.getDatasetSequence() != null)
382 ds = ds.getDatasetSequence();
385 if (ds.getAnnotation() != null)
387 for (AlignmentAnnotation ala : ds.getAnnotation())
389 // false if any annotation present from this structure
390 // JBPNote this fails for jmol/chimera view because the *file* is
391 // passed, not the structure data ID -
392 if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
400 StructureFile pdb = null;
401 boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
404 pdb = new JmolParser(pdbFile, protocol);
406 if (pdb.getId() != null && pdb.getId().trim().length() > 0
407 && DataSourceType.FILE == protocol)
409 registerPDBFile(pdb.getId().trim(), pdbFile);
411 // if PDBId is unavailable then skip SIFTS mapping execution path
412 isMapUsingSIFTs = isMapUsingSIFTs && pdb.isPPDBIdAvailable();
414 } catch (Exception ex)
416 ex.printStackTrace();
424 siftsClient = new SiftsClient(pdb);
426 } catch (SiftsException e)
428 isMapUsingSIFTs = false;
432 String targetChainId;
433 for (int s = 0; s < sequenceArray.length; s++)
435 boolean infChain = true;
436 final SequenceI seq = sequenceArray[s];
438 while (ds.getDatasetSequence() != null)
440 ds = ds.getDatasetSequence();
443 if (targetChainIds != null && targetChainIds[s] != null)
446 targetChainId = targetChainIds[s];
448 else if (seq.getName().indexOf("|") > -1)
450 targetChainId = seq.getName().substring(
451 seq.getName().lastIndexOf("|") + 1);
452 if (targetChainId.length() > 1)
454 if (targetChainId.trim().length() == 0)
460 // not a valid chain identifier
471 * Attempt pairwise alignment of the sequence with each chain in the PDB,
472 * and remember the highest scoring chain
475 AlignSeq maxAlignseq = null;
476 String maxChainId = " ";
477 PDBChain maxChain = null;
478 boolean first = true;
479 for (PDBChain chain : pdb.getChains())
481 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
484 continue; // don't try to map chains don't match.
486 // TODO: correctly determine sequence type for mixed na/peptide
488 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
489 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
492 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
493 // as.calcScoreMatrix();
494 // as.traceAlignment();
496 if (first || as.maxscore > max
497 || (as.maxscore == max && chain.id.equals(targetChainId)))
503 maxChainId = chain.id;
506 if (maxChain == null)
511 if (protocol.equals(DataSourceType.PASTE))
513 pdbFile = "INLINE" + pdb.getId();
515 boolean phyre2Template = isPhyre2Template(pdbFile);
516 List<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
517 if (!phyre2Template && isMapUsingSIFTs && seq.isProtein())
519 if (progress!=null) {
520 progress.setProgressBar(MessageManager
521 .getString("status.obtaining_mapping_with_sifts"),
524 jalview.datamodel.Mapping sqmpping = maxAlignseq
525 .getMappingFromS1(false);
526 if (targetChainId != null && !targetChainId.trim().isEmpty())
528 StructureMapping siftsMapping;
531 siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
532 pdb, maxChain, sqmpping, maxAlignseq);
533 seqToStrucMapping.add(siftsMapping);
534 maxChain.makeExactMapping(maxAlignseq, seq);
535 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
537 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
538 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
540 } catch (SiftsException e)
542 // fall back to NW alignment
543 System.err.println(e.getMessage());
544 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
545 targetChainId, maxChain, pdb, maxAlignseq);
546 seqToStrucMapping.add(nwMapping);
547 maxChain.makeExactMapping(maxAlignseq, seq);
548 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
550 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
551 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
552 } catch (Exception e)
559 List<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
560 for (PDBChain chain : pdb.getChains())
564 StructureMapping siftsMapping = getStructureMapping(seq,
565 pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
566 foundSiftsMappings.add(siftsMapping);
567 } catch (SiftsException e)
569 System.err.println(e.getMessage());
570 } catch (Exception e)
575 if (!foundSiftsMappings.isEmpty())
577 seqToStrucMapping.addAll(foundSiftsMappings);
578 maxChain.makeExactMapping(maxAlignseq, seq);
579 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
581 maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
583 ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0));
587 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
588 maxChainId, maxChain, pdb, maxAlignseq);
589 seqToStrucMapping.add(nwMapping);
590 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
592 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
593 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
597 else if (phyre2Template)
599 setProgressBar(null);
600 setProgressBar(MessageManager
601 .getString("status.obtaining_mapping_with_phyre2_template_alignment"));
602 StructureMapping phyre2ModelMapping = new Phyre2Client(pdb)
603 .getStructureMapping(seq, pdbFile, " ");
605 seqToStrucMapping.add(phyre2ModelMapping);
606 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
610 if (progress != null)
612 progress.setProgressBar(MessageManager
613 .getString("status.obtaining_mapping_with_nw_alignment"),
616 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
617 maxChainId, maxChain, pdb, maxAlignseq);
618 seqToStrucMapping.add(nwMapping);
619 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
623 if (forStructureView)
625 mappings.addAll(seqToStrucMapping);
631 public void registerPhyre2Template(String phyre2Template)
633 phyre2ModelTemplates.add(phyre2Template);
637 * retrieve a mapping for seq from SIFTs using associated DBRefEntry for
642 * @param targetChainId
648 * @throws SiftsException
650 private StructureMapping getStructureMapping(SequenceI seq,
651 String pdbFile, String targetChainId, StructureFile pdb,
652 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
653 AlignSeq maxAlignseq) throws Exception
655 StructureMapping curChainMapping = siftsClient
656 .getStructureMapping(seq, pdbFile, targetChainId);
659 PDBChain chain = pdb.findChain(targetChainId);
662 chain.transferResidueAnnotation(curChainMapping, sqmpping);
664 } catch (Exception e)
668 return curChainMapping;
671 private StructureMapping getNWMappings(SequenceI seq, String pdbFile,
672 String maxChainId, PDBChain maxChain, StructureFile pdb,
673 AlignSeq maxAlignseq)
675 final StringBuilder mappingDetails = new StringBuilder(128);
676 mappingDetails.append(NEWLINE).append(
677 "Sequence \u27f7 Structure mapping details");
678 mappingDetails.append(NEWLINE);
680 .append("Method: inferred with Needleman & Wunsch alignment");
681 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
682 .append(NEWLINE).append("Sequence = ")
683 .append(maxChain.sequence.getSequenceAsString());
684 mappingDetails.append(NEWLINE).append("No of residues = ")
685 .append(maxChain.residues.size()).append(NEWLINE)
687 PrintStream ps = new PrintStream(System.out)
690 public void print(String x)
692 mappingDetails.append(x);
696 public void println()
698 mappingDetails.append(NEWLINE);
702 maxAlignseq.printAlignment(ps);
704 mappingDetails.append(NEWLINE).append("PDB start/end ");
705 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
707 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
708 mappingDetails.append(NEWLINE).append("SEQ start/end ");
709 mappingDetails.append(
710 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
712 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
713 + (seq.getStart() - 1)));
714 mappingDetails.append(NEWLINE);
715 maxChain.makeExactMapping(maxAlignseq, seq);
716 jalview.datamodel.Mapping sqmpping = maxAlignseq
717 .getMappingFromS1(false);
718 maxChain.transferRESNUMFeatures(seq, null);
720 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
727 Atom tmp = maxChain.atoms.elementAt(index);
728 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
729 && tmp.alignmentMapping != -1)
731 resNum = tmp.resNumber;
732 insCode = tmp.insCode;
733 if (tmp.alignmentMapping >= -1)
735 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
741 } while (index < maxChain.atoms.size());
743 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
744 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
745 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
749 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
751 listeners.removeElement(svl);
752 if (svl instanceof SequenceListener)
754 for (int i = 0; i < listeners.size(); i++)
756 if (listeners.elementAt(i) instanceof StructureListener)
758 ((StructureListener) listeners.elementAt(i))
759 .releaseReferences(svl);
764 if (pdbfiles == null)
770 * Remove mappings to the closed listener's PDB files, but first check if
771 * another listener is still interested
773 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
775 StructureListener sl;
776 for (int i = 0; i < listeners.size(); i++)
778 if (listeners.elementAt(i) instanceof StructureListener)
780 sl = (StructureListener) listeners.elementAt(i);
781 for (String pdbfile : sl.getPdbFile())
783 pdbs.remove(pdbfile);
789 * Rebuild the mappings set, retaining only those which are for 'other' PDB
794 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
795 for (StructureMapping sm : mappings)
797 if (!pdbs.contains(sm.pdbfile))
808 * Propagate mouseover of a single position in a structure
814 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
816 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
817 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
818 mouseOverStructure(atoms);
822 * Propagate mouseover or selection of multiple positions in a structure
826 public void mouseOverStructure(List<AtomSpec> atoms)
828 if (listeners == null)
830 // old or prematurely sent event
833 boolean hasSequenceListener = false;
834 for (int i = 0; i < listeners.size(); i++)
836 if (listeners.elementAt(i) instanceof SequenceListener)
838 hasSequenceListener = true;
841 if (!hasSequenceListener)
846 SearchResultsI results = new SearchResults();
847 for (AtomSpec atom : atoms)
849 SequenceI lastseq = null;
851 for (StructureMapping sm : mappings)
853 if (sm.pdbfile.equals(atom.getPdbFile())
854 && sm.pdbchain.equals(atom.getChain()))
856 int indexpos = sm.getSeqPos(atom.getPdbResNum());
857 if (lastipos != indexpos && lastseq != sm.sequence)
859 results.addResult(sm.sequence, indexpos, indexpos);
861 lastseq = sm.sequence;
862 // construct highlighted sequence list
863 for (AlignedCodonFrame acf : seqmappings)
865 acf.markMappedRegion(sm.sequence, indexpos, results);
871 for (Object li : listeners)
873 if (li instanceof SequenceListener)
875 ((SequenceListener) li).highlightSequence(results);
881 * highlight regions associated with a position (indexpos) in seq
884 * the sequence that the mouse over occurred on
886 * the absolute position being mouseovered in seq (0 to seq.length())
888 * the sequence position (if -1, seq.findPosition is called to
889 * resolve the residue number)
891 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
894 boolean hasSequenceListeners = handlingVamsasMo
895 || !seqmappings.isEmpty();
896 SearchResultsI results = null;
899 seqPos = seq.findPosition(indexpos);
901 for (int i = 0; i < listeners.size(); i++)
903 Object listener = listeners.elementAt(i);
904 if (listener == source)
906 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
907 // Temporary fudge with SequenceListener.getVamsasSource()
910 if (listener instanceof StructureListener)
912 highlightStructure((StructureListener) listener, seq, seqPos);
916 if (listener instanceof SequenceListener)
918 final SequenceListener seqListener = (SequenceListener) listener;
919 if (hasSequenceListeners
920 && seqListener.getVamsasSource() != source)
922 if (relaySeqMappings)
926 results = MappingUtils.buildSearchResults(seq, seqPos,
929 if (handlingVamsasMo)
931 results.addResult(seq, seqPos, seqPos);
934 if (!results.isEmpty())
936 seqListener.highlightSequence(results);
941 else if (listener instanceof VamsasListener && !handlingVamsasMo)
943 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
946 else if (listener instanceof SecondaryStructureListener)
948 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
956 * Send suitable messages to a StructureListener to highlight atoms
957 * corresponding to the given sequence position(s)
963 public void highlightStructure(StructureListener sl, SequenceI seq,
966 if (!sl.isListeningFor(seq))
971 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
972 for (StructureMapping sm : mappings)
974 if (sm.sequence == seq
975 || sm.sequence == seq.getDatasetSequence()
976 || (sm.sequence.getDatasetSequence() != null && sm.sequence
977 .getDatasetSequence() == seq.getDatasetSequence()))
979 for (int index : positions)
981 atomNo = sm.getAtomNum(index);
985 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
986 .getPDBResNum(index), atomNo));
991 sl.highlightAtoms(atoms);
995 * true if a mouse over event from an external (ie Vamsas) source is being
998 boolean handlingVamsasMo = false;
1003 * as mouseOverSequence but only route event to SequenceListeners
1007 * in an alignment sequence
1009 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
1010 VamsasSource source)
1012 handlingVamsasMo = true;
1013 long msg = sequenceI.hashCode() * (1 + position);
1017 mouseOverSequence(sequenceI, position, -1, source);
1019 handlingVamsasMo = false;
1022 public Annotation[] colourSequenceFromStructure(SequenceI seq,
1026 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
1027 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
1029 * Annotation [] annotations = new Annotation[seq.getLength()];
1031 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
1032 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
1033 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
1035 * for (int j = 0; j < mappings.length; j++) {
1037 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
1038 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
1039 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
1040 * "+mappings[j].pdbfile);
1042 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
1043 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
1045 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
1046 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
1047 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
1048 * mappings[j].pdbfile); }
1050 * annotations[index] = new Annotation("X",null,' ',0,col); } return
1051 * annotations; } } } }
1053 * return annotations;
1057 public void structureSelectionChanged()
1061 public void sequenceSelectionChanged()
1065 public void sequenceColoursChanged(Object source)
1067 StructureListener sl;
1068 for (int i = 0; i < listeners.size(); i++)
1070 if (listeners.elementAt(i) instanceof StructureListener)
1072 sl = (StructureListener) listeners.elementAt(i);
1073 sl.updateColours(source);
1078 public StructureMapping[] getMapping(String pdbfile)
1080 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1081 for (StructureMapping sm : mappings)
1083 if (sm.pdbfile.equals(pdbfile))
1088 return tmp.toArray(new StructureMapping[tmp.size()]);
1092 * Returns a readable description of all mappings for the given pdbfile to any
1093 * of the given sequences
1099 public String printMappings(String pdbfile, List<SequenceI> seqs)
1101 if (pdbfile == null || seqs == null || seqs.isEmpty())
1106 StringBuilder sb = new StringBuilder(64);
1107 for (StructureMapping sm : mappings)
1109 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1111 sb.append(sm.mappingDetails);
1113 // separator makes it easier to read multiple mappings
1114 sb.append("=====================");
1120 return sb.toString();
1124 * Remove the given mapping
1128 public void deregisterMapping(AlignedCodonFrame acf)
1132 boolean removed = seqmappings.remove(acf);
1133 if (removed && seqmappings.isEmpty())
1135 System.out.println("All mappings removed");
1141 * Add each of the given codonFrames to the stored set, if not aready present.
1145 public void registerMappings(List<AlignedCodonFrame> mappings)
1147 if (mappings != null)
1149 for (AlignedCodonFrame acf : mappings)
1151 registerMapping(acf);
1157 * Add the given mapping to the stored set, unless already stored.
1159 public void registerMapping(AlignedCodonFrame acf)
1163 if (!seqmappings.contains(acf))
1165 seqmappings.add(acf);
1171 * Resets this object to its initial state by removing all registered
1172 * listeners, codon mappings, PDB file mappings
1174 public void resetAll()
1176 if (mappings != null)
1180 if (seqmappings != null)
1182 seqmappings.clear();
1184 if (sel_listeners != null)
1186 sel_listeners.clear();
1188 if (listeners != null)
1192 if (commandListeners != null)
1194 commandListeners.clear();
1196 if (view_listeners != null)
1198 view_listeners.clear();
1200 if (pdbFileNameId != null)
1202 pdbFileNameId.clear();
1204 if (pdbIdFileName != null)
1206 pdbIdFileName.clear();
1210 public void addSelectionListener(SelectionListener selecter)
1212 if (!sel_listeners.contains(selecter))
1214 sel_listeners.add(selecter);
1218 public void removeSelectionListener(SelectionListener toremove)
1220 if (sel_listeners.contains(toremove))
1222 sel_listeners.remove(toremove);
1226 public synchronized void sendSelection(
1227 jalview.datamodel.SequenceGroup selection,
1228 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1230 for (SelectionListener slis : sel_listeners)
1234 slis.selection(selection, colsel, source);
1239 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1241 public synchronized void sendViewPosition(
1242 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1243 int startSeq, int endSeq)
1246 if (view_listeners != null && view_listeners.size() > 0)
1248 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1250 while (listeners.hasMoreElements())
1252 AlignmentViewPanelListener slis = listeners.nextElement();
1255 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1263 * release all references associated with this manager provider
1265 * @param jalviewLite
1267 public static void release(StructureSelectionManagerProvider jalviewLite)
1269 // synchronized (instances)
1271 if (instances == null)
1275 StructureSelectionManager mnger = (instances.get(jalviewLite));
1278 instances.remove(jalviewLite);
1282 } catch (Throwable x)
1289 public void registerPDBEntry(PDBEntry pdbentry)
1291 if (pdbentry.getFile() != null
1292 && pdbentry.getFile().trim().length() > 0)
1294 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1298 public void addCommandListener(CommandListener cl)
1300 if (!commandListeners.contains(cl))
1302 commandListeners.add(cl);
1306 public boolean hasCommandListener(CommandListener cl)
1308 return this.commandListeners.contains(cl);
1311 public boolean removeCommandListener(CommandListener l)
1313 return commandListeners.remove(l);
1317 * Forward a command to any command listeners (except for the command's
1321 * the command to be broadcast (in its form after being performed)
1323 * if true, the command was being 'undone'
1326 public void commandPerformed(CommandI command, boolean undo,
1327 VamsasSource source)
1329 for (CommandListener listener : commandListeners)
1331 listener.mirrorCommand(command, undo, this, source);
1336 * Returns a new CommandI representing the given command as mapped to the
1337 * given sequences. If no mapping could be made, or the command is not of a
1338 * mappable kind, returns null.
1346 public CommandI mapCommand(CommandI command, boolean undo,
1347 final AlignmentI mapTo, char gapChar)
1349 if (command instanceof EditCommand)
1351 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1352 mapTo, gapChar, seqmappings);
1354 else if (command instanceof OrderCommand)
1356 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1357 mapTo, seqmappings);
1362 public IProgressIndicator getProgressIndicator()
1364 return progressIndicator;
1367 public void setProgressIndicator(IProgressIndicator progressIndicator)
1369 this.progressIndicator = progressIndicator;
1372 public long getProgressSessionId()
1374 return progressSessionId;
1377 public void setProgressSessionId(long progressSessionId)
1379 this.progressSessionId = progressSessionId;
1382 public void setProgressBar(String message)
1384 if (progressIndicator == null)
1388 progressIndicator.setProgressBar(message, progressSessionId);
1391 public List<AlignedCodonFrame> getSequenceMappings()
1396 public boolean isPhyre2Template(String structureFile)
1398 if (structureFile == null || phyre2ModelTemplates == null
1399 || phyre2ModelTemplates.isEmpty())
1403 return (phyre2ModelTemplates.contains(structureFile));
1407 public static StructureSelectionManager getStructureSelectionManager()
1409 return instances.values().iterator().next();