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.SearchResultsI;
35 import jalview.datamodel.SequenceI;
36 import jalview.ext.jmol.JmolParser;
37 import jalview.gui.IProgressIndicator;
38 import jalview.io.DataSourceType;
39 import jalview.io.StructureFile;
40 import jalview.util.MappingUtils;
41 import jalview.util.MessageManager;
42 import jalview.ws.sifts.SiftsClient;
43 import jalview.ws.sifts.SiftsException;
44 import jalview.ws.sifts.SiftsSettings;
46 import java.io.PrintStream;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collections;
50 import java.util.Enumeration;
51 import java.util.HashMap;
52 import java.util.IdentityHashMap;
53 import java.util.List;
55 import java.util.Vector;
58 import MCview.PDBChain;
59 import MCview.PDBfile;
61 public class StructureSelectionManager
63 public final static String NEWLINE = System.lineSeparator();
65 static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
67 private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
69 private boolean processSecondaryStructure = false;
71 private boolean secStructServices = false;
73 private boolean addTempFacAnnot = false;
75 private IProgressIndicator progressIndicator;
77 private SiftsClient siftsClient = null;
79 private long progressSessionId;
82 * Set of any registered mappings between (dataset) sequences.
84 private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
86 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
88 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
91 * @return true if will try to use external services for processing secondary
94 public boolean isSecStructServices()
96 return secStructServices;
100 * control use of external services for processing secondary structure
102 * @param secStructServices
104 public void setSecStructServices(boolean secStructServices)
106 this.secStructServices = secStructServices;
110 * flag controlling addition of any kind of structural annotation
112 * @return true if temperature factor annotation will be added
114 public boolean isAddTempFacAnnot()
116 return addTempFacAnnot;
120 * set flag controlling addition of structural annotation
122 * @param addTempFacAnnot
124 public void setAddTempFacAnnot(boolean addTempFacAnnot)
126 this.addTempFacAnnot = addTempFacAnnot;
131 * @return if true, the structure manager will attempt to add secondary
132 * structure lines for unannotated sequences
135 public boolean isProcessSecondaryStructure()
137 return processSecondaryStructure;
141 * Control whether structure manager will try to annotate mapped sequences
142 * with secondary structure from PDB data.
146 public void setProcessSecondaryStructure(boolean enable)
148 processSecondaryStructure = enable;
152 * debug function - write all mappings to stdout
154 public void reportMapping()
156 if (mappings.isEmpty())
158 System.err.println("reportMapping: No PDB/Sequence mappings.");
162 System.err.println("reportMapping: There are " + mappings.size()
165 for (StructureMapping sm : mappings)
167 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
173 * map between the PDB IDs (or structure identifiers) used by Jalview and the
174 * absolute filenames for PDB data that corresponds to it
176 Map<String, String> pdbIdFileName = new HashMap<String, String>();
178 Map<String, String> pdbFileNameId = new HashMap<String, String>();
180 public void registerPDBFile(String idForFile, String absoluteFile)
182 pdbIdFileName.put(idForFile, absoluteFile);
183 pdbFileNameId.put(absoluteFile, idForFile);
186 public String findIdForPDBFile(String idOrFile)
188 String id = pdbFileNameId.get(idOrFile);
192 public String findFileForPDBId(String idOrFile)
194 String id = pdbIdFileName.get(idOrFile);
198 public boolean isPDBFileRegistered(String idOrFile)
200 return pdbFileNameId.containsKey(idOrFile)
201 || pdbIdFileName.containsKey(idOrFile);
204 private static StructureSelectionManager nullProvider = null;
206 public static StructureSelectionManager getStructureSelectionManager(
207 StructureSelectionManagerProvider context)
211 if (nullProvider == null)
213 if (instances != null)
217 .getString("error.implementation_error_structure_selection_manager_null"),
218 new NullPointerException(MessageManager
219 .getString("exception.ssm_context_is_null")));
223 nullProvider = new StructureSelectionManager();
228 if (instances == null)
230 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
232 StructureSelectionManager instance = instances.get(context);
233 if (instance == null)
235 if (nullProvider != null)
237 instance = nullProvider;
241 instance = new StructureSelectionManager();
243 instances.put(context, instance);
249 * flag controlling whether SeqMappings are relayed from received sequence
250 * mouse over events to other sequences
252 boolean relaySeqMappings = true;
255 * Enable or disable relay of seqMapping events to other sequences. You might
256 * want to do this if there are many sequence mappings and the host computer
261 public void setRelaySeqMappings(boolean relay)
263 relaySeqMappings = relay;
267 * get the state of the relay seqMappings flag.
269 * @return true if sequence mouse overs are being relayed to other mapped
272 public boolean isRelaySeqMappingsEnabled()
274 return relaySeqMappings;
277 Vector listeners = new Vector();
280 * register a listener for alignment sequence mouseover events
284 public void addStructureViewerListener(Object svl)
286 if (!listeners.contains(svl))
288 listeners.addElement(svl);
293 * Returns the file name for a mapped PDB id (or null if not mapped).
298 public String alreadyMappedToFile(String pdbid)
300 for (StructureMapping sm : mappings)
302 if (sm.getPdbId().equals(pdbid))
311 * Import structure data and register a structure mapping for broadcasting
312 * colouring, mouseovers and selection events (convenience wrapper).
315 * - one or more sequences to be mapped to pdbFile
316 * @param targetChains
317 * - optional chain specification for mapping each sequence to pdb
318 * (may be nill, individual elements may be nill)
320 * - structure data resource
322 * - how to resolve data from resource
323 * @return null or the structure data parsed as a pdb file
325 synchronized public StructureFile setMapping(SequenceI[] sequence,
326 String[] targetChains, String pdbFile, DataSourceType protocol)
328 return setMapping(true, sequence, targetChains, pdbFile, protocol);
332 * create sequence structure mappings between each sequence and the given
333 * pdbFile (retrieved via the given protocol).
335 * @param forStructureView
336 * when true, record the mapping for use in mouseOvers
338 * @param sequenceArray
339 * - one or more sequences to be mapped to pdbFile
340 * @param targetChainIds
341 * - optional chain specification for mapping each sequence to pdb
342 * (may be nill, individual elements may be nill)
344 * - structure data resource
346 * - how to resolve data from resource
347 * @return null or the structure data parsed as a pdb file
349 synchronized public StructureFile setMapping(boolean forStructureView,
350 SequenceI[] sequenceArray, String[] targetChainIds,
351 String pdbFile, DataSourceType sourceType)
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();
387 pdb = new JmolParser(pdbFile, sourceType);
389 if (pdb.getId() != null && pdb.getId().trim().length() > 0
390 && DataSourceType.FILE == sourceType)
392 registerPDBFile(pdb.getId().trim(), pdbFile);
394 // if PDBId is unavailable then skip SIFTS mapping execution path
395 isMapUsingSIFTs = isMapUsingSIFTs && pdb.isPPDBIdAvailable();
397 } catch (Exception ex)
399 ex.printStackTrace();
407 siftsClient = new SiftsClient(pdb);
409 } catch (SiftsException e)
411 isMapUsingSIFTs = false;
415 String targetChainId;
416 for (int s = 0; s < sequenceArray.length; s++)
418 boolean infChain = true;
419 final SequenceI seq = sequenceArray[s];
421 while (ds.getDatasetSequence() != null)
423 ds = ds.getDatasetSequence();
426 if (targetChainIds != null && targetChainIds[s] != null)
429 targetChainId = targetChainIds[s];
431 else if (seq.getName().indexOf("|") > -1)
433 targetChainId = seq.getName().substring(
434 seq.getName().lastIndexOf("|") + 1);
435 if (targetChainId.length() > 1)
437 if (targetChainId.trim().length() == 0)
443 // not a valid chain identifier
454 * Attempt pairwise alignment of the sequence with each chain in the PDB,
455 * and remember the highest scoring chain
458 AlignSeq maxAlignseq = null;
459 String maxChainId = " ";
460 PDBChain maxChain = null;
461 boolean first = true;
462 for (PDBChain chain : pdb.getChains())
464 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
467 continue; // don't try to map chains don't match.
469 // TODO: correctly determine sequence type for mixed na/peptide
471 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
472 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
475 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
476 // as.calcScoreMatrix();
477 // as.traceAlignment();
479 if (first || as.maxscore > max
480 || (as.maxscore == max && chain.id.equals(targetChainId)))
486 maxChainId = chain.id;
489 if (maxChain == null)
494 if (sourceType == DataSourceType.PASTE)
496 pdbFile = "INLINE" + pdb.getId();
499 List<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
500 if (isMapUsingSIFTs && seq.isProtein())
502 setProgressBar(null);
503 setProgressBar(MessageManager
504 .getString("status.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);// FIXME: is this
518 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
519 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
521 } catch (SiftsException e)
523 // fall back to NW alignment
524 System.err.println(e.getMessage());
525 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
526 targetChainId, maxChain, pdb, maxAlignseq);
527 seqToStrucMapping.add(nwMapping);
528 maxChain.makeExactMapping(maxAlignseq, seq);
529 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
531 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
532 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
537 List<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
538 for (PDBChain chain : pdb.getChains())
542 StructureMapping siftsMapping = getStructureMapping(seq,
543 pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
544 foundSiftsMappings.add(siftsMapping);
545 } catch (SiftsException e)
547 System.err.println(e.getMessage());
550 if (!foundSiftsMappings.isEmpty())
552 seqToStrucMapping.addAll(foundSiftsMappings);
553 maxChain.makeExactMapping(maxAlignseq, seq);
554 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
556 maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
558 ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0));
562 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
563 maxChainId, maxChain, pdb, maxAlignseq);
564 seqToStrucMapping.add(nwMapping);
565 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
567 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
568 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
574 setProgressBar(null);
575 setProgressBar(MessageManager
576 .getString("status.obtaining_mapping_with_nw_alignment"));
577 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
578 maxChainId, maxChain, pdb, maxAlignseq);
579 seqToStrucMapping.add(nwMapping);
580 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
584 if (forStructureView)
586 mappings.addAll(seqToStrucMapping);
592 private boolean isCIFFile(String filename)
594 String fileExt = filename.substring(filename.lastIndexOf(".") + 1,
596 return "cif".equalsIgnoreCase(fileExt);
600 * retrieve a mapping for seq from SIFTs using associated DBRefEntry for
605 * @param targetChainId
611 * @throws SiftsException
613 private StructureMapping getStructureMapping(SequenceI seq,
614 String pdbFile, String targetChainId, StructureFile pdb,
615 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
616 AlignSeq maxAlignseq) throws SiftsException
618 StructureMapping curChainMapping = siftsClient
619 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
622 PDBChain chain = pdb.findChain(targetChainId);
625 chain.transferResidueAnnotation(curChainMapping, sqmpping);
627 } catch (Exception e)
631 return curChainMapping;
634 private StructureMapping getNWMappings(SequenceI seq, String pdbFile,
635 String maxChainId, PDBChain maxChain, StructureFile pdb,
636 AlignSeq maxAlignseq)
638 final StringBuilder mappingDetails = new StringBuilder(128);
639 mappingDetails.append(NEWLINE).append(
640 "Sequence \u27f7 Structure mapping details");
641 mappingDetails.append(NEWLINE);
643 .append("Method: inferred with Needleman & Wunsch alignment");
644 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
645 .append(NEWLINE).append("Sequence = ")
646 .append(maxChain.sequence.getSequenceAsString());
647 mappingDetails.append(NEWLINE).append("No of residues = ")
648 .append(maxChain.residues.size()).append(NEWLINE)
650 PrintStream ps = new PrintStream(System.out)
653 public void print(String x)
655 mappingDetails.append(x);
659 public void println()
661 mappingDetails.append(NEWLINE);
665 maxAlignseq.printAlignment(ps);
667 mappingDetails.append(NEWLINE).append("PDB start/end ");
668 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
670 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
671 mappingDetails.append(NEWLINE).append("SEQ start/end ");
672 mappingDetails.append(
673 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
675 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
676 + (seq.getStart() - 1)));
677 mappingDetails.append(NEWLINE);
678 maxChain.makeExactMapping(maxAlignseq, seq);
679 jalview.datamodel.Mapping sqmpping = maxAlignseq
680 .getMappingFromS1(false);
681 maxChain.transferRESNUMFeatures(seq, null);
683 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
690 Atom tmp = maxChain.atoms.elementAt(index);
691 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
692 && tmp.alignmentMapping != -1)
694 resNum = tmp.resNumber;
695 insCode = tmp.insCode;
696 if (tmp.alignmentMapping >= -1)
698 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
704 } while (index < maxChain.atoms.size());
706 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
707 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
708 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
712 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
714 listeners.removeElement(svl);
715 if (svl instanceof SequenceListener)
717 for (int i = 0; i < listeners.size(); i++)
719 if (listeners.elementAt(i) instanceof StructureListener)
721 ((StructureListener) listeners.elementAt(i))
722 .releaseReferences(svl);
727 if (pdbfiles == null)
733 * Remove mappings to the closed listener's PDB files, but first check if
734 * another listener is still interested
736 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
738 StructureListener sl;
739 for (int i = 0; i < listeners.size(); i++)
741 if (listeners.elementAt(i) instanceof StructureListener)
743 sl = (StructureListener) listeners.elementAt(i);
744 for (String pdbfile : sl.getPdbFile())
746 pdbs.remove(pdbfile);
752 * Rebuild the mappings set, retaining only those which are for 'other' PDB
757 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
758 for (StructureMapping sm : mappings)
760 if (!pdbs.contains(sm.pdbfile))
771 * Propagate mouseover of a single position in a structure
777 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
779 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
780 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
781 mouseOverStructure(atoms);
785 * Propagate mouseover or selection of multiple positions in a structure
789 public void mouseOverStructure(List<AtomSpec> atoms)
791 if (listeners == null)
793 // old or prematurely sent event
796 boolean hasSequenceListener = false;
797 for (int i = 0; i < listeners.size(); i++)
799 if (listeners.elementAt(i) instanceof SequenceListener)
801 hasSequenceListener = true;
804 if (!hasSequenceListener)
809 SearchResultsI results = new SearchResults();
810 for (AtomSpec atom : atoms)
812 SequenceI lastseq = null;
814 for (StructureMapping sm : mappings)
816 if (sm.pdbfile.equals(atom.getPdbFile())
817 && sm.pdbchain.equals(atom.getChain()))
819 int indexpos = sm.getSeqPos(atom.getPdbResNum());
820 if (lastipos != indexpos && lastseq != sm.sequence)
822 results.addResult(sm.sequence, indexpos, indexpos);
824 lastseq = sm.sequence;
825 // construct highlighted sequence list
826 for (AlignedCodonFrame acf : seqmappings)
828 acf.markMappedRegion(sm.sequence, indexpos, results);
834 for (Object li : listeners)
836 if (li instanceof SequenceListener)
838 ((SequenceListener) li).highlightSequence(results);
844 * highlight regions associated with a position (indexpos) in seq
847 * the sequence that the mouse over occurred on
849 * the absolute position being mouseovered in seq (0 to seq.length())
851 * the sequence position (if -1, seq.findPosition is called to
852 * resolve the residue number)
854 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
857 boolean hasSequenceListeners = handlingVamsasMo
858 || !seqmappings.isEmpty();
859 SearchResultsI results = null;
862 seqPos = seq.findPosition(indexpos);
864 for (int i = 0; i < listeners.size(); i++)
866 Object listener = listeners.elementAt(i);
867 if (listener == source)
869 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
870 // Temporary fudge with SequenceListener.getVamsasSource()
873 if (listener instanceof StructureListener)
875 highlightStructure((StructureListener) listener, seq, seqPos);
879 if (listener instanceof SequenceListener)
881 final SequenceListener seqListener = (SequenceListener) listener;
882 if (hasSequenceListeners
883 && seqListener.getVamsasSource() != source)
885 if (relaySeqMappings)
889 results = MappingUtils.buildSearchResults(seq, seqPos,
892 if (handlingVamsasMo)
894 results.addResult(seq, seqPos, seqPos);
897 if (!results.isEmpty())
899 seqListener.highlightSequence(results);
904 else if (listener instanceof VamsasListener && !handlingVamsasMo)
906 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
909 else if (listener instanceof SecondaryStructureListener)
911 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
919 * Send suitable messages to a StructureListener to highlight atoms
920 * corresponding to the given sequence position(s)
926 public void highlightStructure(StructureListener sl, SequenceI seq,
929 if (!sl.isListeningFor(seq))
934 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
935 for (StructureMapping sm : mappings)
937 if (sm.sequence == seq
938 || sm.sequence == seq.getDatasetSequence()
939 || (sm.sequence.getDatasetSequence() != null && sm.sequence
940 .getDatasetSequence() == seq.getDatasetSequence()))
942 for (int index : positions)
944 atomNo = sm.getAtomNum(index);
948 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
949 .getPDBResNum(index), atomNo));
954 sl.highlightAtoms(atoms);
958 * true if a mouse over event from an external (ie Vamsas) source is being
961 boolean handlingVamsasMo = false;
966 * as mouseOverSequence but only route event to SequenceListeners
970 * in an alignment sequence
972 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
975 handlingVamsasMo = true;
976 long msg = sequenceI.hashCode() * (1 + position);
980 mouseOverSequence(sequenceI, position, -1, source);
982 handlingVamsasMo = false;
985 public Annotation[] colourSequenceFromStructure(SequenceI seq,
989 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
990 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
992 * Annotation [] annotations = new Annotation[seq.getLength()];
994 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
995 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
996 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
998 * for (int j = 0; j < mappings.length; j++) {
1000 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
1001 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
1002 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
1003 * "+mappings[j].pdbfile);
1005 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
1006 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
1008 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
1009 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
1010 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
1011 * mappings[j].pdbfile); }
1013 * annotations[index] = new Annotation("X",null,' ',0,col); } return
1014 * annotations; } } } }
1016 * return annotations;
1020 public void structureSelectionChanged()
1024 public void sequenceSelectionChanged()
1028 public void sequenceColoursChanged(Object source)
1030 StructureListener sl;
1031 for (int i = 0; i < listeners.size(); i++)
1033 if (listeners.elementAt(i) instanceof StructureListener)
1035 sl = (StructureListener) listeners.elementAt(i);
1036 sl.updateColours(source);
1041 public StructureMapping[] getMapping(String pdbfile)
1043 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1044 for (StructureMapping sm : mappings)
1046 if (sm.pdbfile.equals(pdbfile))
1051 return tmp.toArray(new StructureMapping[tmp.size()]);
1055 * Returns a readable description of all mappings for the given pdbfile to any
1056 * of the given sequences
1062 public String printMappings(String pdbfile, List<SequenceI> seqs)
1064 if (pdbfile == null || seqs == null || seqs.isEmpty())
1069 StringBuilder sb = new StringBuilder(64);
1070 for (StructureMapping sm : mappings)
1072 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1074 sb.append(sm.mappingDetails);
1076 // separator makes it easier to read multiple mappings
1077 sb.append("=====================");
1083 return sb.toString();
1087 * Remove the given mapping
1091 public void deregisterMapping(AlignedCodonFrame acf)
1095 boolean removed = seqmappings.remove(acf);
1096 if (removed && seqmappings.isEmpty())
1098 System.out.println("All mappings removed");
1104 * Add each of the given codonFrames to the stored set, if not aready present.
1108 public void registerMappings(List<AlignedCodonFrame> mappings)
1110 if (mappings != null)
1112 for (AlignedCodonFrame acf : mappings)
1114 registerMapping(acf);
1120 * Add the given mapping to the stored set, unless already stored.
1122 public void registerMapping(AlignedCodonFrame acf)
1126 if (!seqmappings.contains(acf))
1128 seqmappings.add(acf);
1134 * Resets this object to its initial state by removing all registered
1135 * listeners, codon mappings, PDB file mappings
1137 public void resetAll()
1139 if (mappings != null)
1143 if (seqmappings != null)
1145 seqmappings.clear();
1147 if (sel_listeners != null)
1149 sel_listeners.clear();
1151 if (listeners != null)
1155 if (commandListeners != null)
1157 commandListeners.clear();
1159 if (view_listeners != null)
1161 view_listeners.clear();
1163 if (pdbFileNameId != null)
1165 pdbFileNameId.clear();
1167 if (pdbIdFileName != null)
1169 pdbIdFileName.clear();
1173 public void addSelectionListener(SelectionListener selecter)
1175 if (!sel_listeners.contains(selecter))
1177 sel_listeners.add(selecter);
1181 public void removeSelectionListener(SelectionListener toremove)
1183 if (sel_listeners.contains(toremove))
1185 sel_listeners.remove(toremove);
1189 public synchronized void sendSelection(
1190 jalview.datamodel.SequenceGroup selection,
1191 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1193 for (SelectionListener slis : sel_listeners)
1197 slis.selection(selection, colsel, source);
1202 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1204 public synchronized void sendViewPosition(
1205 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1206 int startSeq, int endSeq)
1209 if (view_listeners != null && view_listeners.size() > 0)
1211 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1213 while (listeners.hasMoreElements())
1215 AlignmentViewPanelListener slis = listeners.nextElement();
1218 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1226 * release all references associated with this manager provider
1228 * @param jalviewLite
1230 public static void release(StructureSelectionManagerProvider jalviewLite)
1232 // synchronized (instances)
1234 if (instances == null)
1238 StructureSelectionManager mnger = (instances.get(jalviewLite));
1241 instances.remove(jalviewLite);
1245 } catch (Throwable x)
1252 public void registerPDBEntry(PDBEntry pdbentry)
1254 if (pdbentry.getFile() != null
1255 && pdbentry.getFile().trim().length() > 0)
1257 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1261 public void addCommandListener(CommandListener cl)
1263 if (!commandListeners.contains(cl))
1265 commandListeners.add(cl);
1269 public boolean hasCommandListener(CommandListener cl)
1271 return this.commandListeners.contains(cl);
1274 public boolean removeCommandListener(CommandListener l)
1276 return commandListeners.remove(l);
1280 * Forward a command to any command listeners (except for the command's
1284 * the command to be broadcast (in its form after being performed)
1286 * if true, the command was being 'undone'
1289 public void commandPerformed(CommandI command, boolean undo,
1290 VamsasSource source)
1292 for (CommandListener listener : commandListeners)
1294 listener.mirrorCommand(command, undo, this, source);
1299 * Returns a new CommandI representing the given command as mapped to the
1300 * given sequences. If no mapping could be made, or the command is not of a
1301 * mappable kind, returns null.
1309 public CommandI mapCommand(CommandI command, boolean undo,
1310 final AlignmentI mapTo, char gapChar)
1312 if (command instanceof EditCommand)
1314 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1315 mapTo, gapChar, seqmappings);
1317 else if (command instanceof OrderCommand)
1319 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1320 mapTo, seqmappings);
1325 public IProgressIndicator getProgressIndicator()
1327 return progressIndicator;
1330 public void setProgressIndicator(IProgressIndicator progressIndicator)
1332 this.progressIndicator = progressIndicator;
1335 public long getProgressSessionId()
1337 return progressSessionId;
1340 public void setProgressSessionId(long progressSessionId)
1342 this.progressSessionId = progressSessionId;
1345 public void setProgressBar(String message)
1347 if (progressIndicator == null)
1351 progressIndicator.setProgressBar(message, progressSessionId);
1354 public List<AlignedCodonFrame> getSequenceMappings()