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 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);
517 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
518 } catch (SiftsException e)
520 // fall back to NW alignment
521 System.err.println(e.getMessage());
522 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
523 targetChainId, maxChain, pdb, maxAlignseq);
524 seqToStrucMapping.add(nwMapping);
529 ArrayList<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
530 for (PDBChain chain : pdb.getChains())
534 StructureMapping siftsMapping = getStructureMapping(seq,
536 chain.id, pdb, chain, sqmpping, maxAlignseq);
537 foundSiftsMappings.add(siftsMapping);
538 } catch (SiftsException e)
540 System.err.println(e.getMessage());
543 if (!foundSiftsMappings.isEmpty())
545 seqToStrucMapping.addAll(foundSiftsMappings);
546 maxChain.makeExactMapping(maxAlignseq, seq);
547 maxChain.transferRESNUMFeatures(seq, null);
548 maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
553 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
554 maxChainId, maxChain, pdb, maxAlignseq);
555 seqToStrucMapping.add(nwMapping);
561 setProgressBar(null);
562 setProgressBar("Obtaining mapping with NW alignment");
563 seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId,
564 maxChain, pdb, maxAlignseq));
567 if (forStructureView)
569 mappings.addAll(seqToStrucMapping);
575 private boolean isCIFFile(String filename)
577 String fileExt = filename.substring(filename.lastIndexOf(".") + 1,
579 return "cif".equalsIgnoreCase(fileExt);
582 private StructureMapping getStructureMapping(SequenceI seq,
583 String pdbFile, String targetChainId, StructureFile pdb,
584 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
585 AlignSeq maxAlignseq) throws SiftsException
587 StructureMapping curChainMapping = siftsClient
588 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
591 PDBChain chain = pdb.findChain(targetChainId);
594 chain.transferResidueAnnotation(curChainMapping, sqmpping);
596 } catch (Exception e)
600 return curChainMapping;
603 private StructureMapping getNWMappings(SequenceI seq,
605 String maxChainId, PDBChain maxChain, StructureFile pdb,
606 AlignSeq maxAlignseq)
608 final StringBuilder mappingDetails = new StringBuilder(128);
609 mappingDetails.append(NEWLINE).append(
610 "Sequence \u27f7 Structure mapping details");
611 mappingDetails.append(NEWLINE);
613 .append("Method: inferred with Needleman & Wunsch alignment");
614 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
615 .append(NEWLINE).append("Sequence = ")
616 .append(maxChain.sequence.getSequenceAsString());
617 mappingDetails.append(NEWLINE).append("No of residues = ")
618 .append(maxChain.residues.size()).append(NEWLINE)
620 PrintStream ps = new PrintStream(System.out)
623 public void print(String x)
625 mappingDetails.append(x);
629 public void println()
631 mappingDetails.append(NEWLINE);
635 maxAlignseq.printAlignment(ps);
637 mappingDetails.append(NEWLINE).append("PDB start/end ");
638 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
640 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
641 mappingDetails.append(NEWLINE).append("SEQ start/end ");
642 mappingDetails.append(
643 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
645 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
646 + (seq.getStart() - 1)));
647 mappingDetails.append(NEWLINE);
648 maxChain.makeExactMapping(maxAlignseq, seq);
649 jalview.datamodel.Mapping sqmpping = maxAlignseq
650 .getMappingFromS1(false);
651 maxChain.transferRESNUMFeatures(seq, null);
653 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
660 Atom tmp = maxChain.atoms.elementAt(index);
661 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
662 && tmp.alignmentMapping != -1)
664 resNum = tmp.resNumber;
665 insCode = tmp.insCode;
666 if (tmp.alignmentMapping >= -1)
668 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
674 } while (index < maxChain.atoms.size());
676 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
677 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
678 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
682 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
684 listeners.removeElement(svl);
685 if (svl instanceof SequenceListener)
687 for (int i = 0; i < listeners.size(); i++)
689 if (listeners.elementAt(i) instanceof StructureListener)
691 ((StructureListener) listeners.elementAt(i))
692 .releaseReferences(svl);
697 if (pdbfiles == null)
703 * Remove mappings to the closed listener's PDB files, but first check if
704 * another listener is still interested
706 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
708 StructureListener sl;
709 for (int i = 0; i < listeners.size(); i++)
711 if (listeners.elementAt(i) instanceof StructureListener)
713 sl = (StructureListener) listeners.elementAt(i);
714 for (String pdbfile : sl.getPdbFile())
716 pdbs.remove(pdbfile);
722 * Rebuild the mappings set, retaining only those which are for 'other' PDB
727 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
728 for (StructureMapping sm : mappings)
730 if (!pdbs.contains(sm.pdbfile))
741 * Propagate mouseover of a single position in a structure
747 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
749 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
750 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
751 mouseOverStructure(atoms);
755 * Propagate mouseover or selection of multiple positions in a structure
759 public void mouseOverStructure(List<AtomSpec> atoms)
761 if (listeners == null)
763 // old or prematurely sent event
766 boolean hasSequenceListener = false;
767 for (int i = 0; i < listeners.size(); i++)
769 if (listeners.elementAt(i) instanceof SequenceListener)
771 hasSequenceListener = true;
774 if (!hasSequenceListener)
779 SearchResults results = new SearchResults();
780 for (AtomSpec atom : atoms)
782 SequenceI lastseq = null;
784 for (StructureMapping sm : mappings)
786 if (sm.pdbfile.equals(atom.getPdbFile())
787 && sm.pdbchain.equals(atom.getChain()))
789 int indexpos = sm.getSeqPos(atom.getPdbResNum());
790 if (lastipos != indexpos && lastseq != sm.sequence)
792 results.addResult(sm.sequence, indexpos, indexpos);
794 lastseq = sm.sequence;
795 // construct highlighted sequence list
796 for (AlignedCodonFrame acf : seqmappings)
798 acf.markMappedRegion(sm.sequence, indexpos, results);
804 for (Object li : listeners)
806 if (li instanceof SequenceListener)
808 ((SequenceListener) li).highlightSequence(results);
814 * highlight regions associated with a position (indexpos) in seq
817 * the sequence that the mouse over occurred on
819 * the absolute position being mouseovered in seq (0 to seq.length())
821 * the sequence position (if -1, seq.findPosition is called to
822 * resolve the residue number)
824 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
827 boolean hasSequenceListeners = handlingVamsasMo
828 || !seqmappings.isEmpty();
829 SearchResults results = null;
832 seqPos = seq.findPosition(indexpos);
834 for (int i = 0; i < listeners.size(); i++)
836 Object listener = listeners.elementAt(i);
837 if (listener == source)
839 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
840 // Temporary fudge with SequenceListener.getVamsasSource()
843 if (listener instanceof StructureListener)
845 highlightStructure((StructureListener) listener, seq, seqPos);
849 if (listener instanceof SequenceListener)
851 final SequenceListener seqListener = (SequenceListener) listener;
852 if (hasSequenceListeners
853 && seqListener.getVamsasSource() != source)
855 if (relaySeqMappings)
859 results = MappingUtils.buildSearchResults(seq, seqPos,
862 if (handlingVamsasMo)
864 results.addResult(seq, seqPos, seqPos);
867 if (!results.isEmpty())
869 seqListener.highlightSequence(results);
874 else if (listener instanceof VamsasListener && !handlingVamsasMo)
876 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
879 else if (listener instanceof SecondaryStructureListener)
881 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
889 * Send suitable messages to a StructureListener to highlight atoms
890 * corresponding to the given sequence position(s)
896 public void highlightStructure(StructureListener sl, SequenceI seq,
899 if (!sl.isListeningFor(seq))
904 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
905 for (StructureMapping sm : mappings)
907 if (sm.sequence == seq
908 || sm.sequence == seq.getDatasetSequence()
909 || (sm.sequence.getDatasetSequence() != null && sm.sequence
910 .getDatasetSequence() == seq.getDatasetSequence()))
912 for (int index : positions)
914 atomNo = sm.getAtomNum(index);
918 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
919 .getPDBResNum(index), atomNo));
924 sl.highlightAtoms(atoms);
928 * true if a mouse over event from an external (ie Vamsas) source is being
931 boolean handlingVamsasMo = false;
936 * as mouseOverSequence but only route event to SequenceListeners
940 * in an alignment sequence
942 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
945 handlingVamsasMo = true;
946 long msg = sequenceI.hashCode() * (1 + position);
950 mouseOverSequence(sequenceI, position, -1, source);
952 handlingVamsasMo = false;
955 public Annotation[] colourSequenceFromStructure(SequenceI seq,
959 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
960 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
962 * Annotation [] annotations = new Annotation[seq.getLength()];
964 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
965 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
966 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
968 * for (int j = 0; j < mappings.length; j++) {
970 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
971 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
972 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
973 * "+mappings[j].pdbfile);
975 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
976 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
978 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
979 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
980 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
981 * mappings[j].pdbfile); }
983 * annotations[index] = new Annotation("X",null,' ',0,col); } return
984 * annotations; } } } }
986 * return annotations;
990 public void structureSelectionChanged()
994 public void sequenceSelectionChanged()
998 public void sequenceColoursChanged(Object source)
1000 StructureListener sl;
1001 for (int i = 0; i < listeners.size(); i++)
1003 if (listeners.elementAt(i) instanceof StructureListener)
1005 sl = (StructureListener) listeners.elementAt(i);
1006 sl.updateColours(source);
1011 public StructureMapping[] getMapping(String pdbfile)
1013 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1014 for (StructureMapping sm : mappings)
1016 if (sm.pdbfile.equals(pdbfile))
1021 return tmp.toArray(new StructureMapping[tmp.size()]);
1025 * Returns a readable description of all mappings for the given pdbfile to any
1026 * of the given sequences
1032 public String printMappings(String pdbfile, List<SequenceI> seqs)
1034 if (pdbfile == null || seqs == null || seqs.isEmpty())
1039 StringBuilder sb = new StringBuilder(64);
1040 for (StructureMapping sm : mappings)
1042 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1044 sb.append(sm.mappingDetails);
1046 // separator makes it easier to read multiple mappings
1047 sb.append("=====================");
1053 return sb.toString();
1057 * Remove the given mapping
1061 public void deregisterMapping(AlignedCodonFrame acf)
1065 boolean removed = seqmappings.remove(acf);
1066 if (removed && seqmappings.isEmpty())
1068 System.out.println("All mappings removed");
1074 * Add each of the given codonFrames to the stored set, if not aready present.
1078 public void registerMappings(List<AlignedCodonFrame> mappings)
1080 if (mappings != null)
1082 for (AlignedCodonFrame acf : mappings)
1084 registerMapping(acf);
1090 * Add the given mapping to the stored set, unless already stored.
1092 public void registerMapping(AlignedCodonFrame acf)
1096 if (!seqmappings.contains(acf))
1098 seqmappings.add(acf);
1104 * Resets this object to its initial state by removing all registered
1105 * listeners, codon mappings, PDB file mappings
1107 public void resetAll()
1109 if (mappings != null)
1113 if (seqmappings != null)
1115 seqmappings.clear();
1117 if (sel_listeners != null)
1119 sel_listeners.clear();
1121 if (listeners != null)
1125 if (commandListeners != null)
1127 commandListeners.clear();
1129 if (view_listeners != null)
1131 view_listeners.clear();
1133 if (pdbFileNameId != null)
1135 pdbFileNameId.clear();
1137 if (pdbIdFileName != null)
1139 pdbIdFileName.clear();
1143 public void addSelectionListener(SelectionListener selecter)
1145 if (!sel_listeners.contains(selecter))
1147 sel_listeners.add(selecter);
1151 public void removeSelectionListener(SelectionListener toremove)
1153 if (sel_listeners.contains(toremove))
1155 sel_listeners.remove(toremove);
1159 public synchronized void sendSelection(
1160 jalview.datamodel.SequenceGroup selection,
1161 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1163 for (SelectionListener slis : sel_listeners)
1167 slis.selection(selection, colsel, source);
1172 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1174 public synchronized void sendViewPosition(
1175 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1176 int startSeq, int endSeq)
1179 if (view_listeners != null && view_listeners.size() > 0)
1181 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1183 while (listeners.hasMoreElements())
1185 AlignmentViewPanelListener slis = listeners.nextElement();
1188 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1196 * release all references associated with this manager provider
1198 * @param jalviewLite
1200 public static void release(StructureSelectionManagerProvider jalviewLite)
1202 // synchronized (instances)
1204 if (instances == null)
1208 StructureSelectionManager mnger = (instances.get(jalviewLite));
1211 instances.remove(jalviewLite);
1215 } catch (Throwable x)
1222 public void registerPDBEntry(PDBEntry pdbentry)
1224 if (pdbentry.getFile() != null
1225 && pdbentry.getFile().trim().length() > 0)
1227 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1231 public void addCommandListener(CommandListener cl)
1233 if (!commandListeners.contains(cl))
1235 commandListeners.add(cl);
1239 public boolean hasCommandListener(CommandListener cl)
1241 return this.commandListeners.contains(cl);
1244 public boolean removeCommandListener(CommandListener l)
1246 return commandListeners.remove(l);
1250 * Forward a command to any command listeners (except for the command's
1254 * the command to be broadcast (in its form after being performed)
1256 * if true, the command was being 'undone'
1259 public void commandPerformed(CommandI command, boolean undo,
1260 VamsasSource source)
1262 for (CommandListener listener : commandListeners)
1264 listener.mirrorCommand(command, undo, this, source);
1269 * Returns a new CommandI representing the given command as mapped to the
1270 * given sequences. If no mapping could be made, or the command is not of a
1271 * mappable kind, returns null.
1279 public CommandI mapCommand(CommandI command, boolean undo,
1280 final AlignmentI mapTo, char gapChar)
1282 if (command instanceof EditCommand)
1284 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1285 mapTo, gapChar, seqmappings);
1287 else if (command instanceof OrderCommand)
1289 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1290 mapTo, seqmappings);
1295 public IProgressIndicator getProgressIndicator()
1297 return progressIndicator;
1300 public void setProgressIndicator(IProgressIndicator progressIndicator)
1302 this.progressIndicator = progressIndicator;
1305 public long getProgressSessionId()
1307 return progressSessionId;
1310 public void setProgressSessionId(long progressSessionId)
1312 this.progressSessionId = progressSessionId;
1315 public void setProgressBar(String message)
1317 if (progressIndicator == null)
1321 progressIndicator.setProgressBar(message, progressSessionId);
1324 public List<AlignedCodonFrame> getSequenceMappings()