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.SequenceI;
35 import jalview.gui.IProgressIndicator;
36 import jalview.io.AppletFormatAdapter;
37 import jalview.io.StructureFile;
38 import jalview.util.MappingUtils;
39 import jalview.util.MessageManager;
40 import jalview.ws.sifts.SiftsClient;
41 import jalview.ws.sifts.SiftsException;
42 import jalview.ws.sifts.SiftsSettings;
44 import java.io.PrintStream;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Collections;
48 import java.util.Enumeration;
49 import java.util.HashMap;
50 import java.util.IdentityHashMap;
51 import java.util.List;
53 import java.util.Vector;
56 import MCview.PDBChain;
57 import MCview.PDBfile;
59 public class StructureSelectionManager
61 public final static String NEWLINE = System.lineSeparator();
63 static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
65 private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
67 private boolean processSecondaryStructure = false;
69 private boolean secStructServices = false;
71 private boolean addTempFacAnnot = false;
73 private IProgressIndicator progressIndicator;
75 private SiftsClient siftsClient = null;
77 private long progressSessionId;
80 * Set of any registered mappings between (dataset) sequences.
82 private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
84 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
86 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
89 * @return true if will try to use external services for processing secondary
92 public boolean isSecStructServices()
94 return secStructServices;
98 * control use of external services for processing secondary structure
100 * @param secStructServices
102 public void setSecStructServices(boolean secStructServices)
104 this.secStructServices = secStructServices;
108 * flag controlling addition of any kind of structural annotation
110 * @return true if temperature factor annotation will be added
112 public boolean isAddTempFacAnnot()
114 return addTempFacAnnot;
118 * set flag controlling addition of structural annotation
120 * @param addTempFacAnnot
122 public void setAddTempFacAnnot(boolean addTempFacAnnot)
124 this.addTempFacAnnot = addTempFacAnnot;
129 * @return if true, the structure manager will attempt to add secondary
130 * structure lines for unannotated sequences
133 public boolean isProcessSecondaryStructure()
135 return processSecondaryStructure;
139 * Control whether structure manager will try to annotate mapped sequences
140 * with secondary structure from PDB data.
144 public void setProcessSecondaryStructure(boolean enable)
146 processSecondaryStructure = enable;
150 * debug function - write all mappings to stdout
152 public void reportMapping()
154 if (mappings.isEmpty())
156 System.err.println("reportMapping: No PDB/Sequence mappings.");
160 System.err.println("reportMapping: There are " + mappings.size()
163 for (StructureMapping sm : mappings)
165 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
171 * map between the PDB IDs (or structure identifiers) used by Jalview and the
172 * absolute filenames for PDB data that corresponds to it
174 Map<String, String> pdbIdFileName = new HashMap<String, String>();
176 Map<String, String> pdbFileNameId = new HashMap<String, String>();
178 public void registerPDBFile(String idForFile, String absoluteFile)
180 pdbIdFileName.put(idForFile, absoluteFile);
181 pdbFileNameId.put(absoluteFile, idForFile);
184 public String findIdForPDBFile(String idOrFile)
186 String id = pdbFileNameId.get(idOrFile);
190 public String findFileForPDBId(String idOrFile)
192 String id = pdbIdFileName.get(idOrFile);
196 public boolean isPDBFileRegistered(String idOrFile)
198 return pdbFileNameId.containsKey(idOrFile)
199 || pdbIdFileName.containsKey(idOrFile);
202 private static StructureSelectionManager nullProvider = null;
204 public static StructureSelectionManager getStructureSelectionManager(
205 StructureSelectionManagerProvider context)
209 if (nullProvider == null)
211 if (instances != null)
215 .getString("error.implementation_error_structure_selection_manager_null"),
216 new NullPointerException(MessageManager
217 .getString("exception.ssm_context_is_null")));
221 nullProvider = new StructureSelectionManager();
226 if (instances == null)
228 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
230 StructureSelectionManager instance = instances.get(context);
231 if (instance == null)
233 if (nullProvider != null)
235 instance = nullProvider;
239 instance = new StructureSelectionManager();
241 instances.put(context, instance);
247 * flag controlling whether SeqMappings are relayed from received sequence
248 * mouse over events to other sequences
250 boolean relaySeqMappings = true;
253 * Enable or disable relay of seqMapping events to other sequences. You might
254 * want to do this if there are many sequence mappings and the host computer
259 public void setRelaySeqMappings(boolean relay)
261 relaySeqMappings = relay;
265 * get the state of the relay seqMappings flag.
267 * @return true if sequence mouse overs are being relayed to other mapped
270 public boolean isRelaySeqMappingsEnabled()
272 return relaySeqMappings;
275 Vector listeners = new Vector();
278 * register a listener for alignment sequence mouseover events
282 public void addStructureViewerListener(Object svl)
284 if (!listeners.contains(svl))
286 listeners.addElement(svl);
291 * Returns the file name for a mapped PDB id (or null if not mapped).
296 public String alreadyMappedToFile(String pdbid)
298 for (StructureMapping sm : mappings)
300 if (sm.getPdbId().equals(pdbid))
309 * Import structure data and register a structure mapping for broadcasting
310 * colouring, mouseovers and selection events (convenience wrapper).
313 * - one or more sequences to be mapped to pdbFile
314 * @param targetChains
315 * - optional chain specification for mapping each sequence to pdb
316 * (may be nill, individual elements may be nill)
318 * - structure data resource
320 * - how to resolve data from resource
321 * @return null or the structure data parsed as a pdb file
323 synchronized public StructureFile setMapping(SequenceI[] sequence,
324 String[] targetChains, String pdbFile, String protocol)
326 return setMapping(true, sequence, targetChains, pdbFile, protocol);
331 * create sequence structure mappings between each sequence and the given
332 * pdbFile (retrieved via the given protocol).
334 * @param forStructureView
335 * when true, record the mapping for use in mouseOvers
337 * @param sequenceArray
338 * - one or more sequences to be mapped to pdbFile
339 * @param targetChainIds
340 * - optional chain specification for mapping each sequence to pdb
341 * (may be nill, individual elements may be nill)
343 * - structure data resource
345 * - how to resolve data from resource
346 * @return null or the structure data parsed as a pdb file
348 synchronized public StructureFile setMapping(boolean forStructureView,
349 SequenceI[] sequenceArray, String[] targetChainIds,
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();
388 if (pdbFile != null && isCIFFile(pdbFile))
390 pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr,
391 secStructServices, pdbFile, protocol);
395 pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
399 if (pdb.getId() != null && pdb.getId().trim().length() > 0
400 && AppletFormatAdapter.FILE.equals(protocol))
402 registerPDBFile(pdb.getId().trim(), pdbFile);
404 } catch (Exception ex)
406 ex.printStackTrace();
414 siftsClient = new SiftsClient(pdb);
416 } catch (SiftsException e)
418 isMapUsingSIFTs = false;
422 String targetChainId;
423 for (int s = 0; s < sequenceArray.length; s++)
425 boolean infChain = true;
426 final SequenceI seq = sequenceArray[s];
427 if (targetChainIds != null && targetChainIds[s] != null)
430 targetChainId = targetChainIds[s];
432 else if (seq.getName().indexOf("|") > -1)
434 targetChainId = seq.getName().substring(
435 seq.getName().lastIndexOf("|") + 1);
436 if (targetChainId.length() > 1)
438 if (targetChainId.trim().length() == 0)
444 // not a valid chain identifier
455 * Attempt pairwise alignment of the sequence with each chain in the PDB,
456 * and remember the highest scoring chain
459 AlignSeq maxAlignseq = null;
460 String maxChainId = " ";
461 PDBChain maxChain = null;
462 boolean first = true;
463 for (PDBChain chain : pdb.getChains())
465 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
468 continue; // don't try to map chains don't match.
470 // TODO: correctly determine sequence type for mixed na/peptide
472 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
473 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
476 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
477 // as.calcScoreMatrix();
478 // as.traceAlignment();
480 if (first || as.maxscore > max
481 || (as.maxscore == max && chain.id.equals(targetChainId)))
487 maxChainId = chain.id;
490 if (maxChain == null)
495 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
497 pdbFile = "INLINE" + pdb.getId();
500 ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
503 setProgressBar(null);
504 setProgressBar("Obtaining mapping with SIFTS");
505 jalview.datamodel.Mapping sqmpping = maxAlignseq
506 .getMappingFromS1(false);
507 if (targetChainId != null && !targetChainId.trim().isEmpty())
509 StructureMapping mapping;
512 mapping = getStructureMapping(seq, pdbFile, targetChainId, pdb,
513 maxChain, sqmpping, maxAlignseq);
514 seqToStrucMapping.add(mapping);
515 } catch (SiftsException e)
517 // e.printStackTrace();
518 // fall back to NW alignment
519 System.err.println(e.getMessage());
520 seqToStrucMapping.add(getNWMappings(seq, pdbFile,
522 maxChain, pdb, maxAlignseq));
529 ArrayList<StructureMapping> tempMapping = new ArrayList<StructureMapping>();
530 for (PDBChain chain : pdb.getChains())
532 StructureMapping mapping = getStructureMapping(seq, pdbFile,
533 chain.id, pdb, chain, sqmpping, maxAlignseq);
534 tempMapping.add(mapping);
536 seqToStrucMapping.addAll(tempMapping);
537 } catch (SiftsException e)
539 // e.printStackTrace();
540 // fall back to NW alignment
541 System.err.println(e.getMessage());
542 seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId,
543 maxChain, pdb, maxAlignseq));
549 setProgressBar(null);
550 setProgressBar("Obtaining mapping with NW alignment");
551 seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId,
552 maxChain, pdb, maxAlignseq));
555 if (forStructureView)
557 mappings.addAll(seqToStrucMapping);
563 private boolean isCIFFile(String filename)
565 String fileExt = filename.substring(filename.lastIndexOf(".") + 1,
567 return "cif".equalsIgnoreCase(fileExt);
570 private StructureMapping getStructureMapping(SequenceI seq,
571 String pdbFile, String targetChainId, StructureFile pdb,
572 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
573 AlignSeq maxAlignseq) throws SiftsException
575 StructureMapping curChainMapping = siftsClient
576 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
579 PDBChain chain = pdb.findChain(targetChainId);
582 chain.transferResidueAnnotation(curChainMapping, sqmpping);
584 } catch (Exception e)
588 return curChainMapping;
591 private StructureMapping getNWMappings(SequenceI seq,
593 String maxChainId, PDBChain maxChain, StructureFile pdb,
594 AlignSeq maxAlignseq)
596 final StringBuilder mappingDetails = new StringBuilder(128);
597 mappingDetails.append(NEWLINE).append(
598 "Sequence \u27f7 Structure mapping details");
599 mappingDetails.append(NEWLINE);
601 .append("Method: inferred with Needleman & Wunsch alignment");
602 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
603 .append(NEWLINE).append("Sequence = ")
604 .append(maxChain.sequence.getSequenceAsString());
605 mappingDetails.append(NEWLINE).append("No of residues = ")
606 .append(maxChain.residues.size()).append(NEWLINE)
608 PrintStream ps = new PrintStream(System.out)
611 public void print(String x)
613 mappingDetails.append(x);
617 public void println()
619 mappingDetails.append(NEWLINE);
623 maxAlignseq.printAlignment(ps);
625 mappingDetails.append(NEWLINE).append("PDB start/end ");
626 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
628 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
629 mappingDetails.append(NEWLINE).append("SEQ start/end ");
630 mappingDetails.append(
631 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
633 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
634 + (seq.getStart() - 1)));
635 mappingDetails.append(NEWLINE);
636 maxChain.makeExactMapping(maxAlignseq, seq);
637 jalview.datamodel.Mapping sqmpping = maxAlignseq
638 .getMappingFromS1(false);
639 maxChain.transferRESNUMFeatures(seq, null);
641 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
648 Atom tmp = maxChain.atoms.elementAt(index);
649 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
650 && tmp.alignmentMapping != -1)
652 resNum = tmp.resNumber;
653 insCode = tmp.insCode;
654 if (tmp.alignmentMapping >= -1)
656 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
662 } while (index < maxChain.atoms.size());
664 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
665 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
666 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
670 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
672 listeners.removeElement(svl);
673 if (svl instanceof SequenceListener)
675 for (int i = 0; i < listeners.size(); i++)
677 if (listeners.elementAt(i) instanceof StructureListener)
679 ((StructureListener) listeners.elementAt(i))
680 .releaseReferences(svl);
685 if (pdbfiles == null)
691 * Remove mappings to the closed listener's PDB files, but first check if
692 * another listener is still interested
694 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
696 StructureListener sl;
697 for (int i = 0; i < listeners.size(); i++)
699 if (listeners.elementAt(i) instanceof StructureListener)
701 sl = (StructureListener) listeners.elementAt(i);
702 for (String pdbfile : sl.getPdbFile())
704 pdbs.remove(pdbfile);
710 * Rebuild the mappings set, retaining only those which are for 'other' PDB
715 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
716 for (StructureMapping sm : mappings)
718 if (!pdbs.contains(sm.pdbfile))
729 * Propagate mouseover of a single position in a structure
735 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
737 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
738 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
739 mouseOverStructure(atoms);
743 * Propagate mouseover or selection of multiple positions in a structure
747 public void mouseOverStructure(List<AtomSpec> atoms)
749 if (listeners == null)
751 // old or prematurely sent event
754 boolean hasSequenceListener = false;
755 for (int i = 0; i < listeners.size(); i++)
757 if (listeners.elementAt(i) instanceof SequenceListener)
759 hasSequenceListener = true;
762 if (!hasSequenceListener)
767 SearchResults results = new SearchResults();
768 for (AtomSpec atom : atoms)
770 SequenceI lastseq = null;
772 for (StructureMapping sm : mappings)
774 if (sm.pdbfile.equals(atom.getPdbFile())
775 && sm.pdbchain.equals(atom.getChain()))
777 int indexpos = sm.getSeqPos(atom.getPdbResNum());
778 if (lastipos != indexpos && lastseq != sm.sequence)
780 results.addResult(sm.sequence, indexpos, indexpos);
782 lastseq = sm.sequence;
783 // construct highlighted sequence list
784 for (AlignedCodonFrame acf : seqmappings)
786 acf.markMappedRegion(sm.sequence, indexpos, results);
792 for (Object li : listeners)
794 if (li instanceof SequenceListener)
796 ((SequenceListener) li).highlightSequence(results);
802 * highlight regions associated with a position (indexpos) in seq
805 * the sequence that the mouse over occurred on
807 * the absolute position being mouseovered in seq (0 to seq.length())
809 * the sequence position (if -1, seq.findPosition is called to
810 * resolve the residue number)
812 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
815 boolean hasSequenceListeners = handlingVamsasMo
816 || !seqmappings.isEmpty();
817 SearchResults results = null;
820 seqPos = seq.findPosition(indexpos);
822 for (int i = 0; i < listeners.size(); i++)
824 Object listener = listeners.elementAt(i);
825 if (listener == source)
827 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
828 // Temporary fudge with SequenceListener.getVamsasSource()
831 if (listener instanceof StructureListener)
833 highlightStructure((StructureListener) listener, seq, seqPos);
837 if (listener instanceof SequenceListener)
839 final SequenceListener seqListener = (SequenceListener) listener;
840 if (hasSequenceListeners
841 && seqListener.getVamsasSource() != source)
843 if (relaySeqMappings)
847 results = MappingUtils.buildSearchResults(seq, seqPos,
850 if (handlingVamsasMo)
852 results.addResult(seq, seqPos, seqPos);
855 if (!results.isEmpty())
857 seqListener.highlightSequence(results);
862 else if (listener instanceof VamsasListener && !handlingVamsasMo)
864 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
867 else if (listener instanceof SecondaryStructureListener)
869 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
877 * Send suitable messages to a StructureListener to highlight atoms
878 * corresponding to the given sequence position(s)
884 public void highlightStructure(StructureListener sl, SequenceI seq,
887 if (!sl.isListeningFor(seq))
892 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
893 for (StructureMapping sm : mappings)
895 if (sm.sequence == seq
896 || sm.sequence == seq.getDatasetSequence()
897 || (sm.sequence.getDatasetSequence() != null && sm.sequence
898 .getDatasetSequence() == seq.getDatasetSequence()))
900 for (int index : positions)
902 atomNo = sm.getAtomNum(index);
906 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
907 .getPDBResNum(index), atomNo));
912 sl.highlightAtoms(atoms);
916 * true if a mouse over event from an external (ie Vamsas) source is being
919 boolean handlingVamsasMo = false;
924 * as mouseOverSequence but only route event to SequenceListeners
928 * in an alignment sequence
930 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
933 handlingVamsasMo = true;
934 long msg = sequenceI.hashCode() * (1 + position);
938 mouseOverSequence(sequenceI, position, -1, source);
940 handlingVamsasMo = false;
943 public Annotation[] colourSequenceFromStructure(SequenceI seq,
947 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
948 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
950 * Annotation [] annotations = new Annotation[seq.getLength()];
952 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
953 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
954 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
956 * for (int j = 0; j < mappings.length; j++) {
958 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
959 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
960 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
961 * "+mappings[j].pdbfile);
963 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
964 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
966 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
967 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
968 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
969 * mappings[j].pdbfile); }
971 * annotations[index] = new Annotation("X",null,' ',0,col); } return
972 * annotations; } } } }
974 * return annotations;
978 public void structureSelectionChanged()
982 public void sequenceSelectionChanged()
986 public void sequenceColoursChanged(Object source)
988 StructureListener sl;
989 for (int i = 0; i < listeners.size(); i++)
991 if (listeners.elementAt(i) instanceof StructureListener)
993 sl = (StructureListener) listeners.elementAt(i);
994 sl.updateColours(source);
999 public StructureMapping[] getMapping(String pdbfile)
1001 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1002 for (StructureMapping sm : mappings)
1004 if (sm.pdbfile.equals(pdbfile))
1009 return tmp.toArray(new StructureMapping[tmp.size()]);
1013 * Returns a readable description of all mappings for the given pdbfile to any
1014 * of the given sequences
1020 public String printMappings(String pdbfile, List<SequenceI> seqs)
1022 if (pdbfile == null || seqs == null || seqs.isEmpty())
1027 StringBuilder sb = new StringBuilder(64);
1028 for (StructureMapping sm : mappings)
1030 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1032 sb.append(sm.mappingDetails);
1034 // separator makes it easier to read multiple mappings
1035 sb.append("=====================");
1041 return sb.toString();
1045 * Remove the given mapping
1049 public void deregisterMapping(AlignedCodonFrame acf)
1053 boolean removed = seqmappings.remove(acf);
1054 if (removed && seqmappings.isEmpty())
1056 System.out.println("All mappings removed");
1062 * Add each of the given codonFrames to the stored set, if not aready present.
1066 public void registerMappings(List<AlignedCodonFrame> mappings)
1068 if (mappings != null)
1070 for (AlignedCodonFrame acf : mappings)
1072 registerMapping(acf);
1078 * Add the given mapping to the stored set, unless already stored.
1080 public void registerMapping(AlignedCodonFrame acf)
1084 if (!seqmappings.contains(acf))
1086 seqmappings.add(acf);
1092 * Resets this object to its initial state by removing all registered
1093 * listeners, codon mappings, PDB file mappings
1095 public void resetAll()
1097 if (mappings != null)
1101 if (seqmappings != null)
1103 seqmappings.clear();
1105 if (sel_listeners != null)
1107 sel_listeners.clear();
1109 if (listeners != null)
1113 if (commandListeners != null)
1115 commandListeners.clear();
1117 if (view_listeners != null)
1119 view_listeners.clear();
1121 if (pdbFileNameId != null)
1123 pdbFileNameId.clear();
1125 if (pdbIdFileName != null)
1127 pdbIdFileName.clear();
1131 public void addSelectionListener(SelectionListener selecter)
1133 if (!sel_listeners.contains(selecter))
1135 sel_listeners.add(selecter);
1139 public void removeSelectionListener(SelectionListener toremove)
1141 if (sel_listeners.contains(toremove))
1143 sel_listeners.remove(toremove);
1147 public synchronized void sendSelection(
1148 jalview.datamodel.SequenceGroup selection,
1149 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1151 for (SelectionListener slis : sel_listeners)
1155 slis.selection(selection, colsel, source);
1160 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1162 public synchronized void sendViewPosition(
1163 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1164 int startSeq, int endSeq)
1167 if (view_listeners != null && view_listeners.size() > 0)
1169 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1171 while (listeners.hasMoreElements())
1173 AlignmentViewPanelListener slis = listeners.nextElement();
1176 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1184 * release all references associated with this manager provider
1186 * @param jalviewLite
1188 public static void release(StructureSelectionManagerProvider jalviewLite)
1190 // synchronized (instances)
1192 if (instances == null)
1196 StructureSelectionManager mnger = (instances.get(jalviewLite));
1199 instances.remove(jalviewLite);
1203 } catch (Throwable x)
1210 public void registerPDBEntry(PDBEntry pdbentry)
1212 if (pdbentry.getFile() != null
1213 && pdbentry.getFile().trim().length() > 0)
1215 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1219 public void addCommandListener(CommandListener cl)
1221 if (!commandListeners.contains(cl))
1223 commandListeners.add(cl);
1227 public boolean hasCommandListener(CommandListener cl)
1229 return this.commandListeners.contains(cl);
1232 public boolean removeCommandListener(CommandListener l)
1234 return commandListeners.remove(l);
1238 * Forward a command to any command listeners (except for the command's
1242 * the command to be broadcast (in its form after being performed)
1244 * if true, the command was being 'undone'
1247 public void commandPerformed(CommandI command, boolean undo,
1248 VamsasSource source)
1250 for (CommandListener listener : commandListeners)
1252 listener.mirrorCommand(command, undo, this, source);
1257 * Returns a new CommandI representing the given command as mapped to the
1258 * given sequences. If no mapping could be made, or the command is not of a
1259 * mappable kind, returns null.
1267 public CommandI mapCommand(CommandI command, boolean undo,
1268 final AlignmentI mapTo, char gapChar)
1270 if (command instanceof EditCommand)
1272 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1273 mapTo, gapChar, seqmappings);
1275 else if (command instanceof OrderCommand)
1277 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1278 mapTo, seqmappings);
1283 public IProgressIndicator getProgressIndicator()
1285 return progressIndicator;
1288 public void setProgressIndicator(IProgressIndicator progressIndicator)
1290 this.progressIndicator = progressIndicator;
1293 public long getProgressSessionId()
1295 return progressSessionId;
1298 public void setProgressSessionId(long progressSessionId)
1300 this.progressSessionId = progressSessionId;
1303 public void setProgressBar(String message)
1305 if (progressIndicator == null)
1309 progressIndicator.setProgressBar(message, progressSessionId);
1312 public List<AlignedCodonFrame> getSequenceMappings()