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 SiftsClient siftsClient = null;
76 * Set of any registered mappings between (dataset) sequences.
78 private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
80 private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
82 private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
85 * @return true if will try to use external services for processing secondary
88 public boolean isSecStructServices()
90 return secStructServices;
94 * control use of external services for processing secondary structure
96 * @param secStructServices
98 public void setSecStructServices(boolean secStructServices)
100 this.secStructServices = secStructServices;
104 * flag controlling addition of any kind of structural annotation
106 * @return true if temperature factor annotation will be added
108 public boolean isAddTempFacAnnot()
110 return addTempFacAnnot;
114 * set flag controlling addition of structural annotation
116 * @param addTempFacAnnot
118 public void setAddTempFacAnnot(boolean addTempFacAnnot)
120 this.addTempFacAnnot = addTempFacAnnot;
125 * @return if true, the structure manager will attempt to add secondary
126 * structure lines for unannotated sequences
129 public boolean isProcessSecondaryStructure()
131 return processSecondaryStructure;
135 * Control whether structure manager will try to annotate mapped sequences
136 * with secondary structure from PDB data.
140 public void setProcessSecondaryStructure(boolean enable)
142 processSecondaryStructure = enable;
146 * debug function - write all mappings to stdout
148 public void reportMapping()
150 if (mappings.isEmpty())
152 System.err.println("reportMapping: No PDB/Sequence mappings.");
156 System.err.println("reportMapping: There are " + mappings.size()
159 for (StructureMapping sm : mappings)
161 System.err.println("mapping " + i++ + " : " + sm.pdbfile);
167 * map between the PDB IDs (or structure identifiers) used by Jalview and the
168 * absolute filenames for PDB data that corresponds to it
170 Map<String, String> pdbIdFileName = new HashMap<String, String>();
172 Map<String, String> pdbFileNameId = new HashMap<String, String>();
174 public void registerPDBFile(String idForFile, String absoluteFile)
176 pdbIdFileName.put(idForFile, absoluteFile);
177 pdbFileNameId.put(absoluteFile, idForFile);
180 public String findIdForPDBFile(String idOrFile)
182 String id = pdbFileNameId.get(idOrFile);
186 public String findFileForPDBId(String idOrFile)
188 String id = pdbIdFileName.get(idOrFile);
192 public boolean isPDBFileRegistered(String idOrFile)
194 return pdbFileNameId.containsKey(idOrFile)
195 || pdbIdFileName.containsKey(idOrFile);
198 private static StructureSelectionManager nullProvider = null;
200 public static StructureSelectionManager getStructureSelectionManager(
201 StructureSelectionManagerProvider context)
205 if (nullProvider == null)
207 if (instances != null)
211 .getString("error.implementation_error_structure_selection_manager_null"),
212 new NullPointerException(MessageManager
213 .getString("exception.ssm_context_is_null")));
217 nullProvider = new StructureSelectionManager();
222 if (instances == null)
224 instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
226 StructureSelectionManager instance = instances.get(context);
227 if (instance == null)
229 if (nullProvider != null)
231 instance = nullProvider;
235 instance = new StructureSelectionManager();
237 instances.put(context, instance);
243 * flag controlling whether SeqMappings are relayed from received sequence
244 * mouse over events to other sequences
246 boolean relaySeqMappings = true;
249 * Enable or disable relay of seqMapping events to other sequences. You might
250 * want to do this if there are many sequence mappings and the host computer
255 public void setRelaySeqMappings(boolean relay)
257 relaySeqMappings = relay;
261 * get the state of the relay seqMappings flag.
263 * @return true if sequence mouse overs are being relayed to other mapped
266 public boolean isRelaySeqMappingsEnabled()
268 return relaySeqMappings;
271 Vector listeners = new Vector();
274 * register a listener for alignment sequence mouseover events
278 public void addStructureViewerListener(Object svl)
280 if (!listeners.contains(svl))
282 listeners.addElement(svl);
287 * Returns the file name for a mapped PDB id (or null if not mapped).
292 public String alreadyMappedToFile(String pdbid)
294 for (StructureMapping sm : mappings)
296 if (sm.getPdbId().equals(pdbid))
305 * Import structure data and register a structure mapping for broadcasting
306 * colouring, mouseovers and selection events (convenience wrapper).
309 * - one or more sequences to be mapped to pdbFile
310 * @param targetChains
311 * - optional chain specification for mapping each sequence to pdb
312 * (may be nill, individual elements may be nill)
314 * - structure data resource
316 * - how to resolve data from resource
317 * @return null or the structure data parsed as a pdb file
319 synchronized public StructureFile setMapping(SequenceI[] sequence,
320 String[] targetChains, String pdbFile, String protocol,
321 IProgressIndicator progress)
323 return computeMapping(true, sequence, targetChains, pdbFile, protocol,
329 * create sequence structure mappings between each sequence and the given
330 * pdbFile (retrieved via the given protocol).
332 * @param forStructureView
333 * when true, record the mapping for use in mouseOvers
335 * @param sequenceArray
336 * - one or more sequences to be mapped to pdbFile
337 * @param targetChainIds
338 * - optional chain specification for mapping each sequence to pdb
339 * (may be null, individual elements may be null)
341 * - structure data resource
343 * - how to resolve data from resource
344 * @return null or the structure data parsed as a pdb file
346 synchronized public StructureFile setMapping(boolean forStructureView,
347 SequenceI[] sequenceArray, String[] targetChainIds,
351 return computeMapping(forStructureView, sequenceArray, targetChainIds,
352 pdbFile, protocol, null);
355 synchronized public StructureFile computeMapping(
356 boolean forStructureView, SequenceI[] sequenceArray,
357 String[] targetChainIds, String pdbFile, String protocol,
358 IProgressIndicator progress)
360 long progressSessionId = System.currentTimeMillis() * 3;
362 * There will be better ways of doing this in the future, for now we'll use
363 * the tried and tested MCview pdb mapping
365 boolean parseSecStr = processSecondaryStructure;
366 if (isPDBFileRegistered(pdbFile))
368 for (SequenceI sq : sequenceArray)
371 while (ds.getDatasetSequence() != null)
373 ds = ds.getDatasetSequence();
376 if (ds.getAnnotation() != null)
378 for (AlignmentAnnotation ala : ds.getAnnotation())
380 // false if any annotation present from this structure
381 // JBPNote this fails for jmol/chimera view because the *file* is
382 // passed, not the structure data ID -
383 if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
391 StructureFile pdb = null;
392 boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
396 if (pdbFile != null && isCIFFile(pdbFile))
398 pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr,
399 secStructServices, pdbFile, protocol);
403 pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
407 if (pdb.getId() != null && pdb.getId().trim().length() > 0
408 && AppletFormatAdapter.FILE.equals(protocol))
410 registerPDBFile(pdb.getId().trim(), pdbFile);
412 } catch (Exception ex)
414 ex.printStackTrace();
422 siftsClient = new SiftsClient(pdb);
424 } catch (SiftsException e)
426 isMapUsingSIFTs = false;
430 String targetChainId;
431 for (int s = 0; s < sequenceArray.length; s++)
433 boolean infChain = true;
434 final SequenceI seq = sequenceArray[s];
435 if (targetChainIds != null && targetChainIds[s] != null)
438 targetChainId = targetChainIds[s];
440 else if (seq.getName().indexOf("|") > -1)
442 targetChainId = seq.getName().substring(
443 seq.getName().lastIndexOf("|") + 1);
444 if (targetChainId.length() > 1)
446 if (targetChainId.trim().length() == 0)
452 // not a valid chain identifier
463 * Attempt pairwise alignment of the sequence with each chain in the PDB,
464 * and remember the highest scoring chain
467 AlignSeq maxAlignseq = null;
468 String maxChainId = " ";
469 PDBChain maxChain = null;
470 boolean first = true;
471 for (PDBChain chain : pdb.getChains())
473 if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
476 continue; // don't try to map chains don't match.
478 // TODO: correctly determine sequence type for mixed na/peptide
480 final String type = chain.isNa ? AlignSeq.DNA : AlignSeq.PEP;
481 AlignSeq as = AlignSeq.doGlobalNWAlignment(seq, chain.sequence,
484 // AlignSeq as = new AlignSeq(sequence[s], chain.sequence, type);
485 // as.calcScoreMatrix();
486 // as.traceAlignment();
488 if (first || as.maxscore > max
489 || (as.maxscore == max && chain.id.equals(targetChainId)))
495 maxChainId = chain.id;
498 if (maxChain == null)
503 if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
505 pdbFile = "INLINE" + pdb.getId();
507 ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
510 <<<<<<< Updated upstream
511 setProgressBar(null);
512 setProgressBar(MessageManager
513 .getString("status.obtaining_mapping_with_sifts"));
515 if (progress!=null) {
516 progress.setProgressBar("Obtaining mapping with SIFTS",
519 >>>>>>> Stashed changes
520 jalview.datamodel.Mapping sqmpping = maxAlignseq
521 .getMappingFromS1(false);
522 if (targetChainId != null && !targetChainId.trim().isEmpty())
524 StructureMapping siftsMapping;
527 siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
528 pdb, maxChain, sqmpping, maxAlignseq);
529 seqToStrucMapping.add(siftsMapping);
530 maxChain.makeExactMapping(maxAlignseq, seq);
531 maxChain.transferRESNUMFeatures(seq, null);
532 maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
533 } catch (SiftsException e)
535 // fall back to NW alignment
536 System.err.println(e.getMessage());
537 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
538 targetChainId, maxChain, pdb, maxAlignseq);
539 seqToStrucMapping.add(nwMapping);
544 ArrayList<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
545 for (PDBChain chain : pdb.getChains())
549 StructureMapping siftsMapping = getStructureMapping(seq,
551 chain.id, pdb, chain, sqmpping, maxAlignseq);
552 foundSiftsMappings.add(siftsMapping);
553 } catch (SiftsException e)
555 System.err.println(e.getMessage());
558 if (!foundSiftsMappings.isEmpty())
560 seqToStrucMapping.addAll(foundSiftsMappings);
561 maxChain.makeExactMapping(maxAlignseq, seq);
562 maxChain.transferRESNUMFeatures(seq, null);
563 maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
568 StructureMapping nwMapping = getNWMappings(seq, pdbFile,
569 maxChainId, maxChain, pdb, maxAlignseq);
570 seqToStrucMapping.add(nwMapping);
576 <<<<<<< Updated upstream
577 setProgressBar(null);
578 setProgressBar(MessageManager
579 .getString("status.obtaining_mapping_with_nw_alignment"));
581 if (progress != null)
583 progress.setProgressBar("Obtaining mapping with NW alignment",
586 >>>>>>> Stashed changes
587 seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId,
588 maxChain, pdb, maxAlignseq));
590 if (forStructureView)
592 mappings.addAll(seqToStrucMapping);
594 if (progress != null)
596 progress.setProgressBar(null, progressSessionId);
602 private boolean isCIFFile(String filename)
604 String fileExt = filename.substring(filename.lastIndexOf(".") + 1,
606 return "cif".equalsIgnoreCase(fileExt);
609 private StructureMapping getStructureMapping(SequenceI seq,
610 String pdbFile, String targetChainId, StructureFile pdb,
611 PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
612 AlignSeq maxAlignseq) throws SiftsException
614 StructureMapping curChainMapping = siftsClient
615 .getSiftsStructureMapping(seq, pdbFile, targetChainId);
618 PDBChain chain = pdb.findChain(targetChainId);
621 chain.transferResidueAnnotation(curChainMapping, sqmpping);
623 } catch (Exception e)
627 return curChainMapping;
630 private StructureMapping getNWMappings(SequenceI seq,
632 String maxChainId, PDBChain maxChain, StructureFile pdb,
633 AlignSeq maxAlignseq)
635 final StringBuilder mappingDetails = new StringBuilder(128);
636 mappingDetails.append(NEWLINE).append(
637 "Sequence \u27f7 Structure mapping details");
638 mappingDetails.append(NEWLINE);
640 .append("Method: inferred with Needleman & Wunsch alignment");
641 mappingDetails.append(NEWLINE).append("PDB Sequence is :")
642 .append(NEWLINE).append("Sequence = ")
643 .append(maxChain.sequence.getSequenceAsString());
644 mappingDetails.append(NEWLINE).append("No of residues = ")
645 .append(maxChain.residues.size()).append(NEWLINE)
647 PrintStream ps = new PrintStream(System.out)
650 public void print(String x)
652 mappingDetails.append(x);
656 public void println()
658 mappingDetails.append(NEWLINE);
662 maxAlignseq.printAlignment(ps);
664 mappingDetails.append(NEWLINE).append("PDB start/end ");
665 mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
667 mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
668 mappingDetails.append(NEWLINE).append("SEQ start/end ");
669 mappingDetails.append(
670 String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
672 mappingDetails.append(String.valueOf(maxAlignseq.seq1end
673 + (seq.getStart() - 1)));
674 mappingDetails.append(NEWLINE);
675 maxChain.makeExactMapping(maxAlignseq, seq);
676 jalview.datamodel.Mapping sqmpping = maxAlignseq
677 .getMappingFromS1(false);
678 maxChain.transferRESNUMFeatures(seq, null);
680 HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
687 Atom tmp = maxChain.atoms.elementAt(index);
688 if ((resNum != tmp.resNumber || insCode != tmp.insCode)
689 && tmp.alignmentMapping != -1)
691 resNum = tmp.resNumber;
692 insCode = tmp.insCode;
693 if (tmp.alignmentMapping >= -1)
695 mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
701 } while (index < maxChain.atoms.size());
703 StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
704 pdb.getId(), maxChainId, mapping, mappingDetails.toString());
705 maxChain.transferResidueAnnotation(nwMapping, sqmpping);
709 public void removeStructureViewerListener(Object svl, String[] pdbfiles)
711 listeners.removeElement(svl);
712 if (svl instanceof SequenceListener)
714 for (int i = 0; i < listeners.size(); i++)
716 if (listeners.elementAt(i) instanceof StructureListener)
718 ((StructureListener) listeners.elementAt(i))
719 .releaseReferences(svl);
724 if (pdbfiles == null)
730 * Remove mappings to the closed listener's PDB files, but first check if
731 * another listener is still interested
733 List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
735 StructureListener sl;
736 for (int i = 0; i < listeners.size(); i++)
738 if (listeners.elementAt(i) instanceof StructureListener)
740 sl = (StructureListener) listeners.elementAt(i);
741 for (String pdbfile : sl.getPdbFile())
743 pdbs.remove(pdbfile);
749 * Rebuild the mappings set, retaining only those which are for 'other' PDB
754 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
755 for (StructureMapping sm : mappings)
757 if (!pdbs.contains(sm.pdbfile))
768 * Propagate mouseover of a single position in a structure
774 public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
776 AtomSpec atomSpec = new AtomSpec(pdbfile, chain, pdbResNum, 0);
777 List<AtomSpec> atoms = Collections.singletonList(atomSpec);
778 mouseOverStructure(atoms);
782 * Propagate mouseover or selection of multiple positions in a structure
786 public void mouseOverStructure(List<AtomSpec> atoms)
788 if (listeners == null)
790 // old or prematurely sent event
793 boolean hasSequenceListener = false;
794 for (int i = 0; i < listeners.size(); i++)
796 if (listeners.elementAt(i) instanceof SequenceListener)
798 hasSequenceListener = true;
801 if (!hasSequenceListener)
806 SearchResults results = new SearchResults();
807 for (AtomSpec atom : atoms)
809 SequenceI lastseq = null;
811 for (StructureMapping sm : mappings)
813 if (sm.pdbfile.equals(atom.getPdbFile())
814 && sm.pdbchain.equals(atom.getChain()))
816 int indexpos = sm.getSeqPos(atom.getPdbResNum());
817 if (lastipos != indexpos && lastseq != sm.sequence)
819 results.addResult(sm.sequence, indexpos, indexpos);
821 lastseq = sm.sequence;
822 // construct highlighted sequence list
823 for (AlignedCodonFrame acf : seqmappings)
825 acf.markMappedRegion(sm.sequence, indexpos, results);
831 for (Object li : listeners)
833 if (li instanceof SequenceListener)
835 ((SequenceListener) li).highlightSequence(results);
841 * highlight regions associated with a position (indexpos) in seq
844 * the sequence that the mouse over occurred on
846 * the absolute position being mouseovered in seq (0 to seq.length())
848 * the sequence position (if -1, seq.findPosition is called to
849 * resolve the residue number)
851 public void mouseOverSequence(SequenceI seq, int indexpos, int seqPos,
854 boolean hasSequenceListeners = handlingVamsasMo
855 || !seqmappings.isEmpty();
856 SearchResults results = null;
859 seqPos = seq.findPosition(indexpos);
861 for (int i = 0; i < listeners.size(); i++)
863 Object listener = listeners.elementAt(i);
864 if (listener == source)
866 // TODO listener (e.g. SeqPanel) is never == source (AlignViewport)
867 // Temporary fudge with SequenceListener.getVamsasSource()
870 if (listener instanceof StructureListener)
872 highlightStructure((StructureListener) listener, seq, seqPos);
876 if (listener instanceof SequenceListener)
878 final SequenceListener seqListener = (SequenceListener) listener;
879 if (hasSequenceListeners
880 && seqListener.getVamsasSource() != source)
882 if (relaySeqMappings)
886 results = MappingUtils.buildSearchResults(seq, seqPos,
889 if (handlingVamsasMo)
891 results.addResult(seq, seqPos, seqPos);
894 if (!results.isEmpty())
896 seqListener.highlightSequence(results);
901 else if (listener instanceof VamsasListener && !handlingVamsasMo)
903 ((VamsasListener) listener).mouseOverSequence(seq, indexpos,
906 else if (listener instanceof SecondaryStructureListener)
908 ((SecondaryStructureListener) listener).mouseOverSequence(seq,
916 * Send suitable messages to a StructureListener to highlight atoms
917 * corresponding to the given sequence position(s)
923 public void highlightStructure(StructureListener sl, SequenceI seq,
926 if (!sl.isListeningFor(seq))
931 List<AtomSpec> atoms = new ArrayList<AtomSpec>();
932 for (StructureMapping sm : mappings)
934 if (sm.sequence == seq
935 || sm.sequence == seq.getDatasetSequence()
936 || (sm.sequence.getDatasetSequence() != null && sm.sequence
937 .getDatasetSequence() == seq.getDatasetSequence()))
939 for (int index : positions)
941 atomNo = sm.getAtomNum(index);
945 atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
946 .getPDBResNum(index), atomNo));
951 sl.highlightAtoms(atoms);
955 * true if a mouse over event from an external (ie Vamsas) source is being
958 boolean handlingVamsasMo = false;
963 * as mouseOverSequence but only route event to SequenceListeners
967 * in an alignment sequence
969 public void mouseOverVamsasSequence(SequenceI sequenceI, int position,
972 handlingVamsasMo = true;
973 long msg = sequenceI.hashCode() * (1 + position);
977 mouseOverSequence(sequenceI, position, -1, source);
979 handlingVamsasMo = false;
982 public Annotation[] colourSequenceFromStructure(SequenceI seq,
986 // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
987 // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
989 * Annotation [] annotations = new Annotation[seq.getLength()];
991 * StructureListener sl; int atomNo = 0; for (int i = 0; i <
992 * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
993 * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
995 * for (int j = 0; j < mappings.length; j++) {
997 * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid)
998 * && mappings[j].pdbfile.equals(sl.getPdbFile())) {
999 * System.out.println(pdbid+" "+mappings[j].getPdbId() +"
1000 * "+mappings[j].pdbfile);
1002 * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
1003 * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
1005 * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
1006 * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
1007 * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
1008 * mappings[j].pdbfile); }
1010 * annotations[index] = new Annotation("X",null,' ',0,col); } return
1011 * annotations; } } } }
1013 * return annotations;
1017 public void structureSelectionChanged()
1021 public void sequenceSelectionChanged()
1025 public void sequenceColoursChanged(Object source)
1027 StructureListener sl;
1028 for (int i = 0; i < listeners.size(); i++)
1030 if (listeners.elementAt(i) instanceof StructureListener)
1032 sl = (StructureListener) listeners.elementAt(i);
1033 sl.updateColours(source);
1038 public StructureMapping[] getMapping(String pdbfile)
1040 List<StructureMapping> tmp = new ArrayList<StructureMapping>();
1041 for (StructureMapping sm : mappings)
1043 if (sm.pdbfile.equals(pdbfile))
1048 return tmp.toArray(new StructureMapping[tmp.size()]);
1052 * Returns a readable description of all mappings for the given pdbfile to any
1053 * of the given sequences
1059 public String printMappings(String pdbfile, List<SequenceI> seqs)
1061 if (pdbfile == null || seqs == null || seqs.isEmpty())
1066 StringBuilder sb = new StringBuilder(64);
1067 for (StructureMapping sm : mappings)
1069 if (sm.pdbfile.equals(pdbfile) && seqs.contains(sm.sequence))
1071 sb.append(sm.mappingDetails);
1073 // separator makes it easier to read multiple mappings
1074 sb.append("=====================");
1080 return sb.toString();
1084 * Remove the given mapping
1088 public void deregisterMapping(AlignedCodonFrame acf)
1092 boolean removed = seqmappings.remove(acf);
1093 if (removed && seqmappings.isEmpty())
1095 System.out.println("All mappings removed");
1101 * Add each of the given codonFrames to the stored set, if not aready present.
1105 public void registerMappings(List<AlignedCodonFrame> mappings)
1107 if (mappings != null)
1109 for (AlignedCodonFrame acf : mappings)
1111 registerMapping(acf);
1117 * Add the given mapping to the stored set, unless already stored.
1119 public void registerMapping(AlignedCodonFrame acf)
1123 if (!seqmappings.contains(acf))
1125 seqmappings.add(acf);
1131 * Resets this object to its initial state by removing all registered
1132 * listeners, codon mappings, PDB file mappings
1134 public void resetAll()
1136 if (mappings != null)
1140 if (seqmappings != null)
1142 seqmappings.clear();
1144 if (sel_listeners != null)
1146 sel_listeners.clear();
1148 if (listeners != null)
1152 if (commandListeners != null)
1154 commandListeners.clear();
1156 if (view_listeners != null)
1158 view_listeners.clear();
1160 if (pdbFileNameId != null)
1162 pdbFileNameId.clear();
1164 if (pdbIdFileName != null)
1166 pdbIdFileName.clear();
1170 public void addSelectionListener(SelectionListener selecter)
1172 if (!sel_listeners.contains(selecter))
1174 sel_listeners.add(selecter);
1178 public void removeSelectionListener(SelectionListener toremove)
1180 if (sel_listeners.contains(toremove))
1182 sel_listeners.remove(toremove);
1186 public synchronized void sendSelection(
1187 jalview.datamodel.SequenceGroup selection,
1188 jalview.datamodel.ColumnSelection colsel, SelectionSource source)
1190 for (SelectionListener slis : sel_listeners)
1194 slis.selection(selection, colsel, source);
1199 Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
1201 public synchronized void sendViewPosition(
1202 jalview.api.AlignmentViewPanel source, int startRes, int endRes,
1203 int startSeq, int endSeq)
1206 if (view_listeners != null && view_listeners.size() > 0)
1208 Enumeration<AlignmentViewPanelListener> listeners = view_listeners
1210 while (listeners.hasMoreElements())
1212 AlignmentViewPanelListener slis = listeners.nextElement();
1215 slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
1223 * release all references associated with this manager provider
1225 * @param jalviewLite
1227 public static void release(StructureSelectionManagerProvider jalviewLite)
1229 // synchronized (instances)
1231 if (instances == null)
1235 StructureSelectionManager mnger = (instances.get(jalviewLite));
1238 instances.remove(jalviewLite);
1242 } catch (Throwable x)
1249 public void registerPDBEntry(PDBEntry pdbentry)
1251 if (pdbentry.getFile() != null
1252 && pdbentry.getFile().trim().length() > 0)
1254 registerPDBFile(pdbentry.getId(), pdbentry.getFile());
1258 public void addCommandListener(CommandListener cl)
1260 if (!commandListeners.contains(cl))
1262 commandListeners.add(cl);
1266 public boolean hasCommandListener(CommandListener cl)
1268 return this.commandListeners.contains(cl);
1271 public boolean removeCommandListener(CommandListener l)
1273 return commandListeners.remove(l);
1277 * Forward a command to any command listeners (except for the command's
1281 * the command to be broadcast (in its form after being performed)
1283 * if true, the command was being 'undone'
1286 public void commandPerformed(CommandI command, boolean undo,
1287 VamsasSource source)
1289 for (CommandListener listener : commandListeners)
1291 listener.mirrorCommand(command, undo, this, source);
1296 * Returns a new CommandI representing the given command as mapped to the
1297 * given sequences. If no mapping could be made, or the command is not of a
1298 * mappable kind, returns null.
1306 public CommandI mapCommand(CommandI command, boolean undo,
1307 final AlignmentI mapTo, char gapChar)
1309 if (command instanceof EditCommand)
1311 return MappingUtils.mapEditCommand((EditCommand) command, undo,
1312 mapTo, gapChar, seqmappings);
1314 else if (command instanceof OrderCommand)
1316 return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
1317 mapTo, seqmappings);
1322 public List<AlignedCodonFrame> getSequenceMappings()