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.sifts.SiftsClient;
43 import jalview.ws.sifts.SiftsException;
44 import jalview.ws.sifts.SiftsSettings;
46 import java.io.PrintStream;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collections;
50 import java.util.Enumeration;
51 import java.util.HashMap;
52 import java.util.IdentityHashMap;
53 import java.util.List;
55 import java.util.Vector;
58 import MCview.PDBChain;
59 import MCview.PDBfile;
61 public class StructureSelectionManager
63 public final static String NEWLINE = System.lineSeparator();
65 static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
67 private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
69 private boolean processSecondaryStructure = false;
71 private boolean secStructServices = false;
73 private boolean addTempFacAnnot = false;
75 private IProgressIndicator progressIndicator;
77 private SiftsClient siftsClient = null;
79 private long progressSessionId;
82 * Set of any registered mappings between (dataset) sequences.
84 private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
86 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
88 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
91 * @return true if will try to use external services for processing secondary
94 public boolean isSecStructServices()
96 return secStructServices;
100 * control use of external services for processing secondary structure
102 * @param secStructServices
104 public void setSecStructServices(boolean secStructServices)
106 this.secStructServices = secStructServices;
110 * flag controlling addition of any kind of structural annotation
112 * @return true if temperature factor annotation will be added
114 public boolean isAddTempFacAnnot()
116 return addTempFacAnnot;
120 * set flag controlling addition of structural annotation
122 * @param addTempFacAnnot
124 public void setAddTempFacAnnot(boolean addTempFacAnnot)
126 this.addTempFacAnnot = addTempFacAnnot;
131 * @return if true, the structure manager will attempt to add secondary
132 * structure lines for unannotated sequences
135 public boolean isProcessSecondaryStructure()
137 return processSecondaryStructure;
141 * Control whether structure manager will try to annotate mapped sequences
142 * with secondary structure from PDB data.
146 public void setProcessSecondaryStructure(boolean enable)
148 processSecondaryStructure = enable;
152 * debug function - write all mappings to stdout
154 public void reportMapping()
156 if (mappings.isEmpty())
158 System.err.println("reportMapping: No PDB/Sequence mappings.");
162 System.err.println("reportMapping: There are " + mappings.size()
165 for (StructureMapping sm : mappings)
167 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
173 * map between the PDB IDs (or structure identifiers) used by Jalview and the
174 * absolute filenames for PDB data that corresponds to it
176 Map<String, String> pdbIdFileName = new HashMap<String, String>();
178 Map<String, String> pdbFileNameId = new HashMap<String, String>();
180 public void registerPDBFile(String idForFile, String absoluteFile)
182 pdbIdFileName.put(idForFile, absoluteFile);
183 pdbFileNameId.put(absoluteFile, idForFile);
186 public String findIdForPDBFile(String idOrFile)
188 String id = pdbFileNameId.get(idOrFile);
192 public String findFileForPDBId(String idOrFile)
194 String id = pdbIdFileName.get(idOrFile);
198 public boolean isPDBFileRegistered(String idOrFile)
200 return pdbFileNameId.containsKey(idOrFile)
201 || pdbIdFileName.containsKey(idOrFile);
204 private static StructureSelectionManager nullProvider = null;
206 public static StructureSelectionManager getStructureSelectionManager(
207 StructureSelectionManagerProvider context)
211 if (nullProvider == null)
213 if (instances != null)
217 .getString("error.implementation_error_structure_selection_manager_null"),
218 new NullPointerException(MessageManager
219 .getString("exception.ssm_context_is_null")));
223 nullProvider = new StructureSelectionManager();
228 if (instances == null)
230 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
232 StructureSelectionManager instance = instances.get(context);
233 if (instance == null)
235 if (nullProvider != null)
237 instance = nullProvider;
241 instance = new StructureSelectionManager();
243 instances.put(context, instance);
249 * flag controlling whether SeqMappings are relayed from received sequence
250 * mouse over events to other sequences
252 boolean relaySeqMappings = true;
255 * Enable or disable relay of seqMapping events to other sequences. You might
256 * want to do this if there are many sequence mappings and the host computer
261 public void setRelaySeqMappings(boolean relay)
263 relaySeqMappings = relay;
267 * get the state of the relay seqMappings flag.
269 * @return true if sequence mouse overs are being relayed to other mapped
272 public boolean isRelaySeqMappingsEnabled()
274 return relaySeqMappings;
277 Vector listeners = new Vector();
280 * register a listener for alignment sequence mouseover events
284 public void addStructureViewerListener(Object svl)
286 if (!listeners.contains(svl))
288 listeners.addElement(svl);
293 * Returns the file name for a mapped PDB id (or null if not mapped).
298 public String alreadyMappedToFile(String pdbid)
300 for (StructureMapping sm : mappings)
302 if (sm.getPdbId().equals(pdbid))
311 * Import structure data and register a structure mapping for broadcasting
312 * colouring, mouseovers and selection events (convenience wrapper).
315 * - one or more sequences to be mapped to pdbFile
316 * @param targetChains
317 * - optional chain specification for mapping each sequence to pdb
318 * (may be nill, individual elements may be nill)
320 * - structure data resource
322 * - how to resolve data from resource
323 * @return null or the structure data parsed as a pdb file
325 synchronized public StructureFile setMapping(SequenceI[] sequence,
326 String[] targetChains, String pdbFile, DataSourceType protocol)
328 return setMapping(true, sequence, targetChains, pdbFile, protocol);
332 * create sequence structure mappings between each sequence and the given
333 * pdbFile (retrieved via the given protocol).
335 * @param forStructureView
336 * when true, record the mapping for use in mouseOvers
338 * @param sequenceArray
339 * - one or more sequences to be mapped to pdbFile
340 * @param targetChainIds
341 * - optional chain specification for mapping each sequence to pdb
342 * (may be nill, individual elements may be nill)
344 * - structure data resource
346 * - how to resolve data from resource
347 * @return null or the structure data parsed as a pdb file
349 synchronized public StructureFile setMapping(boolean forStructureView,
350 SequenceI[] sequenceArray, String[] targetChainIds,
351 String pdbFile, DataSourceType sourceType)
354 * There will be better ways of doing this in the future, for now we'll use
355 * the tried and tested MCview pdb mapping
357 boolean parseSecStr = processSecondaryStructure;
358 if (isPDBFileRegistered(pdbFile))
360 for (SequenceI sq : sequenceArray)
363 while (ds.getDatasetSequence() != null)
365 ds = ds.getDatasetSequence();
368 if (ds.getAnnotation() != null)
370 for (AlignmentAnnotation ala : ds.getAnnotation())
372 // false if any annotation present from this structure
373 // JBPNote this fails for jmol/chimera view because the *file* is
374 // passed, not the structure data ID -
375 if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
383 StructureFile pdb = null;
384 boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
387 pdb = new JmolParser(pdbFile, sourceType);
389 if (pdb.getId() != null && pdb.getId().trim().length() > 0
390 && DataSourceType.FILE == sourceType)
392 registerPDBFile(pdb.getId().trim(), pdbFile);
394 // if PDBId is unavailable then skip SIFTS mapping execution path
395 isMapUsingSIFTs = isMapUsingSIFTs && pdb.isPPDBIdAvailable();
397 } catch (Exception ex)
399 ex.printStackTrace();
407 siftsClient = new SiftsClient(pdb);
409 } catch (SiftsException e)
411 isMapUsingSIFTs = false;
415 String targetChainId;
416 for (int s = 0; s < sequenceArray.length; s++)
418 boolean infChain = true;
419 final SequenceI seq = sequenceArray[s];
421 while (ds.getDatasetSequence() != null)
423 ds = ds.getDatasetSequence();
426 if (targetChainIds != null && targetChainIds[s] != null)
429 targetChainId = targetChainIds[s];
431 else if (seq.getName().indexOf("|") > -1)
433 targetChainId = seq.getName().substring(
434 seq.getName().lastIndexOf("|") + 1);
435 if (targetChainId.length() > 1)
437 if (targetChainId.trim().length() == 0)
443 // not a valid chain identifier
454 * Attempt pairwise alignment of the sequence with each chain in the PDB,
455 * and remember the highest scoring chain
458 AlignSeq maxAlignseq = null;
459 String maxChainId = " ";
460 PDBChain maxChain = null;
461 boolean first = true;
462 for (PDBChain chain : pdb.getChains())
464 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
467 continue; // don't try to map chains don't match.
469 // TODO: correctly determine sequence type for mixed na/peptide
471 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
472 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
475 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
476 // as.calcScoreMatrix();
477 // as.traceAlignment();
479 if (first || as.maxscore > max
480 || (as.maxscore == max && chain.id.equals(targetChainId)))
486 maxChainId = chain.id;
489 if (maxChain == null)
494 if (sourceType == DataSourceType.PASTE)
496 pdbFile = "INLINE" + pdb.getId();
499 List<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
500 if (isMapUsingSIFTs && seq.isProtein())
502 setProgressBar(null);
503 setProgressBar(MessageManager
504 .getString("status.obtaining_mapping_with_sifts"));
505 jalview.datamodel.Mapping sqmpping = maxAlignseq
506 .getMappingFromS1(false);
507 if (targetChainId != null && !targetChainId.trim().isEmpty())
509 StructureMapping siftsMapping;
512 siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
513 pdb, maxChain, sqmpping, maxAlignseq);
514 seqToStrucMapping.add(siftsMapping);
515 maxChain.makeExactMapping(maxAlignseq, seq);
516 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
518 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
519 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
521 } catch (SiftsException e)
523 // fall back to NW alignment
524 System.err.println(e.getMessage());
525 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
526 targetChainId, maxChain, pdb, maxAlignseq);
527 seqToStrucMapping.add(nwMapping);
528 maxChain.makeExactMapping(maxAlignseq, seq);
529 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
531 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
532 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
537 List<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
538 for (PDBChain chain : pdb.getChains())
542 StructureMapping siftsMapping = getStructureMapping(seq,
543 pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
544 foundSiftsMappings.add(siftsMapping);
545 } catch (SiftsException e)
547 System.err.println(e.getMessage());
550 if (!foundSiftsMappings.isEmpty())
552 seqToStrucMapping.addAll(foundSiftsMappings);
553 maxChain.makeExactMapping(maxAlignseq, seq);
554 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
556 maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
558 ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0));
562 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
563 maxChainId, maxChain, pdb, maxAlignseq);
564 seqToStrucMapping.add(nwMapping);
565 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
567 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
568 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
574 setProgressBar(null);
575 setProgressBar(MessageManager
576 .getString("status.obtaining_mapping_with_nw_alignment"));
577 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
578 maxChainId, maxChain, pdb, maxAlignseq);
579 seqToStrucMapping.add(nwMapping);
580 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
584 if (forStructureView)
586 mappings.addAll(seqToStrucMapping);
592 public void addStructureMapping(StructureMapping sm)
598 * retrieve a mapping for seq from SIFTs using associated DBRefEntry for
603 * @param targetChainId
609 * @throws SiftsException
611 private StructureMapping getStructureMapping(SequenceI seq,
612 String pdbFile, String targetChainId, StructureFile pdb,
613 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
614 AlignSeq maxAlignseq) throws SiftsException
616 StructureMapping curChainMapping = siftsClient
617 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
620 PDBChain chain = pdb.findChain(targetChainId);
623 chain.transferResidueAnnotation(curChainMapping, sqmpping);
625 } catch (Exception e)
629 return curChainMapping;
632 private StructureMapping getNWMappings(SequenceI seq, String pdbFile,
633 String maxChainId, PDBChain maxChain, StructureFile pdb,
634 AlignSeq maxAlignseq)
636 final StringBuilder mappingDetails = new StringBuilder(128);
637 mappingDetails.append(NEWLINE).append(
638 "Sequence \u27f7 Structure mapping details");
639 mappingDetails.append(NEWLINE);
641 .append("Method: inferred with Needleman & Wunsch alignment");
642 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
643 .append(NEWLINE).append("Sequence = ")
644 .append(maxChain.sequence.getSequenceAsString());
645 mappingDetails.append(NEWLINE).append("No of residues = ")
646 .append(maxChain.residues.size()).append(NEWLINE)
648 PrintStream ps = new PrintStream(System.out)
651 public void print(String x)
653 mappingDetails.append(x);
657 public void println()
659 mappingDetails.append(NEWLINE);
663 maxAlignseq.printAlignment(ps);
665 mappingDetails.append(NEWLINE).append("PDB start/end ");
666 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
668 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
669 mappingDetails.append(NEWLINE).append("SEQ start/end ");
670 mappingDetails.append(
671 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
673 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
674 + (seq.getStart() - 1)));
675 mappingDetails.append(NEWLINE);
676 maxChain.makeExactMapping(maxAlignseq, seq);
677 jalview.datamodel.Mapping sqmpping = maxAlignseq
678 .getMappingFromS1(false);
679 maxChain.transferRESNUMFeatures(seq, null);
681 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
688 Atom tmp = maxChain.atoms.elementAt(index);
689 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
690 && tmp.alignmentMapping != -1)
692 resNum = tmp.resNumber;
693 insCode = tmp.insCode;
694 if (tmp.alignmentMapping >= -1)
696 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
702 } while (index < maxChain.atoms.size());
704 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
705 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
706 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
710 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
712 listeners.removeElement(svl);
713 if (svl instanceof SequenceListener)
715 for (int i = 0; i < listeners.size(); i++)
717 if (listeners.elementAt(i) instanceof StructureListener)
719 ((StructureListener) listeners.elementAt(i))
720 .releaseReferences(svl);
725 if (pdbfiles == null)
731 * Remove mappings to the closed listener's PDB files, but first check if
732 * another listener is still interested
734 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
736 StructureListener sl;
737 for (int i = 0; i < listeners.size(); i++)
739 if (listeners.elementAt(i) instanceof StructureListener)
741 sl = (StructureListener) listeners.elementAt(i);
742 for (String pdbfile : sl.getPdbFile())
744 pdbs.remove(pdbfile);
750 * Rebuild the mappings set, retaining only those which are for 'other' PDB
755 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
756 for (StructureMapping sm : mappings)
758 if (!pdbs.contains(sm.pdbfile))
769 * Propagate mouseover of a single position in a structure
775 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
777 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
778 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
779 mouseOverStructure(atoms);
783 * Propagate mouseover or selection of multiple positions in a structure
787 public void mouseOverStructure(List<AtomSpec> atoms)
789 if (listeners == null)
791 // old or prematurely sent event
794 boolean hasSequenceListener = false;
795 for (int i = 0; i < listeners.size(); i++)
797 if (listeners.elementAt(i) instanceof SequenceListener)
799 hasSequenceListener = true;
802 if (!hasSequenceListener)
807 SearchResultsI results = findAlignmentPositionsForStructurePositions(atoms);
808 for (Object li : listeners)
810 if (li instanceof SequenceListener)
812 ((SequenceListener) li).highlightSequence(results);
818 * Constructs a SearchResults object holding regions (if any) in the Jalview
819 * alignment which have a mapping to the structure viewer positions in the
825 public SearchResultsI findAlignmentPositionsForStructurePositions(
826 List<AtomSpec> atoms)
828 SearchResultsI results = new SearchResults();
829 for (AtomSpec atom : atoms)
831 SequenceI lastseq = null;
833 for (StructureMapping sm : mappings)
835 if (sm.pdbfile.equals(atom.getPdbFile())
836 && sm.pdbchain.equals(atom.getChain()))
838 int indexpos = sm.getSeqPos(atom.getPdbResNum());
839 if (lastipos != indexpos && lastseq != sm.sequence)
841 results.addResult(sm.sequence, indexpos, indexpos);
843 lastseq = sm.sequence;
844 // construct highlighted sequence list
845 for (AlignedCodonFrame acf : seqmappings)
847 acf.markMappedRegion(sm.sequence, indexpos, results);
857 * highlight regions associated with a position (indexpos) in seq
860 * the sequence that the mouse over occurred on
862 * the absolute position being mouseovered in seq (0 to seq.length())
864 * the sequence position (if -1, seq.findPosition is called to
865 * resolve the residue number)
867 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
870 boolean hasSequenceListeners = handlingVamsasMo
871 || !seqmappings.isEmpty();
872 SearchResultsI results = null;
875 seqPos = seq.findPosition(indexpos);
877 for (int i = 0; i < listeners.size(); i++)
879 Object listener = listeners.elementAt(i);
880 if (listener == source)
882 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
883 // Temporary fudge with SequenceListener.getVamsasSource()
886 if (listener instanceof StructureListener)
888 highlightStructure((StructureListener) listener, seq, seqPos);
892 if (listener instanceof SequenceListener)
894 final SequenceListener seqListener = (SequenceListener) listener;
895 if (hasSequenceListeners
896 && seqListener.getVamsasSource() != source)
898 if (relaySeqMappings)
902 results = MappingUtils.buildSearchResults(seq, seqPos,
905 if (handlingVamsasMo)
907 results.addResult(seq, seqPos, seqPos);
910 if (!results.isEmpty())
912 seqListener.highlightSequence(results);
917 else if (listener instanceof VamsasListener && !handlingVamsasMo)
919 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
922 else if (listener instanceof SecondaryStructureListener)
924 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
932 * Send suitable messages to a StructureListener to highlight atoms
933 * corresponding to the given sequence position(s)
939 public void highlightStructure(StructureListener sl, SequenceI seq,
942 if (!sl.isListeningFor(seq))
947 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
948 for (StructureMapping sm : mappings)
950 if (sm.sequence == seq
951 || sm.sequence == seq.getDatasetSequence()
952 || (sm.sequence.getDatasetSequence() != null && sm.sequence
953 .getDatasetSequence() == seq.getDatasetSequence()))
955 for (int index : positions)
957 atomNo = sm.getAtomNum(index);
961 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
962 .getPDBResNum(index), atomNo));
967 sl.highlightAtoms(atoms);
971 * true if a mouse over event from an external (ie Vamsas) source is being
974 boolean handlingVamsasMo = false;
979 * as mouseOverSequence but only route event to SequenceListeners
983 * in an alignment sequence
985 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
988 handlingVamsasMo = true;
989 long msg = sequenceI.hashCode() * (1 + position);
993 mouseOverSequence(sequenceI, position, -1, source);
995 handlingVamsasMo = false;
998 public Annotation[] colourSequenceFromStructure(SequenceI seq,
1002 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
1003 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
1005 * Annotation [] annotations = new Annotation[seq.getLength()];
1007 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
1008 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
1009 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
1011 * for (int j = 0; j < mappings.length; j++) {
1013 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
1014 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
1015 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
1016 * "+mappings[j].pdbfile);
1018 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
1019 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
1021 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
1022 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
1023 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
1024 * mappings[j].pdbfile); }
1026 * annotations[index] = new Annotation("X",null,' ',0,col); } return
1027 * annotations; } } } }
1029 * return annotations;
1033 public void structureSelectionChanged()
1037 public void sequenceSelectionChanged()
1041 public void sequenceColoursChanged(Object source)
1043 StructureListener sl;
1044 for (int i = 0; i < listeners.size(); i++)
1046 if (listeners.elementAt(i) instanceof StructureListener)
1048 sl = (StructureListener) listeners.elementAt(i);
1049 sl.updateColours(source);
1054 public StructureMapping[] getMapping(String pdbfile)
1056 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1057 for (StructureMapping sm : mappings)
1059 if (sm.pdbfile.equals(pdbfile))
1064 return tmp.toArray(new StructureMapping[tmp.size()]);
1068 * Returns a readable description of all mappings for the given pdbfile to any
1069 * of the given sequences
1075 public String printMappings(String pdbfile, List<SequenceI> seqs)
1077 if (pdbfile == null || seqs == null || seqs.isEmpty())
1082 StringBuilder sb = new StringBuilder(64);
1083 for (StructureMapping sm : mappings)
1085 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1087 sb.append(sm.mappingDetails);
1089 // separator makes it easier to read multiple mappings
1090 sb.append("=====================");
1096 return sb.toString();
1100 * Remove the given mapping
1104 public void deregisterMapping(AlignedCodonFrame acf)
1108 boolean removed = seqmappings.remove(acf);
1109 if (removed && seqmappings.isEmpty())
1111 System.out.println("All mappings removed");
1117 * Add each of the given codonFrames to the stored set, if not aready present.
1121 public void registerMappings(List<AlignedCodonFrame> mappings)
1123 if (mappings != null)
1125 for (AlignedCodonFrame acf : mappings)
1127 registerMapping(acf);
1133 * Add the given mapping to the stored set, unless already stored.
1135 public void registerMapping(AlignedCodonFrame acf)
1139 if (!seqmappings.contains(acf))
1141 seqmappings.add(acf);
1147 * Resets this object to its initial state by removing all registered
1148 * listeners, codon mappings, PDB file mappings
1150 public void resetAll()
1152 if (mappings != null)
1156 if (seqmappings != null)
1158 seqmappings.clear();
1160 if (sel_listeners != null)
1162 sel_listeners.clear();
1164 if (listeners != null)
1168 if (commandListeners != null)
1170 commandListeners.clear();
1172 if (view_listeners != null)
1174 view_listeners.clear();
1176 if (pdbFileNameId != null)
1178 pdbFileNameId.clear();
1180 if (pdbIdFileName != null)
1182 pdbIdFileName.clear();
1186 public void addSelectionListener(SelectionListener selecter)
1188 if (!sel_listeners.contains(selecter))
1190 sel_listeners.add(selecter);
1194 public void removeSelectionListener(SelectionListener toremove)
1196 if (sel_listeners.contains(toremove))
1198 sel_listeners.remove(toremove);
1202 public synchronized void sendSelection(
1203 jalview.datamodel.SequenceGroup selection,
1204 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1206 for (SelectionListener slis : sel_listeners)
1210 slis.selection(selection, colsel, source);
1215 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1217 public synchronized void sendViewPosition(
1218 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1219 int startSeq, int endSeq)
1222 if (view_listeners != null && view_listeners.size() > 0)
1224 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1226 while (listeners.hasMoreElements())
1228 AlignmentViewPanelListener slis = listeners.nextElement();
1231 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1239 * release all references associated with this manager provider
1241 * @param jalviewLite
1243 public static void release(StructureSelectionManagerProvider jalviewLite)
1245 // synchronized (instances)
1247 if (instances == null)
1251 StructureSelectionManager mnger = (instances.get(jalviewLite));
1254 instances.remove(jalviewLite);
1258 } catch (Throwable x)
1265 public void registerPDBEntry(PDBEntry pdbentry)
1267 if (pdbentry.getFile() != null
1268 && pdbentry.getFile().trim().length() > 0)
1270 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1274 public void addCommandListener(CommandListener cl)
1276 if (!commandListeners.contains(cl))
1278 commandListeners.add(cl);
1282 public boolean hasCommandListener(CommandListener cl)
1284 return this.commandListeners.contains(cl);
1287 public boolean removeCommandListener(CommandListener l)
1289 return commandListeners.remove(l);
1293 * Forward a command to any command listeners (except for the command's
1297 * the command to be broadcast (in its form after being performed)
1299 * if true, the command was being 'undone'
1302 public void commandPerformed(CommandI command, boolean undo,
1303 VamsasSource source)
1305 for (CommandListener listener : commandListeners)
1307 listener.mirrorCommand(command, undo, this, source);
1312 * Returns a new CommandI representing the given command as mapped to the
1313 * given sequences. If no mapping could be made, or the command is not of a
1314 * mappable kind, returns null.
1322 public CommandI mapCommand(CommandI command, boolean undo,
1323 final AlignmentI mapTo, char gapChar)
1325 if (command instanceof EditCommand)
1327 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1328 mapTo, gapChar, seqmappings);
1330 else if (command instanceof OrderCommand)
1332 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1333 mapTo, seqmappings);
1338 public IProgressIndicator getProgressIndicator()
1340 return progressIndicator;
1343 public void setProgressIndicator(IProgressIndicator progressIndicator)
1345 this.progressIndicator = progressIndicator;
1348 public long getProgressSessionId()
1350 return progressSessionId;
1353 public void setProgressSessionId(long progressSessionId)
1355 this.progressSessionId = progressSessionId;
1358 public void setProgressBar(String message)
1360 if (progressIndicator == null)
1364 progressIndicator.setProgressBar(message, progressSessionId);
1367 public List<AlignedCodonFrame> getSequenceMappings()