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 boolean isParseWithJMOL = StructureImportSettings
389 .getDefaultPDBFileParser().equalsIgnoreCase(
390 StructureImportSettings.StructureParser.JMOL_PARSER
392 if (isParseWithJMOL || (pdbFile != null && isCIFFile(pdbFile)))
394 pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr,
395 secStructServices, pdbFile, protocol);
399 pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
403 if (pdb.getId() != null && pdb.getId().trim().length() > 0
404 && AppletFormatAdapter.FILE.equals(protocol))
406 registerPDBFile(pdb.getId().trim(), pdbFile);
408 } catch (Exception ex)
410 ex.printStackTrace();
418 siftsClient = new SiftsClient(pdb);
420 } catch (SiftsException e)
422 isMapUsingSIFTs = false;
426 String targetChainId;
427 for (int s = 0; s < sequenceArray.length; s++)
429 boolean infChain = true;
430 final SequenceI seq = sequenceArray[s];
432 while (ds.getDatasetSequence() != null)
434 ds = ds.getDatasetSequence();
437 if (targetChainIds != null && targetChainIds[s] != null)
440 targetChainId = targetChainIds[s];
442 else if (seq.getName().indexOf("|") > -1)
444 targetChainId = seq.getName().substring(
445 seq.getName().lastIndexOf("|") + 1);
446 if (targetChainId.length() > 1)
448 if (targetChainId.trim().length() == 0)
454 // not a valid chain identifier
465 * Attempt pairwise alignment of the sequence with each chain in the PDB,
466 * and remember the highest scoring chain
469 AlignSeq maxAlignseq = null;
470 String maxChainId = " ";
471 PDBChain maxChain = null;
472 boolean first = true;
473 for (PDBChain chain : pdb.getChains())
475 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
478 continue; // don't try to map chains don't match.
480 // TODO: correctly determine sequence type for mixed na/peptide
482 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
483 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
486 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
487 // as.calcScoreMatrix();
488 // as.traceAlignment();
490 if (first || as.maxscore > max
491 || (as.maxscore == max && chain.id.equals(targetChainId)))
497 maxChainId = chain.id;
500 if (maxChain == null)
505 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
507 pdbFile = "INLINE" + pdb.getId();
510 ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
511 if (isMapUsingSIFTs && seq.isProtein())
513 setProgressBar(null);
514 setProgressBar(MessageManager
515 .getString("status.obtaining_mapping_with_sifts"));
516 jalview.datamodel.Mapping sqmpping = maxAlignseq
517 .getMappingFromS1(false);
518 if (targetChainId != null && !targetChainId.trim().isEmpty())
520 StructureMapping siftsMapping;
523 siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
524 pdb, maxChain, sqmpping, maxAlignseq);
525 seqToStrucMapping.add(siftsMapping);
526 maxChain.makeExactMapping(maxAlignseq, seq);
527 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
529 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
530 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
532 } catch (SiftsException e)
534 // fall back to NW alignment
535 System.err.println(e.getMessage());
536 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
537 targetChainId, maxChain, pdb, maxAlignseq);
538 seqToStrucMapping.add(nwMapping);
539 maxChain.makeExactMapping(maxAlignseq, seq);
540 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
542 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
543 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
548 ArrayList<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
549 for (PDBChain chain : pdb.getChains())
553 StructureMapping siftsMapping = getStructureMapping(seq,
555 chain.id, pdb, chain, sqmpping, maxAlignseq);
556 foundSiftsMappings.add(siftsMapping);
557 } catch (SiftsException e)
559 System.err.println(e.getMessage());
562 if (!foundSiftsMappings.isEmpty())
564 seqToStrucMapping.addAll(foundSiftsMappings);
565 maxChain.makeExactMapping(maxAlignseq, seq);
566 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
568 maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
570 ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0));
574 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
575 maxChainId, maxChain, pdb, maxAlignseq);
576 seqToStrucMapping.add(nwMapping);
577 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
579 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
580 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
586 setProgressBar(null);
587 setProgressBar(MessageManager
588 .getString("status.obtaining_mapping_with_nw_alignment"));
589 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
590 maxChainId, maxChain, pdb, maxAlignseq);
591 seqToStrucMapping.add(nwMapping);
592 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
596 if (forStructureView)
598 mappings.addAll(seqToStrucMapping);
604 private boolean isCIFFile(String filename)
606 String fileExt = filename.substring(filename.lastIndexOf(".") + 1,
608 return "cif".equalsIgnoreCase(fileExt);
612 * retrieve a mapping for seq from SIFTs using associated DBRefEntry for
617 * @param targetChainId
623 * @throws SiftsException
625 private StructureMapping getStructureMapping(SequenceI seq,
626 String pdbFile, String targetChainId, StructureFile pdb,
627 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
628 AlignSeq maxAlignseq) throws SiftsException
630 StructureMapping curChainMapping = siftsClient
631 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
634 PDBChain chain = pdb.findChain(targetChainId);
637 chain.transferResidueAnnotation(curChainMapping, sqmpping);
639 } catch (Exception e)
643 return curChainMapping;
646 private StructureMapping getNWMappings(SequenceI seq,
648 String maxChainId, PDBChain maxChain, StructureFile pdb,
649 AlignSeq maxAlignseq)
651 final StringBuilder mappingDetails = new StringBuilder(128);
652 mappingDetails.append(NEWLINE).append(
653 "Sequence \u27f7 Structure mapping details");
654 mappingDetails.append(NEWLINE);
656 .append("Method: inferred with Needleman & Wunsch alignment");
657 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
658 .append(NEWLINE).append("Sequence = ")
659 .append(maxChain.sequence.getSequenceAsString());
660 mappingDetails.append(NEWLINE).append("No of residues = ")
661 .append(maxChain.residues.size()).append(NEWLINE)
663 PrintStream ps = new PrintStream(System.out)
666 public void print(String x)
668 mappingDetails.append(x);
672 public void println()
674 mappingDetails.append(NEWLINE);
678 maxAlignseq.printAlignment(ps);
680 mappingDetails.append(NEWLINE).append("PDB start/end ");
681 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
683 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
684 mappingDetails.append(NEWLINE).append("SEQ start/end ");
685 mappingDetails.append(
686 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
688 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
689 + (seq.getStart() - 1)));
690 mappingDetails.append(NEWLINE);
691 maxChain.makeExactMapping(maxAlignseq, seq);
692 jalview.datamodel.Mapping sqmpping = maxAlignseq
693 .getMappingFromS1(false);
694 maxChain.transferRESNUMFeatures(seq, null);
696 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
703 Atom tmp = maxChain.atoms.elementAt(index);
704 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
705 && tmp.alignmentMapping != -1)
707 resNum = tmp.resNumber;
708 insCode = tmp.insCode;
709 if (tmp.alignmentMapping >= -1)
711 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
717 } while (index < maxChain.atoms.size());
719 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
720 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
721 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
725 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
727 listeners.removeElement(svl);
728 if (svl instanceof SequenceListener)
730 for (int i = 0; i < listeners.size(); i++)
732 if (listeners.elementAt(i) instanceof StructureListener)
734 ((StructureListener) listeners.elementAt(i))
735 .releaseReferences(svl);
740 if (pdbfiles == null)
746 * Remove mappings to the closed listener's PDB files, but first check if
747 * another listener is still interested
749 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
751 StructureListener sl;
752 for (int i = 0; i < listeners.size(); i++)
754 if (listeners.elementAt(i) instanceof StructureListener)
756 sl = (StructureListener) listeners.elementAt(i);
757 for (String pdbfile : sl.getPdbFile())
759 pdbs.remove(pdbfile);
765 * Rebuild the mappings set, retaining only those which are for 'other' PDB
770 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
771 for (StructureMapping sm : mappings)
773 if (!pdbs.contains(sm.pdbfile))
784 * Propagate mouseover of a single position in a structure
790 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
792 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
793 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
794 mouseOverStructure(atoms);
798 * Propagate mouseover or selection of multiple positions in a structure
802 public void mouseOverStructure(List<AtomSpec> atoms)
804 if (listeners == null)
806 // old or prematurely sent event
809 boolean hasSequenceListener = false;
810 for (int i = 0; i < listeners.size(); i++)
812 if (listeners.elementAt(i) instanceof SequenceListener)
814 hasSequenceListener = true;
817 if (!hasSequenceListener)
822 SearchResults results = new SearchResults();
823 for (AtomSpec atom : atoms)
825 SequenceI lastseq = null;
827 for (StructureMapping sm : mappings)
829 if (sm.pdbfile.equals(atom.getPdbFile())
830 && sm.pdbchain.equals(atom.getChain()))
832 int indexpos = sm.getSeqPos(atom.getPdbResNum());
833 if (lastipos != indexpos && lastseq != sm.sequence)
835 results.addResult(sm.sequence, indexpos, indexpos);
837 lastseq = sm.sequence;
838 // construct highlighted sequence list
839 for (AlignedCodonFrame acf : seqmappings)
841 acf.markMappedRegion(sm.sequence, indexpos, results);
847 for (Object li : listeners)
849 if (li instanceof SequenceListener)
851 ((SequenceListener) li).highlightSequence(results);
857 * highlight regions associated with a position (indexpos) in seq
860 * the sequence that the mouse over occurred on
862 * the absolute position being mouseovered in seq (0 to seq.length())
864 * the sequence position (if -1, seq.findPosition is called to
865 * resolve the residue number)
867 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
870 boolean hasSequenceListeners = handlingVamsasMo
871 || !seqmappings.isEmpty();
872 SearchResults results = null;
875 seqPos = seq.findPosition(indexpos);
877 for (int i = 0; i < listeners.size(); i++)
879 Object listener = listeners.elementAt(i);
880 if (listener == source)
882 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
883 // Temporary fudge with SequenceListener.getVamsasSource()
886 if (listener instanceof StructureListener)
888 highlightStructure((StructureListener) listener, seq, seqPos);
892 if (listener instanceof SequenceListener)
894 final SequenceListener seqListener = (SequenceListener) listener;
895 if (hasSequenceListeners
896 && seqListener.getVamsasSource() != source)
898 if (relaySeqMappings)
902 results = MappingUtils.buildSearchResults(seq, seqPos,
905 if (handlingVamsasMo)
907 results.addResult(seq, seqPos, seqPos);
910 if (!results.isEmpty())
912 seqListener.highlightSequence(results);
917 else if (listener instanceof VamsasListener && !handlingVamsasMo)
919 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
922 else if (listener instanceof SecondaryStructureListener)
924 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
932 * Send suitable messages to a StructureListener to highlight atoms
933 * corresponding to the given sequence position(s)
939 public void highlightStructure(StructureListener sl, SequenceI seq,
942 if (!sl.isListeningFor(seq))
947 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
948 for (StructureMapping sm : mappings)
950 if (sm.sequence == seq
951 || sm.sequence == seq.getDatasetSequence()
952 || (sm.sequence.getDatasetSequence() != null && sm.sequence
953 .getDatasetSequence() == seq.getDatasetSequence()))
955 for (int index : positions)
957 atomNo = sm.getAtomNum(index);
961 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
962 .getPDBResNum(index), atomNo));
967 sl.highlightAtoms(atoms);
971 * true if a mouse over event from an external (ie Vamsas) source is being
974 boolean handlingVamsasMo = false;
979 * as mouseOverSequence but only route event to SequenceListeners
983 * in an alignment sequence
985 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
988 handlingVamsasMo = true;
989 long msg = sequenceI.hashCode() * (1 + position);
993 mouseOverSequence(sequenceI, position, -1, source);
995 handlingVamsasMo = false;
998 public Annotation[] colourSequenceFromStructure(SequenceI seq,
1002 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
1003 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
1005 * Annotation [] annotations = new Annotation[seq.getLength()];
1007 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
1008 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
1009 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
1011 * for (int j = 0; j < mappings.length; j++) {
1013 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
1014 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
1015 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
1016 * "+mappings[j].pdbfile);
1018 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
1019 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
1021 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
1022 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
1023 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
1024 * mappings[j].pdbfile); }
1026 * annotations[index] = new Annotation("X",null,' ',0,col); } return
1027 * annotations; } } } }
1029 * return annotations;
1033 public void structureSelectionChanged()
1037 public void sequenceSelectionChanged()
1041 public void sequenceColoursChanged(Object source)
1043 StructureListener sl;
1044 for (int i = 0; i < listeners.size(); i++)
1046 if (listeners.elementAt(i) instanceof StructureListener)
1048 sl = (StructureListener) listeners.elementAt(i);
1049 sl.updateColours(source);
1054 public StructureMapping[] getMapping(String pdbfile)
1056 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1057 for (StructureMapping sm : mappings)
1059 if (sm.pdbfile.equals(pdbfile))
1064 return tmp.toArray(new StructureMapping[tmp.size()]);
1068 * Returns a readable description of all mappings for the given pdbfile to any
1069 * of the given sequences
1075 public String printMappings(String pdbfile, List<SequenceI> seqs)
1077 if (pdbfile == null || seqs == null || seqs.isEmpty())
1082 StringBuilder sb = new StringBuilder(64);
1083 for (StructureMapping sm : mappings)
1085 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1087 sb.append(sm.mappingDetails);
1089 // separator makes it easier to read multiple mappings
1090 sb.append("=====================");
1096 return sb.toString();
1100 * Remove the given mapping
1104 public void deregisterMapping(AlignedCodonFrame acf)
1108 boolean removed = seqmappings.remove(acf);
1109 if (removed && seqmappings.isEmpty())
1111 System.out.println("All mappings removed");
1117 * Add each of the given codonFrames to the stored set, if not aready present.
1121 public void registerMappings(List<AlignedCodonFrame> mappings)
1123 if (mappings != null)
1125 for (AlignedCodonFrame acf : mappings)
1127 registerMapping(acf);
1133 * Add the given mapping to the stored set, unless already stored.
1135 public void registerMapping(AlignedCodonFrame acf)
1139 if (!seqmappings.contains(acf))
1141 seqmappings.add(acf);
1147 * Resets this object to its initial state by removing all registered
1148 * listeners, codon mappings, PDB file mappings
1150 public void resetAll()
1152 if (mappings != null)
1156 if (seqmappings != null)
1158 seqmappings.clear();
1160 if (sel_listeners != null)
1162 sel_listeners.clear();
1164 if (listeners != null)
1168 if (commandListeners != null)
1170 commandListeners.clear();
1172 if (view_listeners != null)
1174 view_listeners.clear();
1176 if (pdbFileNameId != null)
1178 pdbFileNameId.clear();
1180 if (pdbIdFileName != null)
1182 pdbIdFileName.clear();
1186 public void addSelectionListener(SelectionListener selecter)
1188 if (!sel_listeners.contains(selecter))
1190 sel_listeners.add(selecter);
1194 public void removeSelectionListener(SelectionListener toremove)
1196 if (sel_listeners.contains(toremove))
1198 sel_listeners.remove(toremove);
1202 public synchronized void sendSelection(
1203 jalview.datamodel.SequenceGroup selection,
1204 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1206 for (SelectionListener slis : sel_listeners)
1210 slis.selection(selection, colsel, source);
1215 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1217 public synchronized void sendViewPosition(
1218 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1219 int startSeq, int endSeq)
1222 if (view_listeners != null && view_listeners.size() > 0)
1224 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1226 while (listeners.hasMoreElements())
1228 AlignmentViewPanelListener slis = listeners.nextElement();
1231 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1239 * release all references associated with this manager provider
1241 * @param jalviewLite
1243 public static void release(StructureSelectionManagerProvider jalviewLite)
1245 // synchronized (instances)
1247 if (instances == null)
1251 StructureSelectionManager mnger = (instances.get(jalviewLite));
1254 instances.remove(jalviewLite);
1258 } catch (Throwable x)
1265 public void registerPDBEntry(PDBEntry pdbentry)
1267 if (pdbentry.getFile() != null
1268 && pdbentry.getFile().trim().length() > 0)
1270 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1274 public void addCommandListener(CommandListener cl)
1276 if (!commandListeners.contains(cl))
1278 commandListeners.add(cl);
1282 public boolean hasCommandListener(CommandListener cl)
1284 return this.commandListeners.contains(cl);
1287 public boolean removeCommandListener(CommandListener l)
1289 return commandListeners.remove(l);
1293 * Forward a command to any command listeners (except for the command's
1297 * the command to be broadcast (in its form after being performed)
1299 * if true, the command was being 'undone'
1302 public void commandPerformed(CommandI command, boolean undo,
1303 VamsasSource source)
1305 for (CommandListener listener : commandListeners)
1307 listener.mirrorCommand(command, undo, this, source);
1312 * Returns a new CommandI representing the given command as mapped to the
1313 * given sequences. If no mapping could be made, or the command is not of a
1314 * mappable kind, returns null.
1322 public CommandI mapCommand(CommandI command, boolean undo,
1323 final AlignmentI mapTo, char gapChar)
1325 if (command instanceof EditCommand)
1327 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1328 mapTo, gapChar, seqmappings);
1330 else if (command instanceof OrderCommand)
1332 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1333 mapTo, seqmappings);
1338 public IProgressIndicator getProgressIndicator()
1340 return progressIndicator;
1343 public void setProgressIndicator(IProgressIndicator progressIndicator)
1345 this.progressIndicator = progressIndicator;
1348 public long getProgressSessionId()
1350 return progressSessionId;
1353 public void setProgressSessionId(long progressSessionId)
1355 this.progressSessionId = progressSessionId;
1358 public void setProgressBar(String message)
1360 if (progressIndicator == null)
1364 progressIndicator.setProgressBar(message, progressSessionId);
1367 public List<AlignedCodonFrame> getSequenceMappings()