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 PDBId is unavailable then skip SIFTS mapping execution path
394 isMapUsingSIFTs = isMapUsingSIFTs && pdb.isPPDBIdAvailable();
396 } catch (Exception ex)
398 ex.printStackTrace();
406 siftsClient = new SiftsClient(pdb);
408 } catch (SiftsException e)
410 isMapUsingSIFTs = false;
414 String targetChainId;
415 for (int s = 0; s < sequenceArray.length; s++)
417 boolean infChain = true;
418 final SequenceI seq = sequenceArray[s];
420 while (ds.getDatasetSequence() != null)
422 ds = ds.getDatasetSequence();
425 if (targetChainIds != null && targetChainIds[s] != null)
428 targetChainId = targetChainIds[s];
430 else if (seq.getName().indexOf("|") > -1)
432 targetChainId = seq.getName().substring(
433 seq.getName().lastIndexOf("|") + 1);
434 if (targetChainId.length() > 1)
436 if (targetChainId.trim().length() == 0)
442 // not a valid chain identifier
453 * Attempt pairwise alignment of the sequence with each chain in the PDB,
454 * and remember the highest scoring chain
457 AlignSeq maxAlignseq = null;
458 String maxChainId = " ";
459 PDBChain maxChain = null;
460 boolean first = true;
461 for (PDBChain chain : pdb.getChains())
463 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
466 continue; // don't try to map chains don't match.
468 // TODO: correctly determine sequence type for mixed na/peptide
470 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
471 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
474 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
475 // as.calcScoreMatrix();
476 // as.traceAlignment();
478 if (first || as.maxscore > max
479 || (as.maxscore == max && chain.id.equals(targetChainId)))
485 maxChainId = chain.id;
488 if (maxChain == null)
493 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
495 pdbFile = "INLINE" + pdb.getId();
498 ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
499 if (isMapUsingSIFTs && seq.isProtein())
501 setProgressBar(null);
502 setProgressBar(MessageManager
503 .getString("status.obtaining_mapping_with_sifts"));
504 jalview.datamodel.Mapping sqmpping = maxAlignseq
505 .getMappingFromS1(false);
506 if (targetChainId != null && !targetChainId.trim().isEmpty())
508 StructureMapping siftsMapping;
511 siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
512 pdb, maxChain, sqmpping, maxAlignseq);
513 seqToStrucMapping.add(siftsMapping);
514 maxChain.makeExactMapping(maxAlignseq, seq);
515 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
517 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
518 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
520 } catch (SiftsException e)
522 // fall back to NW alignment
523 System.err.println(e.getMessage());
524 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
525 targetChainId, maxChain, pdb, maxAlignseq);
526 seqToStrucMapping.add(nwMapping);
527 maxChain.makeExactMapping(maxAlignseq, seq);
528 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
530 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
531 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
536 ArrayList<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
537 for (PDBChain chain : pdb.getChains())
541 StructureMapping siftsMapping = getStructureMapping(seq,
542 pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
543 foundSiftsMappings.add(siftsMapping);
544 } catch (SiftsException e)
546 System.err.println(e.getMessage());
549 if (!foundSiftsMappings.isEmpty())
551 seqToStrucMapping.addAll(foundSiftsMappings);
552 maxChain.makeExactMapping(maxAlignseq, seq);
553 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
555 maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
557 ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0));
561 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
562 maxChainId, maxChain, pdb, maxAlignseq);
563 seqToStrucMapping.add(nwMapping);
564 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
566 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
567 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
573 setProgressBar(null);
574 setProgressBar(MessageManager
575 .getString("status.obtaining_mapping_with_nw_alignment"));
576 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
577 maxChainId, maxChain, pdb, maxAlignseq);
578 seqToStrucMapping.add(nwMapping);
579 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
583 if (forStructureView)
585 mappings.addAll(seqToStrucMapping);
591 private boolean isCIFFile(String filename)
593 String fileExt = filename.substring(filename.lastIndexOf(".") + 1,
595 return "cif".equalsIgnoreCase(fileExt);
599 * retrieve a mapping for seq from SIFTs using associated DBRefEntry for
604 * @param targetChainId
610 * @throws SiftsException
612 private StructureMapping getStructureMapping(SequenceI seq,
613 String pdbFile, String targetChainId, StructureFile pdb,
614 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
615 AlignSeq maxAlignseq) throws SiftsException
617 StructureMapping curChainMapping = siftsClient
618 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
621 PDBChain chain = pdb.findChain(targetChainId);
624 chain.transferResidueAnnotation(curChainMapping, sqmpping);
626 } catch (Exception e)
630 return curChainMapping;
633 private StructureMapping getNWMappings(SequenceI seq, String pdbFile,
634 String maxChainId, PDBChain maxChain, StructureFile pdb,
635 AlignSeq maxAlignseq)
637 final StringBuilder mappingDetails = new StringBuilder(128);
638 mappingDetails.append(NEWLINE).append(
639 "Sequence \u27f7 Structure mapping details");
640 mappingDetails.append(NEWLINE);
642 .append("Method: inferred with Needleman & Wunsch alignment");
643 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
644 .append(NEWLINE).append("Sequence = ")
645 .append(maxChain.sequence.getSequenceAsString());
646 mappingDetails.append(NEWLINE).append("No of residues = ")
647 .append(maxChain.residues.size()).append(NEWLINE)
649 PrintStream ps = new PrintStream(System.out)
652 public void print(String x)
654 mappingDetails.append(x);
658 public void println()
660 mappingDetails.append(NEWLINE);
664 maxAlignseq.printAlignment(ps);
666 mappingDetails.append(NEWLINE).append("PDB start/end ");
667 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
669 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
670 mappingDetails.append(NEWLINE).append("SEQ start/end ");
671 mappingDetails.append(
672 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
674 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
675 + (seq.getStart() - 1)));
676 mappingDetails.append(NEWLINE);
677 maxChain.makeExactMapping(maxAlignseq, seq);
678 jalview.datamodel.Mapping sqmpping = maxAlignseq
679 .getMappingFromS1(false);
680 maxChain.transferRESNUMFeatures(seq, null);
682 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
689 Atom tmp = maxChain.atoms.elementAt(index);
690 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
691 && tmp.alignmentMapping != -1)
693 resNum = tmp.resNumber;
694 insCode = tmp.insCode;
695 if (tmp.alignmentMapping >= -1)
697 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
703 } while (index < maxChain.atoms.size());
705 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
706 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
707 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
711 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
713 listeners.removeElement(svl);
714 if (svl instanceof SequenceListener)
716 for (int i = 0; i < listeners.size(); i++)
718 if (listeners.elementAt(i) instanceof StructureListener)
720 ((StructureListener) listeners.elementAt(i))
721 .releaseReferences(svl);
726 if (pdbfiles == null)
732 * Remove mappings to the closed listener's PDB files, but first check if
733 * another listener is still interested
735 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
737 StructureListener sl;
738 for (int i = 0; i < listeners.size(); i++)
740 if (listeners.elementAt(i) instanceof StructureListener)
742 sl = (StructureListener) listeners.elementAt(i);
743 for (String pdbfile : sl.getPdbFile())
745 pdbs.remove(pdbfile);
751 * Rebuild the mappings set, retaining only those which are for 'other' PDB
756 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
757 for (StructureMapping sm : mappings)
759 if (!pdbs.contains(sm.pdbfile))
770 * Propagate mouseover of a single position in a structure
776 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
778 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
779 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
780 mouseOverStructure(atoms);
784 * Propagate mouseover or selection of multiple positions in a structure
788 public void mouseOverStructure(List<AtomSpec> atoms)
790 if (listeners == null)
792 // old or prematurely sent event
795 boolean hasSequenceListener = false;
796 for (int i = 0; i < listeners.size(); i++)
798 if (listeners.elementAt(i) instanceof SequenceListener)
800 hasSequenceListener = true;
803 if (!hasSequenceListener)
808 SearchResults results = new SearchResults();
809 for (AtomSpec atom : atoms)
811 SequenceI lastseq = null;
813 for (StructureMapping sm : mappings)
815 if (sm.pdbfile.equals(atom.getPdbFile())
816 && sm.pdbchain.equals(atom.getChain()))
818 int indexpos = sm.getSeqPos(atom.getPdbResNum());
819 if (lastipos != indexpos && lastseq != sm.sequence)
821 results.addResult(sm.sequence, indexpos, indexpos);
823 lastseq = sm.sequence;
824 // construct highlighted sequence list
825 for (AlignedCodonFrame acf : seqmappings)
827 acf.markMappedRegion(sm.sequence, indexpos, results);
833 for (Object li : listeners)
835 if (li instanceof SequenceListener)
837 ((SequenceListener) li).highlightSequence(results);
843 * highlight regions associated with a position (indexpos) in seq
846 * the sequence that the mouse over occurred on
848 * the absolute position being mouseovered in seq (0 to seq.length())
850 * the sequence position (if -1, seq.findPosition is called to
851 * resolve the residue number)
853 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
856 boolean hasSequenceListeners = handlingVamsasMo
857 || !seqmappings.isEmpty();
858 SearchResults results = null;
861 seqPos = seq.findPosition(indexpos);
863 for (int i = 0; i < listeners.size(); i++)
865 Object listener = listeners.elementAt(i);
866 if (listener == source)
868 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
869 // Temporary fudge with SequenceListener.getVamsasSource()
872 if (listener instanceof StructureListener)
874 highlightStructure((StructureListener) listener, seq, seqPos);
878 if (listener instanceof SequenceListener)
880 final SequenceListener seqListener = (SequenceListener) listener;
881 if (hasSequenceListeners
882 && seqListener.getVamsasSource() != source)
884 if (relaySeqMappings)
888 results = MappingUtils.buildSearchResults(seq, seqPos,
891 if (handlingVamsasMo)
893 results.addResult(seq, seqPos, seqPos);
896 if (!results.isEmpty())
898 seqListener.highlightSequence(results);
903 else if (listener instanceof VamsasListener && !handlingVamsasMo)
905 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
908 else if (listener instanceof SecondaryStructureListener)
910 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
918 * Send suitable messages to a StructureListener to highlight atoms
919 * corresponding to the given sequence position(s)
925 public void highlightStructure(StructureListener sl, SequenceI seq,
928 if (!sl.isListeningFor(seq))
933 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
934 for (StructureMapping sm : mappings)
936 if (sm.sequence == seq
937 || sm.sequence == seq.getDatasetSequence()
938 || (sm.sequence.getDatasetSequence() != null && sm.sequence
939 .getDatasetSequence() == seq.getDatasetSequence()))
941 for (int index : positions)
943 atomNo = sm.getAtomNum(index);
947 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
948 .getPDBResNum(index), atomNo));
953 sl.highlightAtoms(atoms);
957 * true if a mouse over event from an external (ie Vamsas) source is being
960 boolean handlingVamsasMo = false;
965 * as mouseOverSequence but only route event to SequenceListeners
969 * in an alignment sequence
971 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
974 handlingVamsasMo = true;
975 long msg = sequenceI.hashCode() * (1 + position);
979 mouseOverSequence(sequenceI, position, -1, source);
981 handlingVamsasMo = false;
984 public Annotation[] colourSequenceFromStructure(SequenceI seq,
988 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
989 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
991 * Annotation [] annotations = new Annotation[seq.getLength()];
993 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
994 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
995 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
997 * for (int j = 0; j < mappings.length; j++) {
999 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
1000 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
1001 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
1002 * "+mappings[j].pdbfile);
1004 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
1005 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
1007 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
1008 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
1009 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
1010 * mappings[j].pdbfile); }
1012 * annotations[index] = new Annotation("X",null,' ',0,col); } return
1013 * annotations; } } } }
1015 * return annotations;
1019 public void structureSelectionChanged()
1023 public void sequenceSelectionChanged()
1027 public void sequenceColoursChanged(Object source)
1029 StructureListener sl;
1030 for (int i = 0; i < listeners.size(); i++)
1032 if (listeners.elementAt(i) instanceof StructureListener)
1034 sl = (StructureListener) listeners.elementAt(i);
1035 sl.updateColours(source);
1040 public StructureMapping[] getMapping(String pdbfile)
1042 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1043 for (StructureMapping sm : mappings)
1045 if (sm.pdbfile.equals(pdbfile))
1050 return tmp.toArray(new StructureMapping[tmp.size()]);
1054 * Returns a readable description of all mappings for the given pdbfile to any
1055 * of the given sequences
1061 public String printMappings(String pdbfile, List<SequenceI> seqs)
1063 if (pdbfile == null || seqs == null || seqs.isEmpty())
1068 StringBuilder sb = new StringBuilder(64);
1069 for (StructureMapping sm : mappings)
1071 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1073 sb.append(sm.mappingDetails);
1075 // separator makes it easier to read multiple mappings
1076 sb.append("=====================");
1082 return sb.toString();
1086 * Remove the given mapping
1090 public void deregisterMapping(AlignedCodonFrame acf)
1094 boolean removed = seqmappings.remove(acf);
1095 if (removed && seqmappings.isEmpty())
1097 System.out.println("All mappings removed");
1103 * Add each of the given codonFrames to the stored set, if not aready present.
1107 public void registerMappings(List<AlignedCodonFrame> mappings)
1109 if (mappings != null)
1111 for (AlignedCodonFrame acf : mappings)
1113 registerMapping(acf);
1119 * Add the given mapping to the stored set, unless already stored.
1121 public void registerMapping(AlignedCodonFrame acf)
1125 if (!seqmappings.contains(acf))
1127 seqmappings.add(acf);
1133 * Resets this object to its initial state by removing all registered
1134 * listeners, codon mappings, PDB file mappings
1136 public void resetAll()
1138 if (mappings != null)
1142 if (seqmappings != null)
1144 seqmappings.clear();
1146 if (sel_listeners != null)
1148 sel_listeners.clear();
1150 if (listeners != null)
1154 if (commandListeners != null)
1156 commandListeners.clear();
1158 if (view_listeners != null)
1160 view_listeners.clear();
1162 if (pdbFileNameId != null)
1164 pdbFileNameId.clear();
1166 if (pdbIdFileName != null)
1168 pdbIdFileName.clear();
1172 public void addSelectionListener(SelectionListener selecter)
1174 if (!sel_listeners.contains(selecter))
1176 sel_listeners.add(selecter);
1180 public void removeSelectionListener(SelectionListener toremove)
1182 if (sel_listeners.contains(toremove))
1184 sel_listeners.remove(toremove);
1188 public synchronized void sendSelection(
1189 jalview.datamodel.SequenceGroup selection,
1190 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1192 for (SelectionListener slis : sel_listeners)
1196 slis.selection(selection, colsel, source);
1201 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1203 public synchronized void sendViewPosition(
1204 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1205 int startSeq, int endSeq)
1208 if (view_listeners != null && view_listeners.size() > 0)
1210 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1212 while (listeners.hasMoreElements())
1214 AlignmentViewPanelListener slis = listeners.nextElement();
1217 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1225 * release all references associated with this manager provider
1227 * @param jalviewLite
1229 public static void release(StructureSelectionManagerProvider jalviewLite)
1231 // synchronized (instances)
1233 if (instances == null)
1237 StructureSelectionManager mnger = (instances.get(jalviewLite));
1240 instances.remove(jalviewLite);
1244 } catch (Throwable x)
1251 public void registerPDBEntry(PDBEntry pdbentry)
1253 if (pdbentry.getFile() != null
1254 && pdbentry.getFile().trim().length() > 0)
1256 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1260 public void addCommandListener(CommandListener cl)
1262 if (!commandListeners.contains(cl))
1264 commandListeners.add(cl);
1268 public boolean hasCommandListener(CommandListener cl)
1270 return this.commandListeners.contains(cl);
1273 public boolean removeCommandListener(CommandListener l)
1275 return commandListeners.remove(l);
1279 * Forward a command to any command listeners (except for the command's
1283 * the command to be broadcast (in its form after being performed)
1285 * if true, the command was being 'undone'
1288 public void commandPerformed(CommandI command, boolean undo,
1289 VamsasSource source)
1291 for (CommandListener listener : commandListeners)
1293 listener.mirrorCommand(command, undo, this, source);
1298 * Returns a new CommandI representing the given command as mapped to the
1299 * given sequences. If no mapping could be made, or the command is not of a
1300 * mappable kind, returns null.
1308 public CommandI mapCommand(CommandI command, boolean undo,
1309 final AlignmentI mapTo, char gapChar)
1311 if (command instanceof EditCommand)
1313 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1314 mapTo, gapChar, seqmappings);
1316 else if (command instanceof OrderCommand)
1318 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1319 mapTo, seqmappings);
1324 public IProgressIndicator getProgressIndicator()
1326 return progressIndicator;
1329 public void setProgressIndicator(IProgressIndicator progressIndicator)
1331 this.progressIndicator = progressIndicator;
1334 public long getProgressSessionId()
1336 return progressSessionId;
1339 public void setProgressSessionId(long progressSessionId)
1341 this.progressSessionId = progressSessionId;
1344 public void setProgressBar(String message)
1346 if (progressIndicator == null)
1350 progressIndicator.setProgressBar(message, progressSessionId);
1353 public List<AlignedCodonFrame> getSequenceMappings()