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();
387 pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr,
388 secStructServices, pdbFile, protocol);
390 if (pdb.getId() != null && pdb.getId().trim().length() > 0
391 && AppletFormatAdapter.FILE.equals(protocol))
393 registerPDBFile(pdb.getId().trim(), pdbFile);
395 } catch (Exception ex)
397 ex.printStackTrace();
405 siftsClient = new SiftsClient(pdb);
407 } catch (SiftsException e)
409 isMapUsingSIFTs = false;
413 String targetChainId;
414 for (int s = 0; s < sequenceArray.length; s++)
416 boolean infChain = true;
417 final SequenceI seq = sequenceArray[s];
419 while (ds.getDatasetSequence() != null)
421 ds = ds.getDatasetSequence();
424 if (targetChainIds != null && targetChainIds[s] != null)
427 targetChainId = targetChainIds[s];
429 else if (seq.getName().indexOf("|") > -1)
431 targetChainId = seq.getName().substring(
432 seq.getName().lastIndexOf("|") + 1);
433 if (targetChainId.length() > 1)
435 if (targetChainId.trim().length() == 0)
441 // not a valid chain identifier
452 * Attempt pairwise alignment of the sequence with each chain in the PDB,
453 * and remember the highest scoring chain
456 AlignSeq maxAlignseq = null;
457 String maxChainId = " ";
458 PDBChain maxChain = null;
459 boolean first = true;
460 for (PDBChain chain : pdb.getChains())
462 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
465 continue; // don't try to map chains don't match.
467 // TODO: correctly determine sequence type for mixed na/peptide
469 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
470 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
473 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
474 // as.calcScoreMatrix();
475 // as.traceAlignment();
477 if (first || as.maxscore > max
478 || (as.maxscore == max && chain.id.equals(targetChainId)))
484 maxChainId = chain.id;
487 if (maxChain == null)
492 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
494 pdbFile = "INLINE" + pdb.getId();
497 ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
498 if (isMapUsingSIFTs && seq.isProtein())
500 setProgressBar(null);
501 setProgressBar(MessageManager
502 .getString("status.obtaining_mapping_with_sifts"));
503 jalview.datamodel.Mapping sqmpping = maxAlignseq
504 .getMappingFromS1(false);
505 if (targetChainId != null && !targetChainId.trim().isEmpty())
507 StructureMapping siftsMapping;
510 siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
511 pdb, maxChain, sqmpping, maxAlignseq);
512 seqToStrucMapping.add(siftsMapping);
513 maxChain.makeExactMapping(maxAlignseq, seq);
514 maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
516 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
517 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
519 } catch (SiftsException e)
521 // fall back to NW alignment
522 System.err.println(e.getMessage());
523 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
524 targetChainId, maxChain, pdb, maxAlignseq);
525 seqToStrucMapping.add(nwMapping);
526 maxChain.makeExactMapping(maxAlignseq, seq);
527 maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
529 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
530 ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
535 ArrayList<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
536 for (PDBChain chain : pdb.getChains())
540 StructureMapping siftsMapping = getStructureMapping(seq,
542 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,
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 SearchResults 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 SearchResults 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()