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.ext.jmol.JmolParser;
36 import jalview.gui.IProgressIndicator;
37 import jalview.io.AppletFormatAdapter;
38 import jalview.io.StructureFile;
39 import jalview.util.MappingUtils;
40 import jalview.util.MessageManager;
41 import jalview.ws.sifts.SiftsClient;
42 import jalview.ws.sifts.SiftsException;
43 import jalview.ws.sifts.SiftsSettings;
45 import java.io.PrintStream;
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.Collections;
49 import java.util.Enumeration;
50 import java.util.HashMap;
51 import java.util.IdentityHashMap;
52 import java.util.List;
54 import java.util.Vector;
57 import MCview.PDBChain;
58 import MCview.PDBfile;
60 public class StructureSelectionManager
62 public final static String NEWLINE = System.lineSeparator();
64 static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
66 private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
68 private boolean processSecondaryStructure = false;
70 private boolean secStructServices = false;
72 private boolean addTempFacAnnot = false;
74 private IProgressIndicator progressIndicator;
76 private SiftsClient siftsClient = null;
78 private long progressSessionId;
81 * Set of any registered mappings between (dataset) sequences.
83 private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
85 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
87 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
90 * @return true if will try to use external services for processing secondary
93 public boolean isSecStructServices()
95 return secStructServices;
99 * control use of external services for processing secondary structure
101 * @param secStructServices
103 public void setSecStructServices(boolean secStructServices)
105 this.secStructServices = secStructServices;
109 * flag controlling addition of any kind of structural annotation
111 * @return true if temperature factor annotation will be added
113 public boolean isAddTempFacAnnot()
115 return addTempFacAnnot;
119 * set flag controlling addition of structural annotation
121 * @param addTempFacAnnot
123 public void setAddTempFacAnnot(boolean addTempFacAnnot)
125 this.addTempFacAnnot = addTempFacAnnot;
130 * @return if true, the structure manager will attempt to add secondary
131 * structure lines for unannotated sequences
134 public boolean isProcessSecondaryStructure()
136 return processSecondaryStructure;
140 * Control whether structure manager will try to annotate mapped sequences
141 * with secondary structure from PDB data.
145 public void setProcessSecondaryStructure(boolean enable)
147 processSecondaryStructure = enable;
151 * debug function - write all mappings to stdout
153 public void reportMapping()
155 if (mappings.isEmpty())
157 System.err.println("reportMapping: No PDB/Sequence mappings.");
161 System.err.println("reportMapping: There are " + mappings.size()
164 for (StructureMapping sm : mappings)
166 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
172 * map between the PDB IDs (or structure identifiers) used by Jalview and the
173 * absolute filenames for PDB data that corresponds to it
175 Map<String, String> pdbIdFileName = new HashMap<String, String>();
177 Map<String, String> pdbFileNameId = new HashMap<String, String>();
179 public void registerPDBFile(String idForFile, String absoluteFile)
181 pdbIdFileName.put(idForFile, absoluteFile);
182 pdbFileNameId.put(absoluteFile, idForFile);
185 public String findIdForPDBFile(String idOrFile)
187 String id = pdbFileNameId.get(idOrFile);
191 public String findFileForPDBId(String idOrFile)
193 String id = pdbIdFileName.get(idOrFile);
197 public boolean isPDBFileRegistered(String idOrFile)
199 return pdbFileNameId.containsKey(idOrFile)
200 || pdbIdFileName.containsKey(idOrFile);
203 private static StructureSelectionManager nullProvider = null;
205 public static StructureSelectionManager getStructureSelectionManager(
206 StructureSelectionManagerProvider context)
210 if (nullProvider == null)
212 if (instances != null)
216 .getString("error.implementation_error_structure_selection_manager_null"),
217 new NullPointerException(MessageManager
218 .getString("exception.ssm_context_is_null")));
222 nullProvider = new StructureSelectionManager();
227 if (instances == null)
229 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
231 StructureSelectionManager instance = instances.get(context);
232 if (instance == null)
234 if (nullProvider != null)
236 instance = nullProvider;
240 instance = new StructureSelectionManager();
242 instances.put(context, instance);
248 * flag controlling whether SeqMappings are relayed from received sequence
249 * mouse over events to other sequences
251 boolean relaySeqMappings = true;
254 * Enable or disable relay of seqMapping events to other sequences. You might
255 * want to do this if there are many sequence mappings and the host computer
260 public void setRelaySeqMappings(boolean relay)
262 relaySeqMappings = relay;
266 * get the state of the relay seqMappings flag.
268 * @return true if sequence mouse overs are being relayed to other mapped
271 public boolean isRelaySeqMappingsEnabled()
273 return relaySeqMappings;
276 Vector listeners = new Vector();
279 * register a listener for alignment sequence mouseover events
283 public void addStructureViewerListener(Object svl)
285 if (!listeners.contains(svl))
287 listeners.addElement(svl);
292 * Returns the file name for a mapped PDB id (or null if not mapped).
297 public String alreadyMappedToFile(String pdbid)
299 for (StructureMapping sm : mappings)
301 if (sm.getPdbId().equals(pdbid))
310 * Import structure data and register a structure mapping for broadcasting
311 * colouring, mouseovers and selection events (convenience wrapper).
314 * - one or more sequences to be mapped to pdbFile
315 * @param targetChains
316 * - optional chain specification for mapping each sequence to pdb
317 * (may be nill, individual elements may be nill)
319 * - structure data resource
321 * - how to resolve data from resource
322 * @return null or the structure data parsed as a pdb file
324 synchronized public StructureFile setMapping(SequenceI[] sequence,
325 String[] targetChains, String pdbFile, String protocol)
327 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,
350 String pdbFile, String protocol)
353 * There will be better ways of doing this in the future, for now we'll use
354 * the tried and tested MCview pdb mapping
356 boolean parseSecStr = processSecondaryStructure;
357 if (isPDBFileRegistered(pdbFile))
359 for (SequenceI sq : sequenceArray)
362 while (ds.getDatasetSequence() != null)
364 ds = ds.getDatasetSequence();
367 if (ds.getAnnotation() != null)
369 for (AlignmentAnnotation ala : ds.getAnnotation())
371 // false if any annotation present from this structure
372 // JBPNote this fails for jmol/chimera view because the *file* is
373 // passed, not the structure data ID -
374 if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
382 StructureFile pdb = null;
383 boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
386 pdb = new JmolParser(pdbFile, protocol);
388 if (pdb.getId() != null && pdb.getId().trim().length() > 0
389 && AppletFormatAdapter.FILE.equals(protocol))
391 registerPDBFile(pdb.getId().trim(), pdbFile);
393 // if PDB/mmCIF file is local then don't perform SIFTS MAPPING
394 if (pdb.getId().contains("."))
396 isMapUsingSIFTs = false;
398 } catch (Exception ex)
400 ex.printStackTrace();
408 siftsClient = new SiftsClient(pdb);
410 } catch (SiftsException e)
412 isMapUsingSIFTs = false;
416 String targetChainId;
417 for (int s = 0; s < sequenceArray.length; s++)
419 boolean infChain = true;
420 final SequenceI seq = sequenceArray[s];
422 while (ds.getDatasetSequence() != null)
424 ds = ds.getDatasetSequence();
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>();
501 if (isMapUsingSIFTs && seq.isProtein())
503 setProgressBar(null);
504 setProgressBar(MessageManager
505 .getString("status.obtaining_mapping_with_sifts"));
506 jalview.datamodel.Mapping sqmpping = maxAlignseq
507 .getMappingFromS1(false);
508 if (targetChainId != null && !targetChainId.trim().isEmpty())
510 StructureMapping siftsMapping;
513 siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
514 pdb, maxChain, sqmpping, maxAlignseq);
515 seqToStrucMapping.add(siftsMapping);
516 maxChain.makeExactMapping(maxAlignseq, seq);
517 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
519 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
520 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
522 } catch (SiftsException e)
524 // fall back to NW alignment
525 System.err.println(e.getMessage());
526 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
527 targetChainId, maxChain, pdb, maxAlignseq);
528 seqToStrucMapping.add(nwMapping);
529 maxChain.makeExactMapping(maxAlignseq, seq);
530 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
532 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
533 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
538 ArrayList<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
539 for (PDBChain chain : pdb.getChains())
543 StructureMapping siftsMapping = getStructureMapping(seq,
544 pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
545 foundSiftsMappings.add(siftsMapping);
546 } catch (SiftsException e)
548 System.err.println(e.getMessage());
551 if (!foundSiftsMappings.isEmpty())
553 seqToStrucMapping.addAll(foundSiftsMappings);
554 maxChain.makeExactMapping(maxAlignseq, seq);
555 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
557 maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
559 ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0));
563 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
564 maxChainId, maxChain, pdb, maxAlignseq);
565 seqToStrucMapping.add(nwMapping);
566 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
568 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
569 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
575 setProgressBar(null);
576 setProgressBar(MessageManager
577 .getString("status.obtaining_mapping_with_nw_alignment"));
578 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
579 maxChainId, maxChain, pdb, maxAlignseq);
580 seqToStrucMapping.add(nwMapping);
581 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
585 if (forStructureView)
587 mappings.addAll(seqToStrucMapping);
593 private boolean isCIFFile(String filename)
595 String fileExt = filename.substring(filename.lastIndexOf(".") + 1,
597 return "cif".equalsIgnoreCase(fileExt);
601 * retrieve a mapping for seq from SIFTs using associated DBRefEntry for
606 * @param targetChainId
612 * @throws SiftsException
614 private StructureMapping getStructureMapping(SequenceI seq,
615 String pdbFile, String targetChainId, StructureFile pdb,
616 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
617 AlignSeq maxAlignseq) throws SiftsException
619 StructureMapping curChainMapping = siftsClient
620 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
623 PDBChain chain = pdb.findChain(targetChainId);
626 chain.transferResidueAnnotation(curChainMapping, sqmpping);
628 } catch (Exception e)
632 return curChainMapping;
635 private StructureMapping getNWMappings(SequenceI seq, String pdbFile,
636 String maxChainId, PDBChain maxChain, StructureFile pdb,
637 AlignSeq maxAlignseq)
639 final StringBuilder mappingDetails = new StringBuilder(128);
640 mappingDetails.append(NEWLINE).append(
641 "Sequence \u27f7 Structure mapping details");
642 mappingDetails.append(NEWLINE);
644 .append("Method: inferred with Needleman & Wunsch alignment");
645 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
646 .append(NEWLINE).append("Sequence = ")
647 .append(maxChain.sequence.getSequenceAsString());
648 mappingDetails.append(NEWLINE).append("No of residues = ")
649 .append(maxChain.residues.size()).append(NEWLINE)
651 PrintStream ps = new PrintStream(System.out)
654 public void print(String x)
656 mappingDetails.append(x);
660 public void println()
662 mappingDetails.append(NEWLINE);
666 maxAlignseq.printAlignment(ps);
668 mappingDetails.append(NEWLINE).append("PDB start/end ");
669 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
671 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
672 mappingDetails.append(NEWLINE).append("SEQ start/end ");
673 mappingDetails.append(
674 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
676 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
677 + (seq.getStart() - 1)));
678 mappingDetails.append(NEWLINE);
679 maxChain.makeExactMapping(maxAlignseq, seq);
680 jalview.datamodel.Mapping sqmpping = maxAlignseq
681 .getMappingFromS1(false);
682 maxChain.transferRESNUMFeatures(seq, null);
684 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
691 Atom tmp = maxChain.atoms.elementAt(index);
692 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
693 && tmp.alignmentMapping != -1)
695 resNum = tmp.resNumber;
696 insCode = tmp.insCode;
697 if (tmp.alignmentMapping >= -1)
699 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
705 } while (index < maxChain.atoms.size());
707 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
708 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
709 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
713 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
715 listeners.removeElement(svl);
716 if (svl instanceof SequenceListener)
718 for (int i = 0; i < listeners.size(); i++)
720 if (listeners.elementAt(i) instanceof StructureListener)
722 ((StructureListener) listeners.elementAt(i))
723 .releaseReferences(svl);
728 if (pdbfiles == null)
734 * Remove mappings to the closed listener's PDB files, but first check if
735 * another listener is still interested
737 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
739 StructureListener sl;
740 for (int i = 0; i < listeners.size(); i++)
742 if (listeners.elementAt(i) instanceof StructureListener)
744 sl = (StructureListener) listeners.elementAt(i);
745 for (String pdbfile : sl.getPdbFile())
747 pdbs.remove(pdbfile);
753 * Rebuild the mappings set, retaining only those which are for 'other' PDB
758 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
759 for (StructureMapping sm : mappings)
761 if (!pdbs.contains(sm.pdbfile))
772 * Propagate mouseover of a single position in a structure
778 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
780 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
781 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
782 mouseOverStructure(atoms);
786 * Propagate mouseover or selection of multiple positions in a structure
790 public void mouseOverStructure(List<AtomSpec> atoms)
792 if (listeners == null)
794 // old or prematurely sent event
797 boolean hasSequenceListener = false;
798 for (int i = 0; i < listeners.size(); i++)
800 if (listeners.elementAt(i) instanceof SequenceListener)
802 hasSequenceListener = true;
805 if (!hasSequenceListener)
810 SearchResults results = new SearchResults();
811 for (AtomSpec atom : atoms)
813 SequenceI lastseq = null;
815 for (StructureMapping sm : mappings)
817 if (sm.pdbfile.equals(atom.getPdbFile())
818 && sm.pdbchain.equals(atom.getChain()))
820 int indexpos = sm.getSeqPos(atom.getPdbResNum());
821 if (lastipos != indexpos && lastseq != sm.sequence)
823 results.addResult(sm.sequence, indexpos, indexpos);
825 lastseq = sm.sequence;
826 // construct highlighted sequence list
827 for (AlignedCodonFrame acf : seqmappings)
829 acf.markMappedRegion(sm.sequence, indexpos, results);
835 for (Object li : listeners)
837 if (li instanceof SequenceListener)
839 ((SequenceListener) li).highlightSequence(results);
845 * highlight regions associated with a position (indexpos) in seq
848 * the sequence that the mouse over occurred on
850 * the absolute position being mouseovered in seq (0 to seq.length())
852 * the sequence position (if -1, seq.findPosition is called to
853 * resolve the residue number)
855 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
858 boolean hasSequenceListeners = handlingVamsasMo
859 || !seqmappings.isEmpty();
860 SearchResults results = null;
863 seqPos = seq.findPosition(indexpos);
865 for (int i = 0; i < listeners.size(); i++)
867 Object listener = listeners.elementAt(i);
868 if (listener == source)
870 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
871 // Temporary fudge with SequenceListener.getVamsasSource()
874 if (listener instanceof StructureListener)
876 highlightStructure((StructureListener) listener, seq, seqPos);
880 if (listener instanceof SequenceListener)
882 final SequenceListener seqListener = (SequenceListener) listener;
883 if (hasSequenceListeners
884 && seqListener.getVamsasSource() != source)
886 if (relaySeqMappings)
890 results = MappingUtils.buildSearchResults(seq, seqPos,
893 if (handlingVamsasMo)
895 results.addResult(seq, seqPos, seqPos);
898 if (!results.isEmpty())
900 seqListener.highlightSequence(results);
905 else if (listener instanceof VamsasListener && !handlingVamsasMo)
907 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
910 else if (listener instanceof SecondaryStructureListener)
912 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
920 * Send suitable messages to a StructureListener to highlight atoms
921 * corresponding to the given sequence position(s)
927 public void highlightStructure(StructureListener sl, SequenceI seq,
930 if (!sl.isListeningFor(seq))
935 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
936 for (StructureMapping sm : mappings)
938 if (sm.sequence == seq
939 || sm.sequence == seq.getDatasetSequence()
940 || (sm.sequence.getDatasetSequence() != null && sm.sequence
941 .getDatasetSequence() == seq.getDatasetSequence()))
943 for (int index : positions)
945 atomNo = sm.getAtomNum(index);
949 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
950 .getPDBResNum(index), atomNo));
955 sl.highlightAtoms(atoms);
959 * true if a mouse over event from an external (ie Vamsas) source is being
962 boolean handlingVamsasMo = false;
967 * as mouseOverSequence but only route event to SequenceListeners
971 * in an alignment sequence
973 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
976 handlingVamsasMo = true;
977 long msg = sequenceI.hashCode() * (1 + position);
981 mouseOverSequence(sequenceI, position, -1, source);
983 handlingVamsasMo = false;
986 public Annotation[] colourSequenceFromStructure(SequenceI seq,
990 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
991 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
993 * Annotation [] annotations = new Annotation[seq.getLength()];
995 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
996 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
997 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
999 * for (int j = 0; j < mappings.length; j++) {
1001 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
1002 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
1003 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
1004 * "+mappings[j].pdbfile);
1006 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
1007 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
1009 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
1010 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
1011 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
1012 * mappings[j].pdbfile); }
1014 * annotations[index] = new Annotation("X",null,' ',0,col); } return
1015 * annotations; } } } }
1017 * return annotations;
1021 public void structureSelectionChanged()
1025 public void sequenceSelectionChanged()
1029 public void sequenceColoursChanged(Object source)
1031 StructureListener sl;
1032 for (int i = 0; i < listeners.size(); i++)
1034 if (listeners.elementAt(i) instanceof StructureListener)
1036 sl = (StructureListener) listeners.elementAt(i);
1037 sl.updateColours(source);
1042 public StructureMapping[] getMapping(String pdbfile)
1044 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1045 for (StructureMapping sm : mappings)
1047 if (sm.pdbfile.equals(pdbfile))
1052 return tmp.toArray(new StructureMapping[tmp.size()]);
1056 * Returns a readable description of all mappings for the given pdbfile to any
1057 * of the given sequences
1063 public String printMappings(String pdbfile, List<SequenceI> seqs)
1065 if (pdbfile == null || seqs == null || seqs.isEmpty())
1070 StringBuilder sb = new StringBuilder(64);
1071 for (StructureMapping sm : mappings)
1073 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1075 sb.append(sm.mappingDetails);
1077 // separator makes it easier to read multiple mappings
1078 sb.append("=====================");
1084 return sb.toString();
1088 * Remove the given mapping
1092 public void deregisterMapping(AlignedCodonFrame acf)
1096 boolean removed = seqmappings.remove(acf);
1097 if (removed && seqmappings.isEmpty())
1099 System.out.println("All mappings removed");
1105 * Add each of the given codonFrames to the stored set, if not aready present.
1109 public void registerMappings(List<AlignedCodonFrame> mappings)
1111 if (mappings != null)
1113 for (AlignedCodonFrame acf : mappings)
1115 registerMapping(acf);
1121 * Add the given mapping to the stored set, unless already stored.
1123 public void registerMapping(AlignedCodonFrame acf)
1127 if (!seqmappings.contains(acf))
1129 seqmappings.add(acf);
1135 * Resets this object to its initial state by removing all registered
1136 * listeners, codon mappings, PDB file mappings
1138 public void resetAll()
1140 if (mappings != null)
1144 if (seqmappings != null)
1146 seqmappings.clear();
1148 if (sel_listeners != null)
1150 sel_listeners.clear();
1152 if (listeners != null)
1156 if (commandListeners != null)
1158 commandListeners.clear();
1160 if (view_listeners != null)
1162 view_listeners.clear();
1164 if (pdbFileNameId != null)
1166 pdbFileNameId.clear();
1168 if (pdbIdFileName != null)
1170 pdbIdFileName.clear();
1174 public void addSelectionListener(SelectionListener selecter)
1176 if (!sel_listeners.contains(selecter))
1178 sel_listeners.add(selecter);
1182 public void removeSelectionListener(SelectionListener toremove)
1184 if (sel_listeners.contains(toremove))
1186 sel_listeners.remove(toremove);
1190 public synchronized void sendSelection(
1191 jalview.datamodel.SequenceGroup selection,
1192 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1194 for (SelectionListener slis : sel_listeners)
1198 slis.selection(selection, colsel, source);
1203 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1205 public synchronized void sendViewPosition(
1206 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1207 int startSeq, int endSeq)
1210 if (view_listeners != null && view_listeners.size() > 0)
1212 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1214 while (listeners.hasMoreElements())
1216 AlignmentViewPanelListener slis = listeners.nextElement();
1219 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1227 * release all references associated with this manager provider
1229 * @param jalviewLite
1231 public static void release(StructureSelectionManagerProvider jalviewLite)
1233 // synchronized (instances)
1235 if (instances == null)
1239 StructureSelectionManager mnger = (instances.get(jalviewLite));
1242 instances.remove(jalviewLite);
1246 } catch (Throwable x)
1253 public void registerPDBEntry(PDBEntry pdbentry)
1255 if (pdbentry.getFile() != null
1256 && pdbentry.getFile().trim().length() > 0)
1258 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1262 public void addCommandListener(CommandListener cl)
1264 if (!commandListeners.contains(cl))
1266 commandListeners.add(cl);
1270 public boolean hasCommandListener(CommandListener cl)
1272 return this.commandListeners.contains(cl);
1275 public boolean removeCommandListener(CommandListener l)
1277 return commandListeners.remove(l);
1281 * Forward a command to any command listeners (except for the command's
1285 * the command to be broadcast (in its form after being performed)
1287 * if true, the command was being 'undone'
1290 public void commandPerformed(CommandI command, boolean undo,
1291 VamsasSource source)
1293 for (CommandListener listener : commandListeners)
1295 listener.mirrorCommand(command, undo, this, source);
1300 * Returns a new CommandI representing the given command as mapped to the
1301 * given sequences. If no mapping could be made, or the command is not of a
1302 * mappable kind, returns null.
1310 public CommandI mapCommand(CommandI command, boolean undo,
1311 final AlignmentI mapTo, char gapChar)
1313 if (command instanceof EditCommand)
1315 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1316 mapTo, gapChar, seqmappings);
1318 else if (command instanceof OrderCommand)
1320 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1321 mapTo, seqmappings);
1326 public IProgressIndicator getProgressIndicator()
1328 return progressIndicator;
1331 public void setProgressIndicator(IProgressIndicator progressIndicator)
1333 this.progressIndicator = progressIndicator;
1336 public long getProgressSessionId()
1338 return progressSessionId;
1341 public void setProgressSessionId(long progressSessionId)
1343 this.progressSessionId = progressSessionId;
1346 public void setProgressBar(String message)
1348 if (progressIndicator == null)
1352 progressIndicator.setProgressBar(message, progressSessionId);
1355 public List<AlignedCodonFrame> getSequenceMappings()