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 } catch (Exception ex)
395 ex.printStackTrace();
403 siftsClient = new SiftsClient(pdb);
405 } catch (SiftsException e)
407 isMapUsingSIFTs = false;
411 String targetChainId;
412 for (int s = 0; s < sequenceArray.length; s++)
414 boolean infChain = true;
415 final SequenceI seq = sequenceArray[s];
417 while (ds.getDatasetSequence() != null)
419 ds = ds.getDatasetSequence();
422 if (targetChainIds != null && targetChainIds[s] != null)
425 targetChainId = targetChainIds[s];
427 else if (seq.getName().indexOf("|") > -1)
429 targetChainId = seq.getName().substring(
430 seq.getName().lastIndexOf("|") + 1);
431 if (targetChainId.length() > 1)
433 if (targetChainId.trim().length() == 0)
439 // not a valid chain identifier
450 * Attempt pairwise alignment of the sequence with each chain in the PDB,
451 * and remember the highest scoring chain
454 AlignSeq maxAlignseq = null;
455 String maxChainId = " ";
456 PDBChain maxChain = null;
457 boolean first = true;
458 for (PDBChain chain : pdb.getChains())
460 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
463 continue; // don't try to map chains don't match.
465 // TODO: correctly determine sequence type for mixed na/peptide
467 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
468 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
471 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
472 // as.calcScoreMatrix();
473 // as.traceAlignment();
475 if (first || as.maxscore > max
476 || (as.maxscore == max && chain.id.equals(targetChainId)))
482 maxChainId = chain.id;
485 if (maxChain == null)
490 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
492 pdbFile = "INLINE" + pdb.getId();
495 ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
496 if (isMapUsingSIFTs && seq.isProtein())
498 setProgressBar(null);
499 setProgressBar(MessageManager
500 .getString("status.obtaining_mapping_with_sifts"));
501 jalview.datamodel.Mapping sqmpping = maxAlignseq
502 .getMappingFromS1(false);
503 if (targetChainId != null && !targetChainId.trim().isEmpty())
505 StructureMapping siftsMapping;
508 siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
509 pdb, maxChain, sqmpping, maxAlignseq);
510 seqToStrucMapping.add(siftsMapping);
511 maxChain.makeExactMapping(maxAlignseq, seq);
512 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
514 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
515 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
517 } catch (SiftsException e)
519 // fall back to NW alignment
520 System.err.println(e.getMessage());
521 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
522 targetChainId, maxChain, pdb, maxAlignseq);
523 seqToStrucMapping.add(nwMapping);
524 maxChain.makeExactMapping(maxAlignseq, seq);
525 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
527 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
528 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
533 ArrayList<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
534 for (PDBChain chain : pdb.getChains())
538 StructureMapping siftsMapping = getStructureMapping(seq,
539 pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
540 foundSiftsMappings.add(siftsMapping);
541 } catch (SiftsException e)
543 System.err.println(e.getMessage());
546 if (!foundSiftsMappings.isEmpty())
548 seqToStrucMapping.addAll(foundSiftsMappings);
549 maxChain.makeExactMapping(maxAlignseq, seq);
550 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
552 maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
554 ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0));
558 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
559 maxChainId, maxChain, pdb, maxAlignseq);
560 seqToStrucMapping.add(nwMapping);
561 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
563 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
564 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
570 setProgressBar(null);
571 setProgressBar(MessageManager
572 .getString("status.obtaining_mapping_with_nw_alignment"));
573 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
574 maxChainId, maxChain, pdb, maxAlignseq);
575 seqToStrucMapping.add(nwMapping);
576 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
580 if (forStructureView)
582 mappings.addAll(seqToStrucMapping);
588 private boolean isCIFFile(String filename)
590 String fileExt = filename.substring(filename.lastIndexOf(".") + 1,
592 return "cif".equalsIgnoreCase(fileExt);
596 * retrieve a mapping for seq from SIFTs using associated DBRefEntry for
601 * @param targetChainId
607 * @throws SiftsException
609 private StructureMapping getStructureMapping(SequenceI seq,
610 String pdbFile, String targetChainId, StructureFile pdb,
611 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
612 AlignSeq maxAlignseq) throws SiftsException
614 StructureMapping curChainMapping = siftsClient
615 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
618 PDBChain chain = pdb.findChain(targetChainId);
621 chain.transferResidueAnnotation(curChainMapping, sqmpping);
623 } catch (Exception e)
627 return curChainMapping;
630 private StructureMapping getNWMappings(SequenceI seq, String pdbFile,
631 String maxChainId, PDBChain maxChain, StructureFile pdb,
632 AlignSeq maxAlignseq)
634 final StringBuilder mappingDetails = new StringBuilder(128);
635 mappingDetails.append(NEWLINE).append(
636 "Sequence \u27f7 Structure mapping details");
637 mappingDetails.append(NEWLINE);
639 .append("Method: inferred with Needleman & Wunsch alignment");
640 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
641 .append(NEWLINE).append("Sequence = ")
642 .append(maxChain.sequence.getSequenceAsString());
643 mappingDetails.append(NEWLINE).append("No of residues = ")
644 .append(maxChain.residues.size()).append(NEWLINE)
646 PrintStream ps = new PrintStream(System.out)
649 public void print(String x)
651 mappingDetails.append(x);
655 public void println()
657 mappingDetails.append(NEWLINE);
661 maxAlignseq.printAlignment(ps);
663 mappingDetails.append(NEWLINE).append("PDB start/end ");
664 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
666 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
667 mappingDetails.append(NEWLINE).append("SEQ start/end ");
668 mappingDetails.append(
669 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
671 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
672 + (seq.getStart() - 1)));
673 mappingDetails.append(NEWLINE);
674 maxChain.makeExactMapping(maxAlignseq, seq);
675 jalview.datamodel.Mapping sqmpping = maxAlignseq
676 .getMappingFromS1(false);
677 maxChain.transferRESNUMFeatures(seq, null);
679 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
686 Atom tmp = maxChain.atoms.elementAt(index);
687 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
688 && tmp.alignmentMapping != -1)
690 resNum = tmp.resNumber;
691 insCode = tmp.insCode;
692 if (tmp.alignmentMapping >= -1)
694 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
700 } while (index < maxChain.atoms.size());
702 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
703 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
704 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
708 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
710 listeners.removeElement(svl);
711 if (svl instanceof SequenceListener)
713 for (int i = 0; i < listeners.size(); i++)
715 if (listeners.elementAt(i) instanceof StructureListener)
717 ((StructureListener) listeners.elementAt(i))
718 .releaseReferences(svl);
723 if (pdbfiles == null)
729 * Remove mappings to the closed listener's PDB files, but first check if
730 * another listener is still interested
732 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
734 StructureListener sl;
735 for (int i = 0; i < listeners.size(); i++)
737 if (listeners.elementAt(i) instanceof StructureListener)
739 sl = (StructureListener) listeners.elementAt(i);
740 for (String pdbfile : sl.getPdbFile())
742 pdbs.remove(pdbfile);
748 * Rebuild the mappings set, retaining only those which are for 'other' PDB
753 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
754 for (StructureMapping sm : mappings)
756 if (!pdbs.contains(sm.pdbfile))
767 * Propagate mouseover of a single position in a structure
773 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
775 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
776 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
777 mouseOverStructure(atoms);
781 * Propagate mouseover or selection of multiple positions in a structure
785 public void mouseOverStructure(List<AtomSpec> atoms)
787 if (listeners == null)
789 // old or prematurely sent event
792 boolean hasSequenceListener = false;
793 for (int i = 0; i < listeners.size(); i++)
795 if (listeners.elementAt(i) instanceof SequenceListener)
797 hasSequenceListener = true;
800 if (!hasSequenceListener)
805 SearchResults results = new SearchResults();
806 for (AtomSpec atom : atoms)
808 SequenceI lastseq = null;
810 for (StructureMapping sm : mappings)
812 if (sm.pdbfile.equals(atom.getPdbFile())
813 && sm.pdbchain.equals(atom.getChain()))
815 int indexpos = sm.getSeqPos(atom.getPdbResNum());
816 if (lastipos != indexpos && lastseq != sm.sequence)
818 results.addResult(sm.sequence, indexpos, indexpos);
820 lastseq = sm.sequence;
821 // construct highlighted sequence list
822 for (AlignedCodonFrame acf : seqmappings)
824 acf.markMappedRegion(sm.sequence, indexpos, results);
830 for (Object li : listeners)
832 if (li instanceof SequenceListener)
834 ((SequenceListener) li).highlightSequence(results);
840 * highlight regions associated with a position (indexpos) in seq
843 * the sequence that the mouse over occurred on
845 * the absolute position being mouseovered in seq (0 to seq.length())
847 * the sequence position (if -1, seq.findPosition is called to
848 * resolve the residue number)
850 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
853 boolean hasSequenceListeners = handlingVamsasMo
854 || !seqmappings.isEmpty();
855 SearchResults results = null;
858 seqPos = seq.findPosition(indexpos);
860 for (int i = 0; i < listeners.size(); i++)
862 Object listener = listeners.elementAt(i);
863 if (listener == source)
865 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
866 // Temporary fudge with SequenceListener.getVamsasSource()
869 if (listener instanceof StructureListener)
871 highlightStructure((StructureListener) listener, seq, seqPos);
875 if (listener instanceof SequenceListener)
877 final SequenceListener seqListener = (SequenceListener) listener;
878 if (hasSequenceListeners
879 && seqListener.getVamsasSource() != source)
881 if (relaySeqMappings)
885 results = MappingUtils.buildSearchResults(seq, seqPos,
888 if (handlingVamsasMo)
890 results.addResult(seq, seqPos, seqPos);
893 if (!results.isEmpty())
895 seqListener.highlightSequence(results);
900 else if (listener instanceof VamsasListener && !handlingVamsasMo)
902 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
905 else if (listener instanceof SecondaryStructureListener)
907 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
915 * Send suitable messages to a StructureListener to highlight atoms
916 * corresponding to the given sequence position(s)
922 public void highlightStructure(StructureListener sl, SequenceI seq,
925 if (!sl.isListeningFor(seq))
930 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
931 for (StructureMapping sm : mappings)
933 if (sm.sequence == seq
934 || sm.sequence == seq.getDatasetSequence()
935 || (sm.sequence.getDatasetSequence() != null && sm.sequence
936 .getDatasetSequence() == seq.getDatasetSequence()))
938 for (int index : positions)
940 atomNo = sm.getAtomNum(index);
944 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
945 .getPDBResNum(index), atomNo));
950 sl.highlightAtoms(atoms);
954 * true if a mouse over event from an external (ie Vamsas) source is being
957 boolean handlingVamsasMo = false;
962 * as mouseOverSequence but only route event to SequenceListeners
966 * in an alignment sequence
968 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
971 handlingVamsasMo = true;
972 long msg = sequenceI.hashCode() * (1 + position);
976 mouseOverSequence(sequenceI, position, -1, source);
978 handlingVamsasMo = false;
981 public Annotation[] colourSequenceFromStructure(SequenceI seq,
985 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
986 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
988 * Annotation [] annotations = new Annotation[seq.getLength()];
990 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
991 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
992 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
994 * for (int j = 0; j < mappings.length; j++) {
996 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
997 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
998 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
999 * "+mappings[j].pdbfile);
1001 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
1002 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
1004 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
1005 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
1006 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
1007 * mappings[j].pdbfile); }
1009 * annotations[index] = new Annotation("X",null,' ',0,col); } return
1010 * annotations; } } } }
1012 * return annotations;
1016 public void structureSelectionChanged()
1020 public void sequenceSelectionChanged()
1024 public void sequenceColoursChanged(Object source)
1026 StructureListener sl;
1027 for (int i = 0; i < listeners.size(); i++)
1029 if (listeners.elementAt(i) instanceof StructureListener)
1031 sl = (StructureListener) listeners.elementAt(i);
1032 sl.updateColours(source);
1037 public StructureMapping[] getMapping(String pdbfile)
1039 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1040 for (StructureMapping sm : mappings)
1042 if (sm.pdbfile.equals(pdbfile))
1047 return tmp.toArray(new StructureMapping[tmp.size()]);
1051 * Returns a readable description of all mappings for the given pdbfile to any
1052 * of the given sequences
1058 public String printMappings(String pdbfile, List<SequenceI> seqs)
1060 if (pdbfile == null || seqs == null || seqs.isEmpty())
1065 StringBuilder sb = new StringBuilder(64);
1066 for (StructureMapping sm : mappings)
1068 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1070 sb.append(sm.mappingDetails);
1072 // separator makes it easier to read multiple mappings
1073 sb.append("=====================");
1079 return sb.toString();
1083 * Remove the given mapping
1087 public void deregisterMapping(AlignedCodonFrame acf)
1091 boolean removed = seqmappings.remove(acf);
1092 if (removed && seqmappings.isEmpty())
1094 System.out.println("All mappings removed");
1100 * Add each of the given codonFrames to the stored set, if not aready present.
1104 public void registerMappings(List<AlignedCodonFrame> mappings)
1106 if (mappings != null)
1108 for (AlignedCodonFrame acf : mappings)
1110 registerMapping(acf);
1116 * Add the given mapping to the stored set, unless already stored.
1118 public void registerMapping(AlignedCodonFrame acf)
1122 if (!seqmappings.contains(acf))
1124 seqmappings.add(acf);
1130 * Resets this object to its initial state by removing all registered
1131 * listeners, codon mappings, PDB file mappings
1133 public void resetAll()
1135 if (mappings != null)
1139 if (seqmappings != null)
1141 seqmappings.clear();
1143 if (sel_listeners != null)
1145 sel_listeners.clear();
1147 if (listeners != null)
1151 if (commandListeners != null)
1153 commandListeners.clear();
1155 if (view_listeners != null)
1157 view_listeners.clear();
1159 if (pdbFileNameId != null)
1161 pdbFileNameId.clear();
1163 if (pdbIdFileName != null)
1165 pdbIdFileName.clear();
1169 public void addSelectionListener(SelectionListener selecter)
1171 if (!sel_listeners.contains(selecter))
1173 sel_listeners.add(selecter);
1177 public void removeSelectionListener(SelectionListener toremove)
1179 if (sel_listeners.contains(toremove))
1181 sel_listeners.remove(toremove);
1185 public synchronized void sendSelection(
1186 jalview.datamodel.SequenceGroup selection,
1187 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1189 for (SelectionListener slis : sel_listeners)
1193 slis.selection(selection, colsel, source);
1198 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1200 public synchronized void sendViewPosition(
1201 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1202 int startSeq, int endSeq)
1205 if (view_listeners != null && view_listeners.size() > 0)
1207 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1209 while (listeners.hasMoreElements())
1211 AlignmentViewPanelListener slis = listeners.nextElement();
1214 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1222 * release all references associated with this manager provider
1224 * @param jalviewLite
1226 public static void release(StructureSelectionManagerProvider jalviewLite)
1228 // synchronized (instances)
1230 if (instances == null)
1234 StructureSelectionManager mnger = (instances.get(jalviewLite));
1237 instances.remove(jalviewLite);
1241 } catch (Throwable x)
1248 public void registerPDBEntry(PDBEntry pdbentry)
1250 if (pdbentry.getFile() != null
1251 && pdbentry.getFile().trim().length() > 0)
1253 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1257 public void addCommandListener(CommandListener cl)
1259 if (!commandListeners.contains(cl))
1261 commandListeners.add(cl);
1265 public boolean hasCommandListener(CommandListener cl)
1267 return this.commandListeners.contains(cl);
1270 public boolean removeCommandListener(CommandListener l)
1272 return commandListeners.remove(l);
1276 * Forward a command to any command listeners (except for the command's
1280 * the command to be broadcast (in its form after being performed)
1282 * if true, the command was being 'undone'
1285 public void commandPerformed(CommandI command, boolean undo,
1286 VamsasSource source)
1288 for (CommandListener listener : commandListeners)
1290 listener.mirrorCommand(command, undo, this, source);
1295 * Returns a new CommandI representing the given command as mapped to the
1296 * given sequences. If no mapping could be made, or the command is not of a
1297 * mappable kind, returns null.
1305 public CommandI mapCommand(CommandI command, boolean undo,
1306 final AlignmentI mapTo, char gapChar)
1308 if (command instanceof EditCommand)
1310 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1311 mapTo, gapChar, seqmappings);
1313 else if (command instanceof OrderCommand)
1315 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1316 mapTo, seqmappings);
1321 public IProgressIndicator getProgressIndicator()
1323 return progressIndicator;
1326 public void setProgressIndicator(IProgressIndicator progressIndicator)
1328 this.progressIndicator = progressIndicator;
1331 public long getProgressSessionId()
1333 return progressSessionId;
1336 public void setProgressSessionId(long progressSessionId)
1338 this.progressSessionId = progressSessionId;
1341 public void setProgressBar(String message)
1343 if (progressIndicator == null)
1347 progressIndicator.setProgressBar(message, progressSessionId);
1350 public List<AlignedCodonFrame> getSequenceMappings()