<td>defaultColour</td>
<td> <em>One of: </em><br>
Clustal, Blosum62, % Identity, Hydrophobic, Zappo, Taylor, Helix
- Propensity, Strand Propensity, Turn Propensity, Buried Index, Nucleotide, T-Coffee Scores, RNA Helices</td>
+ Propensity, Strand Propensity, Turn Propensity, Buried Index, Nucleotide, Purine/Pyrimidine, T-Coffee Scores, RNA Helices</td>
<td>Default is no colour.</td>
</tr>
<tr>
ST-TURN-IIL blue|255,0,255|absolute|20.0|95.0|below|66.0
-GAMMA-TURN-CLASSIC red|0,255,255|20.0|95.0|below|66.0
+GAMMA-TURN-CLASSIC lightGray|0,255,255|20.0|95.0|below|66.0
BETA-TURN-IR 9a6a94
BETA-TURN-IL d6a6ca
BETA-BULGE 1dc451
--- /dev/null
+import java.awt.Color;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceCollectionI;
+
+/*
+ * Example script that registers two new alignment colour schemes
+ */
+
+/*
+ * Closure that defines a colour scheme where consensus residues are pink,
+ * other residues are red in odd columns and blue in even columns, and
+ * gaps are yellow
+ */
+def candy
+candy = { ->
+ [
+ /*
+ * name shown in the colour menu
+ */
+ getSchemeName: { -> 'candy' },
+
+ /*
+ * to make a new instance for each alignment view
+ */
+ getInstance: { AnnotatedCollectionI coll, Map<SequenceI, SequenceCollectionI> map -> candy() },
+
+ /*
+ * method only needed if colour scheme has to recalculate
+ * values when an alignment is modified
+ */
+ alignmentChanged: { AnnotatedCollectionI coll, Map<SequenceI, SequenceCollectionI> map -> },
+
+ /*
+ * determine colour for a residue at an aligned position of a
+ * sequence, given consensus residue(s) for the column and the
+ * consensus percentage identity score for the column
+ */
+ findColour: { char res, int col, SequenceI seq, String consensus, float pid ->
+ if (res == ' ' || res == '-' || res == '.')
+ {
+ Color.yellow
+ } else if (consensus.contains(String.valueOf(res)))
+ {
+ Color.pink
+ } else if (col % 2 == 0)
+ {
+ Color.blue
+ } else
+ {
+ Color.red
+ }
+ },
+
+ /*
+ * true means applicable to nucleotide or peptide data
+ */
+ isApplicableTo: {AnnotatedCollectionI coll -> true},
+
+ /*
+ * simple colour schemes are those that depend on the residue
+ * only (these are also available to colour structure viewers)
+ */
+ isSimple: { false }
+ ] as ColourSchemeI
+}
+
+/*
+ * A closure that defines a colour scheme graduated
+ * (approximately) by amino acid weight
+ * here from lightest (G) Blue, to heaviest (W) Red
+ */
+def makeColour = { weight ->
+ minWeight = 75 // Glycine
+ maxWeight = 204 // Tryptophan
+ int i = 255 * (weight - minWeight) / (maxWeight - minWeight);
+ new Color(i, 0, 255-i);
+}
+def byWeight
+byWeight = { ->
+ [
+ getSchemeName: { 'By Weight' },
+ // this colour scheme is peptide-specific:
+ isApplicableTo: { coll -> !coll.isNucleotide() },
+ alignmentChanged: { coll, map -> },
+ getInstance: { coll, map -> byWeight() },
+ isSimple: { true },
+ findColour: {res, col, seq, consensus, pid ->
+ switch (res) {
+ case ' ':
+ case '-':
+ case '.':
+ Color.white
+ break
+ case 'A':
+ makeColour(89)
+ break
+ case 'R':
+ makeColour(174)
+ break
+ case 'N':
+ case 'D':
+ case 'B':
+ case 'I':
+ case 'L':
+ makeColour(132)
+ break
+ case 'C':
+ makeColour(121)
+ break
+ case 'Q':
+ case 'E':
+ case 'Z':
+ case 'K':
+ case 'M':
+ makeColour(146)
+ break
+ case 'G':
+ makeColour(75)
+ break
+ case 'H':
+ makeColour(155)
+ break
+ case 'F':
+ makeColour(165)
+ break
+ case 'P':
+ makeColour(115)
+ break
+ case 'S':
+ makeColour(105)
+ break
+ case 'T':
+ makeColour(119)
+ break
+ case 'W':
+ makeColour(204)
+ break
+ case 'Y':
+ makeColour(181)
+ break
+ case 'V':
+ makeColour(117)
+ break
+ default:
+ makeColour(150)
+ }
+ }
+ ] as ColourSchemeI
+}
+
+ColourSchemes.instance.registerColourScheme(candy())
+ColourSchemes.instance.registerColourScheme(byWeight())
--- /dev/null
+import jalview.datamodel.AlignmentI
+import jalview.datamodel.SequenceI
+import jalview.datamodel.Sequence
+import jalview.io.FileFormatI
+import jalview.io.FileFormats
+import jalview.io.FileParse
+import jalview.io.AlignFile
+
+/*
+ * Example script that registers a new alignment file format
+ * consisting of lines like
+ * !I=<sequence id>
+ * !S=<sequence string>
+ */
+
+/*
+ * A parser class to read or write the format
+ */
+class MyParser extends AlignFile
+{
+ /*
+ * Constructor for reading a file; the superclass
+ * constructor will call the parse() method
+ */
+ MyParser(FileParse src)
+ {
+ super(src)
+ }
+
+ /*
+ * Constructor for writing out an alignment
+ */
+ MyParser(AlignmentI al)
+ {
+ }
+
+ /*
+ * Parse a formatted data file (with no error checking!)
+ */
+ void parse()
+ {
+ String id
+ String line
+ while ((line = nextLine()) != null)
+ {
+ if (line.startsWith('!I='))
+ {
+ int pos = line.indexOf('/')
+ id = line.substring(3, pos == -1 ? line.length() : pos)
+ } else if (line.startsWith('!S='))
+ {
+ String seq = line.substring(3)
+ addSequence(new Sequence(id, seq))
+ }
+ }
+ }
+
+ /*
+ * Print the formatted sequences
+ * (addSuffix always defaults to true as no user preference for it)
+ */
+ String print(SequenceI[] seqs, boolean addSuffix)
+ {
+ StringBuilder sb = new StringBuilder()
+ for (SequenceI seq : seqs)
+ {
+ sb.append('!I=').append(seq.getDisplayId(addSuffix)).append('\n')
+ sb.append('!S=').append(seq.getSequenceAsString()).append('\n')
+ }
+ sb.toString()
+ }
+}
+
+/*
+ * A closure that defines the 'Groovy example' file format,
+ * delegating to MyParser for reading and writing
+ */
+def myFormat = { ->
+ [
+ getName: { -> 'Groovy example' },
+
+ toString: { -> getName() },
+
+ getExtensions: { -> 'grv' },
+
+ getReader: { FileParse source -> new MyParser(source) },
+
+ getWriter: { AlignmentI al -> new MyParser(al) },
+
+ isReadable: { -> true },
+
+ isWritable: { -> true },
+
+ isTextFormat: { -> true },
+
+ isStructureFile: { -> false },
+
+ isComplexAlignFile: { -> false },
+
+ ] as FileFormatI
+}
+
+/*
+ * Register the file format. After running this script in Jalview's
+ * Groovy console, the new format should be shown in open file,
+ * save file, and output to textbox menu options.
+ */
+FileFormats.instance.registerFileFormat(myFormat())
<mapID target="uniprotfetcher" url="html/features/uniprotsequencefetcher.html" />
+ <mapID target="urllinks" url="html/webServices/urllinks.html" />
+ <mapID target="linksprefs" url="html/features/Preferences.html#links" />
+
<mapID target="backIcon" url="icons/back.png" />
<mapID target="forwardIcon" url="icons/forward.png" />
<mapID target="homeIcon" url="icons/Home.png" />
<tocitem text="Chimera Viewer" target="chimera" />
</tocitem>
<tocitem text="Viewing RNA structures" target="varna" expand="false"/>
+ <tocitem text="Opening URLs from Jalview" target="urllinks" expand="true">
+ <tocitem text="Configuring URL Links" target="urllinkspref" />
+ </tocitem>
<tocitem text="VAMSAS Data Exchange" target="vamsas">
<!-- what can Jalview share with other apps -->
<!-- what other apps exist -->
is assigned a colour if the amino acid profile of the alignment at
that position meets some minimum criteria specific for the residue
type.</p>
- <p>The table below gives these criteria as clauses: {+X%,xx,y},
- where X is the minimum percentage presence for any of the xx (or y)
- residue types.</p>
+ <p>The table below gives these criteria as clauses: {>X%,xx,y},
+ where X is the threshold percentage presence for any of the xx (or y)
+ residue types.
+ <br>For example, K or R is coloured red if the column includes more than 60% K or R (combined), or more than 80% of either K or R or Q (individually).</p>
<div align="center">
<p> </p>
<table border="1">
<tr>
<td><table border="1">
<tr>
+ <th>Category</th>
+ <th>Colour</th>
<th>Residue at position</th>
- <th>Applied Colour</th>
- <th>{ Threshhold, Residue group }</th>
+ <th>{ Threshold, Residue group }</th>
</tr>
<tr>
+ <td rowspan="2">Hydrophobic</td>
+ <td rowspan="2" bgcolor="#80a0f0">BLUE</td>
<td>A,I,L,M,F,W,V</td>
- <td bgcolor="#80a0f0">BLUE</td>
- <td>{+60%, WLVIMAFCHP}</td>
+ <td>{>60%, WLVIMAFCHP}</td>
</tr>
<tr>
- <td>R,K</td>
+ <td>C</td>
+ <td>{>60%, WLVIMAFCHP}</td>
+ </tr>
+ <tr>
+ <td>Positive charge</td>
<td bgcolor="#f01505">RED</td>
- <td>{+60%,KR},{+80%, K,R,Q}</td>
+ <td>K,R</td>
+ <td>{>60%,KR},{>80%, K,R,Q}</td>
</tr>
<tr>
- <td>N</td>
- <td bgcolor="#15c015">GREEN</td>
- <td>{+50%, N}, {+85%, N,Y}</td>
+ <td rowspan="2">Negative charge</td>
+ <td rowspan="2" bgcolor="#c048c0">MAGENTA</td>
+ <td>E</td>
+ <td>{>60%,KR},{>50%,QE},{>85%,E,Q,D}</td>
</tr>
<tr>
- <td>C</td>
- <td bgcolor="#80a0f0">BLUE</td>
- <td>{+60%, WLVIMAFCHP}</td>
+ <td>D</td>
+ <td>{>60%,KR}, {>85%, K,R,Q}, {>50%,ED}</td>
</tr>
<tr>
- <td>C</td>
- <td bgcolor="#f08080">PINK</td>
- <td>{100%, C}</td>
+ <td rowspan="3">Polar</td>
+ <td rowspan="3" bgcolor="#15c015">GREEN</td>
+ <td>N</td>
+ <td>{>50%, N}, {>85%, N,Y}</td>
</tr>
<tr>
<td>Q</td>
- <td bgcolor="#15c015">GREEN</td>
- <td>{+60%,KR},{+50%,QE},{+85%,Q,E,K,R}</td>
+ <td>{>60%,KR},{>50%,QE},{>85%,Q,E,K,R}</td>
</tr>
<tr>
- <td>E</td>
- <td bgcolor="#c048c0">MAGENTA</td>
- <td>{+60%,KR},{+50%,QE},{+85%,E,Q,D}</td>
+ <td>S,T</td>
+ <td>{>60%, WLVIMAFCHP}, {>50%, TS}, {>85%,S,T}</td>
</tr>
<tr>
- <td>D</td>
- <td bgcolor="#c048c0">MAGENTA</td>
- <td>{+60%,KR}, {+85%, K,R,Q}, {+50%,ED}</td>
+ <td>Cysteines</td>
+ <td bgcolor="#f08080">PINK</td>
+ <td>C</td>
+ <td>{>85%, C}</td>
</tr>
<tr>
- <td>G</td>
+ <td>Glycines</td>
<td bgcolor="#f09048">ORANGE</td>
- <td>{+0%, G}</td>
+ <td>G</td>
+ <td>{>0%, G}</td>
</tr>
<tr>
- <td>H,Y</td>
- <td bgcolor="#15a4a4">CYAN</td>
- <td>{+60%, WLVIMAFCHP}, {+85%,
- W,Y,A,C,P,Q,F,H,I,L,M,V}</td>
+ <td>Prolines</td>
+ <td bgcolor="#c0c000">YELLOW</td>
+ <td>P</td>
+ <td>{>0%, P}</td>
</tr>
<tr>
- <td>P</td>
- <td bgcolor="#c0c000">YELLOW</td>
- <td>{+0%, P}</td>
+ <td>Aromatic</td>
+ <td bgcolor="#15a4a4">CYAN</td>
+ <td>H,Y</td>
+ <td>{>60%, WLVIMAFCHP}, {>85%,
+ W,Y,A,C,P,Q,F,H,I,L,M,V}</td>
</tr>
<tr>
- <td>S,T</td>
- <td bgcolor="#15c015">GREEN</td>
- <td>{+60%, WLVIMAFCHP}, {+50%, TS}, {+85%,S,T}</td>
+ <td>Unconserved</td>
+ <td>WHITE</td>
+ <td>any / gap</td>
+ <td>If none of the above criteria are met</td>
</tr>
</table></td>
</tr>
The <strong>Case Sensitive</strong> option allows you to choose
distinct colours for upper and lower case residue codes.
<p>
+ The <strong>Lower Case Colour</strong> option allows you to apply a selected colour
+ to all lower case residues.
+ <p>
Click <strong>Apply</strong> or <strong>OK</strong> to set your new
colours on the active alignment window.<br /> Click <strong>Cancel</strong>
to undo your changes if you pressed the <strong>Apply</strong>
and displaying structure information.
</li>
<li>The <a href="#connections"><strong>"Connections"</strong>
- Preferences</a> tab allows you to change the links made from Jalview
- to your default web browser.
+ Preferences</a> tab allows you to configure Jalview's internet
+ settings and specify your default web browser.
+ </li>
+ <li>The <a href="#links"><strong>"Links"</strong>
+ Preferences</a> tab shows the currently configured <em>URL
+ Links</em> shown in the <strong>Link</strong> submenu in the Sequence
+ ID popup menu.
</li>
<li>The <a href="#output"><strong>"Output"</strong>
Preferences</a> tab contains settings affecting the export of
Preferences tab</strong></a>
</p>
<p>
- <em>URL Link From Sequence ID</em><br> These definitions are
- used to generate URLs from a sequence's ID or database cross
- references. Read more about <a
- href="../webServices/urllinks.html#urllinks">configuring
- URL links here</a>.
- </p>
- <p>
<em>Default Browser (Unix)</em><br> Its difficult in Java to
detect the default web browser for Unix users. If Jalview can't find
your default web browser, enter the name or full path to your web
statement</a> for more information.
</p>
<p>
+ <a name="links"><strong>The "Links" Preferences
+ tab</strong></a>
+ </p>
+ <p>
+ This panel shows a table, and two sections - <em>Edit</em> and <em>Filter</em>.
+ The table shows the available URL link definitions (consisting of a
+ database, Name, and URL template string), a checkbox <em>In
+ Menu</em> which indicates if the link is enabled, and <em>Double
+ Click</em> which marks the link that will be opened if a sequence's ID
+ is double clicked. The table can be sorted by clicking on the column headers.
+ </p>
+ <p><em>Edit Links</em><br /> This section contains three buttons,
+ <em>New</em>, <em>Edit</em> and <em>Delete</em>, which allow you to
+ create, modify and remove user-defined URL links from the Sequence
+ ID's links submenu.
+ </p>
+ <p>
+ <em>Filter</em><br /> The <em>Filter text</em> box allows you to
+ quickly show rows in the table containing a particular text string.
+ The <em>Custom only</em> button limits the entries in the table to
+ just those you have configured yourself <em>via</em> the <em>Edit
+ Links</em> buttons. Press <em>Show all</em> to clear any filters.
+ <p>
+ <a href="../webServices/urllinks.html#urllinks">Read more about configuring
+ URL links.</a>
+ </p>
+ <p>
<a name="output"><strong>Output Preferences tab</strong></a>
</p>
<p>
and PDB file association (if available). The Jalview id/start-end
option is ignored if Modeller output is selected.
<p>
- <a name="editing"><strong>Editing Preferences tab</strong></a>
+ <a name="editing"><strong>e"Editinge" Preferences tab</strong></a>
</p>
<p>There are currently three options available which can be
selected / deselected.</p>
1QCF ----------6878742356789999999999889
cons 00100000006877641356789999999999889
</pre>
-
+<table border="1">
+<tr><th>Score</th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th></tr>
+<tr>
+<td>RGB colour</td>
+<td bgcolor="#6666FF">102, 102, 255</td>
+<td bgcolor="#00FF00">0, 255, 0</td>
+<td bgcolor="#66FF00">102, 255, 0</td>
+<td bgcolor="#CCFF00">204, 255, 0</td>
+<td bgcolor="#FFFF00">255, 255, 0</td>
+<td bgcolor="#FFCC00">255, 204, 0</td>
+<td bgcolor="#FF9900">255, 153, 0</td>
+<td bgcolor="#FF6600">255, 102, 0</td>
+<td bgcolor="#FF3300">255, 51, 0</td>
+<td bgcolor="#FF2000">255, 34, 0</td></tr>
+</table>
</body>
</html>
</head>
<body>
<p>
- <p>
<strong>Opening URLs from Jalview</strong><br> Both the applet
and the desktop application are able to open URLs as 'popups' in
- your web browser. <br> Double-clicking on the ID of a sequence
- will open the first URL that can be generated from its sequence ID.
+ your web browser.</p>
+ <p> Double-clicking on the ID of a sequence
+ will open whichever URL is selected for 'popups' in the <strong>"Links"</strong> tab of the <a
+ href="../features/preferences.html#links">Jalview desktop
+ preferences</a>.
This is by default the EMBL-EBI site, but you can easily configure your own <a
href="#urllinks">sequence URL links</a>.
</p>
<p>
- Other links for a sequence either derived from any other configured
+ Other links for a sequence, either derived from any other configured
URL links, or imported from the sequence's annotation, are accessed
by right clicking to open the sequence pop-up menu, and selecting
from the <em>Links</em> submenu.
</p>
<p>
<strong><a name="urllinks">Configuring URL Links</a></strong> <br>URL
- links are defined in the "Connections" tab of the <a
- href="../features/preferences.html">Jalview desktop
+ links are defined in the "Links" tab of the <a
+ href="../features/preferences.html#links">Jalview desktop
preferences</a>, or specified as <a
href="http://www.jalview.org/examples/appletParameters.html#parameters">applet
- parameters</a>. <br> By default the item "EMBL-EBI Search" is added
- to this link menu. This link will show a web page in your default
- browser with the selected sequence id as part of the URL.<br>
- In the preferences dialog box, click <strong>new</strong> to add a
- new link, and <strong>edit</strong> to modify an existing link, or <strong>delete</strong>
- to remove it.<br> You can name the link, this will be displayed
- on a new menu item under the "Link" menu when you right
- click on a sequence id. <br> The URL string must contain a
- token that can be replaced with a sequence ID or DB accession ID. The simplest token is
- "$SEQUENCE_ID$", which will be replaced by the chosen
- sequence id when you click on it.
+ parameters</a>.</p>
+ <p>
+ <em>Default Link Settings</em><br /> The "EMBL-EBI Search"
+ link is the default link shown in the "Link" submenu, and
+ opened when double-clicking on a sequence ID. When clicked, this
+ link will show a web page in your default browser with the selected
+ sequence ID as part of the URL.
+ </p>
+ <p>
+ <em>Adding additional links</em><br /> You can configure your own
+ links via the Jalview <a href="../features/preferences.html#links"><strong>Preferences</strong></a>
+ dialog. Jalview also provides persistent URLs for many common
+ bioinformatics databases. These links are downloaded by Jalview from
+ the <em>identifiers.org</em> website, and the names and URLs are not
+ user editable.
</p>
<p>
- eg.<br> UniRef100 =
- http://www.ebi.uniprot.org/uniprot-srv/uniRefView.do?proteinAc=$SEQUENCE_ID$&library=uniref100<br>
- Swissprot = http://www.expasy.org/uniprot/$SEQUENCE_ID$ <br> <br>
+ <em>Creating your own URL link</em> URL links are specified as a
+ template containing special tokens that Jalview will replace with
+ the Sequence ID or Database Accession of the sequence when you
+ double click on its ID or open it's <strong>Link</strong> submenu.
+ Link URL templates must contain at least one token.
+ </p>
+ <em>eg.</em><pre> UniRef100 =
+ http://www.ebi.uniprot.org/uniprot-srv/uniRefView.do?proteinAc=$SEQUENCE_ID$&library=uniref100<br/>
+ Swissprot = http://www.expasy.org/uniprot/$SEQUENCE_ID$ <br> </pre>
+ <p>
Links will also be made for any database cross references associated
with the sequence where the database name exactly matches a URL link
name. In this case, the $DB_ACCESSION$ string will be replaced with
<p>
<strong>Regular Expression Substitution</strong><br> A url may
contain a string of the form $SEQUENCE_ID=/<em>regular
- expression</em>/=$ or $DB_ACCESSION=/<em>regular expression</em>/=$.
- In this case, the regular expression will be
- applied to the full sequence ID or DB accession ID string and the resulting match will
+ expression</em>/=$ or $DB_ACCESSION=/<em>regular expression</em>/=$. In
+ this case, the regular expression will be applied to the full
+ sequence ID or DB accession ID string and the resulting match will
be inserted into the URL. Groups of parentheses can be used to
specify which regions of the regular expression will be used to
generate the URL:
+
<ul>
<li>Each top level parenthesis will yield a URL containing the
text matched within that parenthesis.</li>
<li>Regions matching sub-parentheses within a top-level
parenthesis will be concatenated to form the text inserted into
the URL for the top-level parenthesis.</li>
- <em>Please Note:
- <ul>
- <li>The regular expressions supported by Jalview are those
- provided by the <a href="http://www.javaregex.com">Stevesoft
- javaregex package</a>.
- </li>
- <li>Some characters must be escaped when specifying them as
- a match within a regular expression.</li>
- </ul> <br> Many Thanks to Bernd Brandt of the Free University of
- Amsterdam for testing this new regular-expression expansion
- feature!
- </em>
- <em>
</ul>
- </p>
- </p>
+ <em>Please Note:</em>
+ <ul>
+ <li>The regular expressions supported by Jalview are those
+ provided by the <a href="http://www.javaregex.com">Stevesoft
+ javaregex package</a>.
+ </li>
+ <li>Some characters must be escaped when specifying them as a
+ match within a regular expression.</li>
+ </ul> <br> Many Thanks to Bernd Brandt of the Free University of
+ Amsterdam for testing the regular-expression expansion feature!
</body>
</html>
action.remove = Remove
action.remove_redundancy = Remove Redundancy...
action.pairwise_alignment = Pairwise Alignment
-action.by_rna_helixes = By RNA Helices
action.user_defined = User Defined...
action.by_conservation = By Conservation
action.wrap = Wrap
label.view_flanking_regions = Show sequence data either side of the subsequences involved in this alignment
label.structures_manager = Structures Manager
label.nickname = Nickname:
-label.url = URL:
+label.url = URL
+label.url\: = URL:
label.input_file_url = Enter URL or Input File
label.select_feature = Select feature
label.name = Name
label.score_model_enhconservation = Physicochemical property conservation
label.status_bar = Status bar
label.out_to_textbox = Output to Textbox
-label.clustalx = Clustalx
+# delete Clustal - use FileFormat name instead
label.clustal = Clustal
-label.zappo = Zappo
-label.taylor = Taylor
+# label.colourScheme_<schemeName> as in JalviewColourScheme
+label.colourScheme_clustal = Clustalx
+label.colourScheme_blosum62 = BLOSUM62 Score
+label.colourScheme_%_identity = Percentage Identity
+label.colourScheme_zappo = Zappo
+label.colourScheme_taylor = Taylor
+label.colourScheme_hydrophobic = Hydrophobicity
+label.colourScheme_helix_propensity = Helix Propensity
+label.colourScheme_strand_propensity = Strand Propensity
+label.colourScheme_turn_propensity = Turn Propensity
+label.colourScheme_buried_index = Buried Index
+label.colourScheme_purine/pyrimidine = Purine/Pyrimidine
+label.colourScheme_nucleotide = Nucleotide
+label.colourScheme_t-coffee_scores = T-Coffee Scores
+label.colourScheme_rna_helices = By RNA Helices
label.blc = BLC
label.fasta = Fasta
label.msf = MSF
label.pfam = PFAM
label.pileup = Pileup
label.pir = PIR
-label.hydrophobicity = Hydrophobicity
-label.helix_propensity = Helix Propensity
-label.strand_propensity = Strand Propensity
-label.turn_propensity = Turn Propensity
-label.buried_index = Buried Index
-label.purine_pyrimidine = Purine/Pyrimidine
-label.percentage_identity = Percentage Identity
-label.blosum62 = BLOSUM62
-label.blosum62_score = BLOSUM62 Score
-label.tcoffee_scores = T-Coffee Scores
-label.average_distance_bloslum62 = Average Distance Using BLOSUM62
+label.average_distance_blosum62 = Average Distance Using BLOSUM62
label.neighbour_blosum62 = Neighbour Joining Using BLOSUM62
label.show_annotations = Show annotations
label.hide_annotations = Hide annotations
label.add_reference_annotations = Add reference annotations
label.find_tip = Search alignment, selection or sequence ids for a subsequence (ignoring gaps).<br>Accepts regular expressions - search Help for 'regex' for details.
label.colour_text = Colour Text
-label.show_non_conversed = Show nonconserved
+label.show_non_conserved = Show nonconserved
label.overview_window = Overview Window
label.none = None
label.above_identity_threshold = Above Identity Threshold
label.style = Style:
label.calculating = Calculating....
label.modify_conservation_visibility = Modify conservation visibility
-label.colour_residues_above_occurence = Colour residues above % occurence
+label.colour_residues_above_occurrence = Colour residues above % occurrence
label.set_this_label_text = set this label text
label.sequences_from = Sequences from {0}
label.successfully_loaded_file = Successfully loaded file {0}
label.vamsas_document_import_failed = Vamsas Document Import Failed
label.couldnt_locate = Couldn't locate {0}
label.url_not_found = URL not found
-label.no_link_selected = No link selected
label.new_sequence_url_link = New sequence URL link
label.cannot_edit_annotations_in_wrapped_view = Cannot edit annotations in wrapped view
label.wrapped_view_no_edit = Wrapped view - no edit
label.standard_databases = Standard Databases
label.fetch_embl_uniprot = Fetch from EMBL/EMBLCDS or Uniprot/PDB and any selected DAS sources
label.reset_min_max_colours_to_defaults = Reset min and max colours to defaults from user preferences.
-label.align_structures_using_linked_alignment_views = Align structures using {0} linked alignment views
+label.align_structures_using_linked_alignment_views = Superpose structures using {0} selected alignment view(s)
label.connect_to_session = Connect to session {0}
label.threshold_feature_display_by_score = Threshold the feature display by score.
label.threshold_feature_no_threshold = No Threshold
label.right_click_to_edit_currently_selected_parameter = Right click to edit currently selected parameter.
label.let_jmol_manage_structure_colours = Let Jmol manage structure colours
label.let_chimera_manage_structure_colours = Let Chimera manage structure colours
+label.fetch_chimera_attributes = Fetch Chimera attributes
+label.fetch_chimera_attributes_tip = Copy Chimera attribute to Jalview feature
label.marks_leaves_tree_not_associated_with_sequence = Marks leaves of tree not associated with a sequence
label.index_web_services_menu_by_host_site = Index web services in menu by the host site
label.option_want_informed_web_service_URL_cannot_be_accessed_jalview_when_starts_up = Check this option if you want to be informed<br>when a web service URL cannot be accessed by Jalview<br>when it starts up
label.structure = Structure
label.show_pdbstruct_dialog = 3D Structure Data...
label.view_rna_structure = VARNA 2D Structure
-label.clustalx_colours = Clustalx colours
-label.above_identity_percentage = Above % Identity
label.create_sequence_details_report_annotation_for = Annotation for {0}
label.sequence_details_for = Sequence Details for {0}
label.sequence_name = Sequence Name
label.pdb_file = PDB file
label.colour_with_jmol = Colour with Jmol
label.colour_with_chimera = Colour with Chimera
-label.align_structures = Align Structures
+label.superpose_structures = Superpose Structures
+error.superposition_failed = Superposition failed: {0}
+label.insufficient_residues = Not enough aligned residues ({0}) to perform superposition
label.jmol = Jmol
label.chimera = Chimera
+label.create_chimera_attributes = Write Jalview features
+label.create_chimera_attributes_tip = Set Chimera residue attributes for visible features
+label.attributes_set = {0} attribute values set on Chimera
label.sort_alignment_by_tree = Sort Alignment By Tree
label.mark_unlinked_leaves = Mark Unlinked Leaves
label.associate_leaves_with = Associate Leaves With
label.save_colour_scheme_with_unique_name_added_to_colour_menu = Save your colour scheme with a unique name and it will be added to the Colour menu
label.case_sensitive = Case Sensitive
-label.lower_case_colour = Lower Case Colour
+label.lower_case_colour = Colour All Lower Case
+label.lower_case_tip = Chosen colour applies to all lower case symbols
label.index_by_host = Index by Host
label.index_by_type = Index by Type
label.enable_jabaws_services = Enable JABAWS Services
label.points_for_params = Points for {0}
label.transformed_points_for_params = Transformed points for {0}
label.graduated_color_for_params = Graduated Feature Colour for {0}
-label.select_backgroud_colour = Select Background Colour
+label.select_background_colour = Select Background Colour
label.invalid_font = Invalid Font
label.separate_multiple_accession_ids = Enter one or more accession IDs separated by a semi-colon ";"
label.separate_multiple_query_values = Enter one or more {0}s separated by a semi-colon ";"
error.implementation_error_cannot_have_null_alignment = Implementation error: Cannot have null alignment property key
error.implementation_error_null_fileparse = Implementation error. Null FileParse in copy constructor
error.implementation_error_cannot_map_alignment_sequences = IMPLEMENTATION ERROR: Cannot map an alignment of sequences from different datasets into a single alignment in the vamsas document.
-error.implementation_error_cannot_duplicate_colour_scheme = Serious implementation error: cannot duplicate colourscheme {0}
error.implementation_error_structure_selection_manager_null = Implementation error. Structure selection manager's context is 'null'
exception.ssm_context_is_null = SSM context is null
error.idstring_seqstrings_only_one_per_sequence = idstrings and seqstrings contain one string each per sequence
exception.bad_pattern_to_regex_perl_code = bad pattern to Regex.perlCode: {0}
exception.no_stub_implementation_for_interface = There is no stub implementation for the interface: {0}
exception.cannot_set_endpoint_address_unknown_port = Cannot set Endpoint Address for Unknown Port {0}
-exception.querying_matching_opening_parenthesis_for_non_closing_parenthesis = Querying matching opening parenthesis for non-closing parenthesis character {0}
exception.mismatched_unseen_closing_char = Mismatched (unseen) closing character {0}
exception.mismatched_closing_char = Mismatched closing character {0}
exception.mismatched_opening_char = Mismatched opening character {0} at {1}
exception.application_test_npe = Application test: throwing an NullPointerException It should arrive at the console
exception.overwriting_vamsas_id_binding = Overwriting vamsas id binding
exception.overwriting_jalview_id_binding = Overwriting jalview id binding
-error.implementation_error_unknown_file_format_string = Implementation error: Unknown file format string
exception.failed_to_resolve_gzip_stream = Failed to resolve GZIP stream
exception.problem_opening_file_also_tried = Problem opening {0} (also tried {1}) : {2}
exception.problem_opening_file = Problem opening {0} : {1}
action.export_hidden_sequences = Export Hidden Sequences
action.export_features = Export Features
label.export_settings = Export Settings
-label.save_as_biojs_html = Save as BioJs HTML
label.pdb_web-service_error = PDB Web-service Error
label.structure_chooser_manual_association = Structure Chooser - Manual association
label.structure_chooser_filter_time = Structure Chooser - Filter time ({0})
label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window:
label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'.
label.do_not_display_again = Do not display this message again
+exception.url_cannot_have_miriam_id = {0} is a MIRIAM id and cannot be used as a custom url name
+exception.url_cannot_have_duplicate_id = {0} cannot be used as a label for more than one line
+label.filter = Filter text:
+action.customfilter = Custom only
+action.showall = Show All
+label.insert = Insert:
+action.seq_id = $SEQUENCE_ID$
+action.db_acc = $DB_ACCESSION$
+label.primary = Double Click
+label.inmenu = In Menu
+label.id = ID
+label.database = Database
+label.urltooltip = Only one url, which must use a sequence id, can be selected for the 'On Click' option
+label.edit_sequence_url_link = Edit sequence URL link
+warn.name_cannot_be_duplicate = User-defined URL names must be unique and cannot be MIRIAM ids
+label.invalid_name = Invalid Name !
label.output_seq_details = Output Sequence Details to list all database references
+<<<<<<< HEAD
label.phyre2_model_prediction = 3D Protein Model prediction with Phyre2
label.run_phyre2_prediction = Run Phyre2 Prediction
-status.obtaining_mapping_with_phyre2_template_alignment = Obtaining mapping with Phyre2 Template alignment
\ No newline at end of file
+status.obtaining_mapping_with_phyre2_template_alignment = Obtaining mapping with Phyre2 Template alignment
+=======
+label.urllinks = Links
+>>>>>>> develop
action.remove = Eliminar
action.remove_redundancy = Eliminar redundancia...
action.pairwise_alignment = Alineamiento de pares...
-action.by_rna_helixes = Por hélices de RNA
action.user_defined = Definido por el usuario...
action.by_conservation = Por conservación
action.wrap = Envolver
label.view_flanking_regions = Mostrar los datos de la secuencia a ambos lados de las subsecuencias implicadas en este alineamiento
label.structures_manager = Administrar estructuras
label.nickname = Sobrenombre:
-label.url = URL:
+label.url\: = URL:
+label.url = URL
label.input_file_url = Introducir URL en el fichero de entrada
label.select_feature = Seleccionar característica
label.name = Nombre
label.score_model_enhconservation = Conservación de las propiedades físico-químicas
label.status_bar = Barra de estado
label.out_to_textbox = Generar cuadro de texto
-label.clustalx = Clustalx
label.clustal = Clustal
-label.zappo = Zappo
-label.taylor = Taylor
+# label.colourScheme_<schemeName> as in JalviewColourScheme
+label.colourScheme_clustal = Clustalx
+label.colourScheme_blosum62 = Puntuación del BLOSUM62
+label.colourScheme_%_identity = Porcentaje de identidad
+label.colourScheme_zappo = Zappo
+label.colourScheme_taylor = Taylor
+label.colourScheme_hydrophobic = Hidrofobicidad
+label.colourScheme_helix_propensity = Tendencia de la hélice
+label.colourScheme_strand_propensity = Tendencia de la hebra
+label.colourScheme_turn_propensity = Tendencia de giro
+label.colourScheme_buried_index = Índice de encubrimiento
+label.colourScheme_purine/pyrimidine = Purina/Pirimidina
+label.colourScheme_nucleotide = Nucleótido
+label.colourScheme_t-coffee_scores = Puntuación del T-Coffee
+label.colourScheme_rna_helices = Por hélices de RNA
label.blc = BLC
label.fasta = Fasta
label.msf = MSF
label.pfam = PFAM
label.pileup = Pileup
label.pir = PIR
-label.hydrophobicity = Hidrofobicidad
-label.helix_propensity = Tendencia de la hélice
-label.strand_propensity = Tendencia de la hebra
-label.turn_propensity = Tendencia de giro
-label.buried_index = Índice de encubrimiento
-label.purine_pyrimidine = Purina/Pirimidina
-label.percentage_identity = Porcentaje de identidad
-label.blosum62 = BLOSUM62
-label.blosum62_score = Puntuación del BLOSUM62
-label.tcoffee_scores = Puntuación del T-Coffee
-label.average_distance_bloslum62 = Distancia Media Usando BLOSUM62
+label.average_distance_blosum62 = Distancia Media Usando BLOSUM62
label.neighbour_blosum62 = Neighbour Joining usando BLOSUM62
label.show_annotations = Mostrar anotaciones
label.colour_text = Color del texto
-label.show_non_conversed = Mostrar no conservadas
+label.show_non_conserved = Mostrar no conservadas
label.overview_window = Ventana resumen
label.none = Ninguno
label.above_identity_threshold = Por encima del umbral de identidad
label.style = Estilo:
label.calculating = Calculando....
label.modify_conservation_visibility = Modificar la visibilidad de conservación
-label.colour_residues_above_occurence = Residuos de color por encima del % de aparición
+label.colour_residues_above_occurrence = Residuos de color por encima del % de aparición
label.set_this_label_text = fijar como etiqueta
label.sequences_from = Secuencias de {0}
label.successfully_loaded_file = Fichero cargado exitosamente {0}
label.vamsas_document_import_failed = Fallo en la importación del documento Vamsas
label.couldnt_locate = No se pudo localizar {0}
label.url_not_found = URL no encontrada
-label.no_link_selected = Enlace no seleccionado
label.new_sequence_url_link = Enlace a una nueva secuencia URL
label.cannot_edit_annotations_in_wrapped_view = No se pueden editar anotaciones en vista envolvente
label.wrapped_view_no_edit = Vista envolvente - no editar
label.standard_databases = Bases de datos estándar
label.fetch_embl_uniprot = Recuperar de EMBL/EMBLCDS o Uniprot/PDB y de cualquier fuente DAS seleccionada
label.reset_min_max_colours_to_defaults = Reiniciar los colores min y max colours a los valores por defecto establecidos en las preferencias de usuario
-label.align_structures_using_linked_alignment_views = Alinear las estructuras utlizando las {0} vistas de alineamiento enlazadas
+label.align_structures_using_linked_alignment_views = Alinear las estructuras utilizando las {0} vista(s) de alineamiento enlazada(s)
label.connect_to_session = Conectar a la sesión {0}
label.threshold_feature_display_by_score = Filtrar la característica mostrada por puntuación.
label.threshold_feature_no_threshold = Sin umbral
label.enter_pdb_id = Introducir PDB Id
label.text_colour = Color del texto
label.structure = Estructura
-label.clustalx_colours = Colores de Clustalx
-label.above_identity_percentage = Sobre % identidad
label.create_sequence_details_report_annotation_for = Anotación para {0}
label.sequence_details_for = Detalles de la secuencia para {0}
label.sequence_name = Nombre de la secuencia
label.associate_leaves_with = Asociar hojas con
label.save_colour_scheme_with_unique_name_added_to_colour_menu = Guarde el esquema cromáticos con un nombre único y se añadirá al menú de colores
label.case_sensitive = Sensible a mayúsculas
-label.lower_case_colour = Color para las minúsculas
+label.lower_case_colour = Colorear todas las minúsculas
+label.lower_case_tip = El color elegido se aplicará a todas las minúsculas
label.index_by_host = Indizar por host
label.index_by_type = Indizar por tipo
label.enable_jabaws_services = Habilitar servicios JABAWS
label.points_for_params = Puntos de {0}
label.transformed_points_for_params = Puntos transformados de {0}
label.graduated_color_for_params = Color graduado para la característica de {0}
-label.select_backgroud_colour = Seleccionar color de fondo
+label.select_background_colour = Seleccionar color de fondo
label.invalid_font = Fuente no válida
label.separate_multiple_accession_ids = Separar los accession id con un punto y coma ";"
label.replace_commas_semicolons = Cambiar comas por puntos y comas
error.implementation_error_cannot_have_null_alignment = Error de implementación: no es posible tener una clave nula en el alineamiento
error.implementation_error_null_fileparse = Error de implementación. FileParse nulo en el construictor de copia
error.implementation_error_cannot_map_alignment_sequences = Error de implementación: no es posible maper un alineamiento de secuencias desde distintos conjuntos de datos en un único alineamiento en el documento VAMSAS.
-error.implementation_error_cannot_duplicate_colour_scheme = Error grave de implementación: no es posible duplicar el esquema cromático {0}
error.implementation_error_structure_selection_manager_null = Error de implementación. El contexto structure selection manager's es nulo
exception.ssm_context_is_null = El contexto SSM es nulo
error.idstring_seqstrings_only_one_per_sequence = idstrings y seqstrings contienen una cadena por cada secuencia
exception.bad_pattern_to_regex_perl_code = patrón erróneo en Regex.perlCode: {0}
exception.no_stub_implementation_for_interface = No existe una implementación del stub para la interfaz: {0}
exception.cannot_set_endpoint_address_unknown_port = No es posible estabelcer la dirección de punto final para el puerto desconocido {0}
-exception.querying_matching_opening_parenthesis_for_non_closing_parenthesis = Consultando la coincidencia de apertura de paréntesis para paréntesis sin cerrar (?)
exception.mismatched_unseen_closing_char = Discordancia (no vista) en el carácter de cierre {0}
exception.mismatched_closing_char = Carácter de cierre discordante {0}
exception.mismatched_opening_char = Carácter de apertura discordante {0} en {1}
exception.application_test_npe = Prueba de aplicación: lanzando un NullPointerException que debe aparecer en la consola
exception.overwriting_vamsas_id_binding = Sobreescribiendo la asociación al VAMSAS id
exception.overwriting_jalview_id_binding = Sobreescribiendo la asociación al Jalview id
-error.implementation_error_unknown_file_format_string = Error de implementación: cadena de formato de fichero desconocido
exception.failed_to_resolve_gzip_stream = Fallo al resolver el flujo GZIP
exception.problem_opening_file_also_tried = Problema abriendo {0} (también se intentó {1}) : {2}
exception.problem_opening_file = Problema abriendo {0} : {1}
info.select_filter_option=Escoger Opción de Filtro / Entrada Manual
info.invalid_msa_input_mininfo=Necesita por lo menos dos secuencias con al menos 3 residuos cada una, sin regiones ocultas entre ellas.
label.chimera_missing=Visualizador de estructura Chimera no encontrado.<br/>Por favor, introduzca la ruta de Chimera,<br/>o descargar e instalar la UCSF Chimera.
-label.save_as_biojs_html=Guardar como HTML BioJs
exception.fts_server_unreachable=Jalview no puede conectar con el servidor {0}. \nPor favor asegúrese de que está conectado a Internet y vuelva a intentarlo.
exception.outofmemory_loading_mmcif_file=Sin memoria al cargar el fichero mmCIF
label.hide_columns_not_containing=Ocultar las columnas que no contengan
label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias:
label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'.
label.do_not_display_again = No mostrar este mensaje de nuevo
+exception.url_cannot_have_miriam_id = {0} es una id MIRIAM y no puede ser usada como nombre url personalizado
+exception.url_cannot_have_duplicate_id = {0} no puede ser usada como etiqueta en más de un enlace
+label.filter = Filtrar texto:
+action.customfilter = Sólo personalizado
+action.showall = Mostrar todo
+label.insert = Insertar:
+action.seq_id = $SEQUENCE_ID$
+action.db_acc = $DB_ACCESSION$
+label.primary = Doble clic
+label.inmenu = En Menú
+label.id = ID
+label.database = Base de datos
+label.urltooltip = Sólo una url, que debe usar una id de secuencia, puede ser seleccionada en la opción 'On Click'
+label.edit_sequence_url_link = Editar link de secuencia URL
+warn.name_cannot_be_duplicate = Los nombres URL definidos por el usuario deben ser únicos y no pueden ser ids de MIRIAM
+label.invalid_name = Nombre inválido !
label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas
+label.urllinks = Enlaces
\ No newline at end of file
zbuffer.addItemListener(this);
charge.setLabel(MessageManager.getString("label.charge_cysteine"));
charge.addActionListener(this);
- hydro.setLabel(MessageManager.getString("label.hydrophobicity"));
+ hydro.setLabel(MessageManager
+ .getString("label.colourScheme_hydrophobic"));
hydro.addActionListener(this);
chain.setLabel(MessageManager.getString("action.by_chain"));
chain.addActionListener(this);
.setLabel(MessageManager.getString("label.all_chains_visible"));
allchains.addItemListener(this);
viewMenu.setLabel(MessageManager.getString("action.view"));
- zappo.setLabel(MessageManager.getString("label.zappo"));
+ zappo.setLabel(MessageManager.getString("label.colourScheme_zappo"));
zappo.addActionListener(this);
- taylor.setLabel(MessageManager.getString("label.taylor"));
+ taylor.setLabel(MessageManager.getString("label.colourScheme_taylor"));
taylor.addActionListener(this);
- helix.setLabel(MessageManager.getString("label.helix_propensity"));
+ helix.setLabel(MessageManager
+ .getString("label.colourScheme_helix_propensity"));
helix.addActionListener(this);
- strand.setLabel(MessageManager.getString("label.strand_propensity"));
+ strand.setLabel(MessageManager
+ .getString("label.colourScheme_strand_propensity"));
strand.addActionListener(this);
- turn.setLabel(MessageManager.getString("label.turn_propensity"));
+ turn.setLabel(MessageManager
+ .getString("label.colourScheme_turn_propensity"));
turn.addActionListener(this);
- buried.setLabel(MessageManager.getString("label.buried_index"));
+ buried.setLabel(MessageManager
+ .getString("label.colourScheme_buried_index"));
buried.addActionListener(this);
user.setLabel(MessageManager.getString("action.user_defined"));
user.addActionListener(this);
public class PDBChain
{
+ public static final String RESNUM_FEATURE = "RESNUM";
+
/**
* SequenceFeature group for PDB File features added to sequences
*/
Residue tmpres = residues.lastElement();
Atom tmpat = tmpres.atoms.get(0);
// Make A new SequenceFeature for the current residue numbering
- SequenceFeature sf = new SequenceFeature("RESNUM", tmpat.resName
+ SequenceFeature sf = new SequenceFeature(RESNUM_FEATURE, tmpat.resName
+ ":" + tmpat.resNumIns + " " + pdbid + id, "", offset
+ count, offset + count, pdbid);
resFeatures.addElement(sf);
try
{
index = ResidueProperties.aa3Hash.get(b.at1.resName).intValue();
- b.startCol = cs.findColour(ResidueProperties.aa[index].charAt(0));
+ b.startCol = cs.findColour(ResidueProperties.aa[index].charAt(0),
+ 0, null, null, 0f);
index = ResidueProperties.aa3Hash.get(b.at2.resName).intValue();
- b.endCol = cs.findColour(ResidueProperties.aa[index].charAt(0));
+ b.endCol = cs.findColour(ResidueProperties.aa[index].charAt(0), 0,
+ null, null, 0f);
} catch (Exception e)
{
+++ /dev/null
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * Jalview is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package MCview;
-
-import jalview.datamodel.PDBEntry;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignmentPanel;
-import jalview.gui.Desktop;
-import jalview.gui.JvOptionPane;
-import jalview.gui.OOMWarning;
-import jalview.gui.UserDefinedColours;
-import jalview.io.DataSourceType;
-import jalview.io.JalviewFileChooser;
-import jalview.io.JalviewFileView;
-import jalview.schemes.BuriedColourScheme;
-import jalview.schemes.HelixColourScheme;
-import jalview.schemes.HydrophobicColourScheme;
-import jalview.schemes.StrandColourScheme;
-import jalview.schemes.TaylorColourScheme;
-import jalview.schemes.TurnColourScheme;
-import jalview.schemes.UserColourScheme;
-import jalview.schemes.ZappoColourScheme;
-import jalview.util.MessageManager;
-import jalview.ws.ebi.EBIFetchClient;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.PrintWriter;
-
-import javax.swing.ButtonGroup;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JColorChooser;
-import javax.swing.JInternalFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JRadioButtonMenuItem;
-
-public class PDBViewer extends JInternalFrame implements Runnable
-{
-
- /**
- * The associated sequence in an alignment
- */
- PDBCanvas pdbcanvas;
-
- PDBEntry pdbentry;
-
- SequenceI[] seq;
-
- String[] chains;
-
- AlignmentPanel ap;
-
- DataSourceType protocol;
-
- String tmpPDBFile;
-
- public PDBViewer(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
- AlignmentPanel ap, DataSourceType protocol)
- {
- this.pdbentry = pdbentry;
- this.seq = seq;
- this.chains = chains;
- this.ap = ap;
- this.protocol = protocol;
-
- try
- {
- jbInit();
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
-
- StringBuffer title = new StringBuffer(seq[0].getName() + ":"
- + pdbentry.getFile());
-
- pdbcanvas = new PDBCanvas();
-
- setContentPane(pdbcanvas);
-
- if (pdbentry.getFile() != null)
- {
- try
- {
- tmpPDBFile = pdbentry.getFile();
- PDBfile pdbfile = new PDBfile(false, false, false, tmpPDBFile,
- DataSourceType.FILE);
-
- pdbcanvas.init(pdbentry, seq, chains, ap, protocol);
-
- } catch (java.io.IOException ex)
- {
- ex.printStackTrace();
- }
- }
- else
- {
- Thread worker = new Thread(this);
- worker.start();
- }
-
- String method = (String) pdbentry.getProperty("method");
- if (method != null)
- {
- title.append(" Method: ");
- title.append(method);
- }
- String ch = (String) pdbentry.getProperty("chains");
- if (ch != null)
- {
- title.append(" Chain:");
- title.append(ch);
- }
- Desktop.addInternalFrame(this, title.toString(), 400, 400);
- }
-
- @Override
- public void run()
- {
- try
- {
- EBIFetchClient ebi = new EBIFetchClient();
- String query = "pdb:" + pdbentry.getId();
- pdbentry.setFile(ebi.fetchDataAsFile(query, "default", "xml")
- .getAbsolutePath());
-
- if (pdbentry.getFile() != null)
- {
- pdbcanvas.init(pdbentry, seq, chains, ap, protocol);
- }
- } catch (Exception ex)
- {
- pdbcanvas.errorMessage = "Error retrieving file: " + pdbentry.getId();
- ex.printStackTrace();
- }
- }
-
- private void jbInit() throws Exception
- {
- this.addKeyListener(new KeyAdapter()
- {
- @Override
- public void keyPressed(KeyEvent evt)
- {
- pdbcanvas.keyPressed(evt);
- }
- });
-
- this.setJMenuBar(jMenuBar1);
- fileMenu.setText(MessageManager.getString("action.file"));
- coloursMenu.setText(MessageManager.getString("label.colours"));
- saveMenu.setActionCommand(MessageManager.getString("action.save_image"));
- saveMenu.setText(MessageManager.getString("action.save_as"));
- png.setText("PNG");
- png.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- png_actionPerformed(e);
- }
- });
- eps.setText("EPS");
- eps.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- eps_actionPerformed(e);
- }
- });
- mapping.setText(MessageManager.getString("label.view_mapping"));
- mapping.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- mapping_actionPerformed(e);
- }
- });
- wire.setText(MessageManager.getString("label.wireframe"));
- wire.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- wire_actionPerformed(e);
- }
- });
- depth.setSelected(true);
- depth.setText(MessageManager.getString("label.depthcue"));
- depth.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- depth_actionPerformed(e);
- }
- });
- zbuffer.setSelected(true);
- zbuffer.setText(MessageManager.getString("label.z_buffering"));
- zbuffer.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- zbuffer_actionPerformed(e);
- }
- });
- charge.setText(MessageManager.getString("label.charge_cysteine"));
- charge.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- charge_actionPerformed(e);
- }
- });
- chain.setText(MessageManager.getString("action.by_chain"));
- chain.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- chain_actionPerformed(e);
- }
- });
- seqButton.setSelected(true);
- seqButton.setText(MessageManager.getString("action.by_sequence"));
- seqButton.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- seqButton_actionPerformed(e);
- }
- });
- allchains.setSelected(true);
- allchains.setText(MessageManager.getString("label.show_all_chains"));
- allchains.addItemListener(new ItemListener()
- {
- @Override
- public void itemStateChanged(ItemEvent e)
- {
- allchains_itemStateChanged(e);
- }
- });
- zappo.setText(MessageManager.getString("label.zappo"));
- zappo.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- zappo_actionPerformed(e);
- }
- });
- taylor.setText(MessageManager.getString("label.taylor"));
- taylor.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- taylor_actionPerformed(e);
- }
- });
- hydro.setText(MessageManager.getString("label.hydrophobicity"));
- hydro.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- hydro_actionPerformed(e);
- }
- });
- helix.setText(MessageManager.getString("label.helix_propensity"));
- helix.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- helix_actionPerformed(e);
- }
- });
- strand.setText(MessageManager.getString("label.strand_propensity"));
- strand.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- strand_actionPerformed(e);
- }
- });
- turn.setText(MessageManager.getString("label.turn_propensity"));
- turn.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- turn_actionPerformed(e);
- }
- });
- buried.setText(MessageManager.getString("label.buried_index"));
- buried.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- buried_actionPerformed(e);
- }
- });
- user.setText(MessageManager.getString("action.user_defined"));
- user.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- user_actionPerformed(e);
- }
- });
- viewMenu.setText(MessageManager.getString("action.view"));
- background
- .setText(MessageManager.getString("action.background_colour"));
- background.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- background_actionPerformed(e);
- }
- });
- savePDB.setText(MessageManager.getString("label.pdb_file"));
- savePDB.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- savePDB_actionPerformed(e);
- }
- });
- jMenuBar1.add(fileMenu);
- jMenuBar1.add(coloursMenu);
- jMenuBar1.add(viewMenu);
- fileMenu.add(saveMenu);
- fileMenu.add(mapping);
- saveMenu.add(savePDB);
- saveMenu.add(png);
- saveMenu.add(eps);
- coloursMenu.add(seqButton);
- coloursMenu.add(chain);
- coloursMenu.add(charge);
- coloursMenu.add(zappo);
- coloursMenu.add(taylor);
- coloursMenu.add(hydro);
- coloursMenu.add(helix);
- coloursMenu.add(strand);
- coloursMenu.add(turn);
- coloursMenu.add(buried);
- coloursMenu.add(user);
- coloursMenu.add(background);
- ButtonGroup bg = new ButtonGroup();
- bg.add(seqButton);
- bg.add(chain);
- bg.add(charge);
- bg.add(zappo);
- bg.add(taylor);
- bg.add(hydro);
- bg.add(helix);
- bg.add(strand);
- bg.add(turn);
- bg.add(buried);
- bg.add(user);
-
- if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
- {
- java.util.Enumeration userColours = jalview.gui.UserDefinedColours
- .getUserColourSchemes().keys();
-
- while (userColours.hasMoreElements())
- {
- final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(
- userColours.nextElement().toString());
- radioItem.setName("USER_DEFINED");
- radioItem.addMouseListener(new MouseAdapter()
- {
- @Override
- public void mousePressed(MouseEvent evt)
- {
- if (evt.isPopupTrigger()) // Mac
- {
- offerRemoval(radioItem);
- }
- }
-
- @Override
- public void mouseReleased(MouseEvent evt)
- {
- if (evt.isPopupTrigger()) // Windows
- {
- offerRemoval(radioItem);
- }
- }
-
- /**
- * @param radioItem
- */
- void offerRemoval(final JRadioButtonMenuItem radioItem)
- {
- radioItem.removeActionListener(radioItem.getActionListeners()[0]);
-
- int option = JvOptionPane.showInternalConfirmDialog(
- jalview.gui.Desktop.desktop, MessageManager
- .getString("label.remove_from_default_list"),
- MessageManager
- .getString("label.remove_user_defined_colour"),
- JvOptionPane.YES_NO_OPTION);
- if (option == JvOptionPane.YES_OPTION)
- {
- jalview.gui.UserDefinedColours
- .removeColourFromDefaults(radioItem.getText());
- coloursMenu.remove(radioItem);
- }
- else
- {
- radioItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- user_actionPerformed(evt);
- }
- });
- }
- }
- });
- radioItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- user_actionPerformed(evt);
- }
- });
- coloursMenu.add(radioItem);
- bg.add(radioItem);
- }
- }
-
- viewMenu.add(wire);
- viewMenu.add(depth);
- viewMenu.add(zbuffer);
- viewMenu.add(allchains);
- }
-
- JMenuBar jMenuBar1 = new JMenuBar();
-
- JMenu fileMenu = new JMenu();
-
- JMenu coloursMenu = new JMenu();
-
- JMenu saveMenu = new JMenu();
-
- JMenuItem png = new JMenuItem();
-
- JMenuItem eps = new JMenuItem();
-
- JMenuItem mapping = new JMenuItem();
-
- JCheckBoxMenuItem wire = new JCheckBoxMenuItem();
-
- JCheckBoxMenuItem depth = new JCheckBoxMenuItem();
-
- JCheckBoxMenuItem zbuffer = new JCheckBoxMenuItem();
-
- JCheckBoxMenuItem allchains = new JCheckBoxMenuItem();
-
- JRadioButtonMenuItem charge = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem chain = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem seqButton = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem hydro = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem taylor = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem zappo = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem user = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem buried = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem turn = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem strand = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem helix = new JRadioButtonMenuItem();
-
- JMenu viewMenu = new JMenu();
-
- JMenuItem background = new JMenuItem();
-
- JMenuItem savePDB = new JMenuItem();
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- public void eps_actionPerformed(ActionEvent e)
- {
- makePDBImage(jalview.util.ImageMaker.TYPE.EPS);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- public void png_actionPerformed(ActionEvent e)
- {
- makePDBImage(jalview.util.ImageMaker.TYPE.PNG);
- }
-
- void makePDBImage(jalview.util.ImageMaker.TYPE type)
- {
- int width = pdbcanvas.getWidth();
- int height = pdbcanvas.getHeight();
-
- jalview.util.ImageMaker im;
-
- if (type == jalview.util.ImageMaker.TYPE.PNG)
- {
- im = new jalview.util.ImageMaker(this,
- jalview.util.ImageMaker.TYPE.PNG, "Make PNG image from view",
- width, height, null, null, null, 0, false);
- }
- else if (type == jalview.util.ImageMaker.TYPE.EPS)
- {
- im = new jalview.util.ImageMaker(this,
- jalview.util.ImageMaker.TYPE.EPS, "Make EPS file from view",
- width, height, null, this.getTitle(), null, 0, false);
- }
- else
- {
-
- im = new jalview.util.ImageMaker(this,
- jalview.util.ImageMaker.TYPE.SVG, "Make SVG file from PCA",
- width, height, null, this.getTitle(), null, 0, false);
- }
-
- if (im.getGraphics() != null)
- {
- pdbcanvas.drawAll(im.getGraphics(), width, height);
- im.writeImage();
- }
- }
-
- public void charge_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = false;
- pdbcanvas.pdb.setChargeColours();
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void hydro_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = false;
- pdbcanvas.pdb.setColours(new HydrophobicColourScheme());
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void chain_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = false;
- pdbcanvas.pdb.setChainColours();
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void zbuffer_actionPerformed(ActionEvent e)
- {
- pdbcanvas.zbuffer = !pdbcanvas.zbuffer;
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void molecule_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bymolecule = !pdbcanvas.bymolecule;
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void depth_actionPerformed(ActionEvent e)
- {
- pdbcanvas.depthcue = !pdbcanvas.depthcue;
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void wire_actionPerformed(ActionEvent e)
- {
- pdbcanvas.wire = !pdbcanvas.wire;
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void seqButton_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = true;
- pdbcanvas.updateSeqColours();
- }
-
- public void mapping_actionPerformed(ActionEvent e)
- {
- jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer();
- try
- {
- cap.setText(pdbcanvas.mappingDetails.toString());
- Desktop.addInternalFrame(cap,
- MessageManager.getString("label.pdb_sequence_mapping"), 550,
- 600);
- } catch (OutOfMemoryError oom)
- {
- new OOMWarning("Opening sequence to structure mapping report", oom);
- cap.dispose();
- }
- }
-
- public void allchains_itemStateChanged(ItemEvent e)
- {
- pdbcanvas.setAllchainsVisible(allchains.getState());
- }
-
- public void zappo_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = false;
- pdbcanvas.pdb.setColours(new ZappoColourScheme());
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void taylor_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = false;
- pdbcanvas.pdb.setColours(new TaylorColourScheme());
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void helix_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = false;
- pdbcanvas.pdb.setColours(new HelixColourScheme());
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void strand_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = false;
- pdbcanvas.pdb.setColours(new StrandColourScheme());
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void turn_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = false;
- pdbcanvas.pdb.setColours(new TurnColourScheme());
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void buried_actionPerformed(ActionEvent e)
- {
- pdbcanvas.bysequence = false;
- pdbcanvas.pdb.setColours(new BuriedColourScheme());
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
-
- public void user_actionPerformed(ActionEvent e)
- {
- if (e.getActionCommand().equals(
- MessageManager.getString("action.user_defined")))
- {
- // new UserDefinedColours(pdbcanvas, null);
- }
- else
- {
- UserColourScheme udc = (UserColourScheme) UserDefinedColours
- .getUserColourSchemes().get(e.getActionCommand());
-
- pdbcanvas.pdb.setColours(udc);
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
- }
-
- public void background_actionPerformed(ActionEvent e)
- {
- java.awt.Color col = JColorChooser.showDialog(this,
- MessageManager.getString("label.select_backgroud_colour"),
- pdbcanvas.backgroundColour);
-
- if (col != null)
- {
- pdbcanvas.backgroundColour = col;
- pdbcanvas.redrawneeded = true;
- pdbcanvas.repaint();
- }
- }
-
- public void savePDB_actionPerformed(ActionEvent e)
- {
- JalviewFileChooser chooser = new JalviewFileChooser(
- jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
-
- chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle(MessageManager.getString("label.save_pdb_file"));
- chooser.setToolTipText(MessageManager.getString("action.save"));
-
- int value = chooser.showSaveDialog(this);
-
- if (value == JalviewFileChooser.APPROVE_OPTION)
- {
- try
- {
- BufferedReader in = new BufferedReader(new FileReader(tmpPDBFile));
- File outFile = chooser.getSelectedFile();
-
- PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
- String data;
- while ((data = in.readLine()) != null)
- {
- if (!(data.indexOf("<PRE>") > -1 || data.indexOf("</PRE>") > -1))
- {
- out.println(data);
- }
- }
- out.close();
- in.close();
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- }
-}
"list selection level residue", true);
if (chimeraReply != null)
{
+ /*
+ * expect 0, 1 or more lines of the format
+ * residue id #0:43.A type GLY
+ * where we are only interested in the atomspec #0.43.A
+ */
for (String inputLine : chimeraReply)
{
String[] inputLineParts = inputLine.split("\\s+");
*/
package jalview.analysis;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.util.MappingUtils;
import jalview.util.QuickSort;
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.List;
-
/**
* Takes in a vector or array of sequences and column start and column end and
* returns a new Hashtable[] of size maxSeqLength, if Hashtable not supplied.
}
}
- public static final ProfilesI calculate(List<SequenceI> list,
- int start, int end)
+ public static final ProfilesI calculate(List<SequenceI> list, int start,
+ int end)
{
return calculate(list, start, end, false);
}
}
/**
+ * Derive the gap count annotation row.
+ *
+ * @param gaprow
+ * the annotation row to add annotations to
+ * @param profiles
+ * the source consensus data
+ * @param startCol
+ * start column (inclusive)
+ * @param endCol
+ * end column (exclusive)
+ */
+ public static void completeGapAnnot(AlignmentAnnotation gaprow,
+ ProfilesI profiles, int startCol, int endCol, long nseq)
+ {
+ if (gaprow == null || gaprow.annotations == null
+ || gaprow.annotations.length < endCol)
+ {
+ /*
+ * called with a bad alignment annotation row
+ * wait for it to be initialised properly
+ */
+ return;
+ }
+ // always set ranges again
+ gaprow.graphMax = nseq;
+ gaprow.graphMin = 0;
+ for (int i = startCol; i < endCol; i++)
+ {
+ ProfileI profile = profiles.get(i);
+ if (profile == null)
+ {
+ /*
+ * happens if sequences calculated over were
+ * shorter than alignment width
+ */
+ gaprow.annotations[i] = null;
+ return;
+ }
+
+ final int gapped = profile.getNonGapped();
+
+ String description = String.valueOf(gapped);
+
+ gaprow.annotations[i] = new Annotation(description, description,
+ '\0',
+ gapped);
+ }
+ }
+
+ /**
* Returns a tooltip showing either
* <ul>
* <li>the full profile (percentages of all residues present), if
* calculations
* @return
*/
- public static int[] extractProfile(ProfileI profile,
- boolean ignoreGaps)
+ public static int[] extractProfile(ProfileI profile, boolean ignoreGaps)
{
int[] rtnval = new int[64];
ResidueCount counts = profile.getCounts();
import jalview.util.DBRefUtils;
import jalview.util.MapList;
import jalview.util.MappingUtils;
+import jalview.util.RangeComparator;
import jalview.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.SortedMap;
import java.util.TreeMap;
/**
* ranges are assembled in order. Other cases should not use this method,
* but instead construct an explicit mapping for CDS (e.g. EMBL parsing).
*/
- Collections.sort(result, new Comparator<int[]>()
- {
- @Override
- public int compare(int[] o1, int[] o2)
- {
- return Integer.compare(o1[0], o2[0]);
- }
- });
+ Collections.sort(result, new RangeComparator(true));
return result;
}
* @param unmapped
* @return
*/
- static Map<Integer, Map<SequenceI, Character>> buildMappedColumnsMap(
+ static SortedMap<Integer, Map<SequenceI, Character>> buildMappedColumnsMap(
AlignmentI unaligned, AlignmentI aligned, List<SequenceI> unmapped)
{
/*
* {unalignedSequence, characterPerSequence} at that position.
* TreeMap keeps the entries in ascending column order.
*/
- Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
+ SortedMap<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
/*
* record any sequences that have no mapping so can't be realigned
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Vector;
* or not conserved (-1)
* Using TreeMap means properties are displayed in alphabetical order
*/
- Map<String, Integer> resultHash = new TreeMap<String, Integer>();
+ SortedMap<String, Integer> resultHash = new TreeMap<String, Integer>();
SymbolCounts symbolCounts = values.getSymbolCounts();
char[] symbols = symbolCounts.symbols;
int[] counts = symbolCounts.values;
*
* @return Conservation sequence
*/
- public Sequence getConsSequence()
+ public SequenceI getConsSequence()
{
return consSequence;
}
*/
package jalview.analysis;
-import jalview.datamodel.BinarySequence;
-import jalview.datamodel.BinarySequence.InvalidSequenceTypeException;
-import jalview.math.Matrix;
+import jalview.math.MatrixI;
import jalview.schemes.ResidueProperties;
import jalview.schemes.ScoreMatrix;
/**
* Performs Principal Component Analysis on given sequences
- *
- * @author $author$
- * @version $Revision$
*/
public class PCA implements Runnable
{
- Matrix m;
-
- Matrix symm;
+ boolean jvCalcMode = true;
- Matrix m2;
+ MatrixI symm;
double[] eigenvalue;
- Matrix eigenvector;
+ MatrixI eigenvector;
- StringBuffer details = new StringBuffer();
+ StringBuilder details = new StringBuilder(1024);
+
+ private String[] seqs;
+
+ private ScoreMatrix scoreMatrix;
/**
* Creates a new PCA object. By default, uses blosum62 matrix to generate
public PCA(String[] s, boolean nucleotides, String s_m)
{
+ this.seqs = s;
- BinarySequence[] bs = new BinarySequence[s.length];
- int ii = 0;
-
- while ((ii < s.length) && (s[ii] != null))
- {
- bs[ii] = new BinarySequence(s[ii], nucleotides);
- bs[ii].encode();
- ii++;
- }
-
- BinarySequence[] bs2 = new BinarySequence[s.length];
- ii = 0;
- ScoreMatrix smtrx = null;
+ scoreMatrix = null;
String sm = s_m;
if (sm != null)
{
- smtrx = ResidueProperties.getScoreMatrix(sm);
+ scoreMatrix = ResidueProperties.getScoreMatrix(sm);
}
- if (smtrx == null)
+ if (scoreMatrix == null)
{
// either we were given a non-existent score matrix or a scoremodel that
// isn't based on a pairwise symbol score matrix
- smtrx = ResidueProperties.getScoreMatrix(sm = (nucleotides ? "DNA"
- : "BLOSUM62"));
+ scoreMatrix = ResidueProperties
+ .getScoreMatrix(sm = (nucleotides ? "DNA" : "BLOSUM62"));
}
details.append("PCA calculation using " + sm
+ " sequence similarity matrix\n========\n\n");
- while ((ii < s.length) && (s[ii] != null))
- {
- bs2[ii] = new BinarySequence(s[ii], nucleotides);
- if (smtrx != null)
- {
- try
- {
- bs2[ii].matrixEncode(smtrx);
- } catch (InvalidSequenceTypeException x)
- {
- details.append("Unexpected mismatch of sequence type and score matrix. Calculation will not be valid!\n\n");
- }
- }
- ii++;
- }
-
- // System.out.println("Created binary encoding");
- // printMemory(rt);
- int count = 0;
-
- while ((count < bs.length) && (bs[count] != null))
- {
- count++;
- }
-
- double[][] seqmat = new double[count][bs[0].getDBinary().length];
- double[][] seqmat2 = new double[count][bs2[0].getDBinary().length];
- int i = 0;
-
- while (i < count)
- {
- seqmat[i] = bs[i].getDBinary();
- seqmat2[i] = bs2[i].getDBinary();
- i++;
- }
-
- // System.out.println("Created array");
- // printMemory(rt);
- // System.out.println(" --- Original matrix ---- ");
- m = new Matrix(seqmat, count, bs[0].getDBinary().length);
- m2 = new Matrix(seqmat2, count, bs2[0].getDBinary().length);
-
- }
-
- /**
- * Returns the matrix used in PCA calculation
- *
- * @return java.math.Matrix object
- */
-
- public Matrix getM()
- {
- return m;
}
/**
*/
public double getEigenvalue(int i)
{
- return eigenvector.d[i];
+ return eigenvector.getD()[i];
}
/**
*/
public float[][] getComponents(int l, int n, int mm, float factor)
{
- float[][] out = new float[m.rows][3];
+ float[][] out = new float[getHeight()][3];
- for (int i = 0; i < m.rows; i++)
+ for (int i = 0; i < getHeight(); i++)
{
out[i][0] = (float) component(i, l) * factor;
out[i][1] = (float) component(i, n) * factor;
public double[] component(int n)
{
// n = index of eigenvector
- double[] out = new double[m.rows];
+ double[] out = new double[getHeight()];
- for (int i = 0; i < m.rows; i++)
+ for (int i = 0; i < out.length; i++)
{
out[i] = component(i, n);
}
{
double out = 0.0;
- for (int i = 0; i < symm.cols; i++)
+ for (int i = 0; i < symm.width(); i++)
{
- out += (symm.value[row][i] * eigenvector.value[i][n]);
+ out += (symm.getValue(row, i) * eigenvector.getValue(i, n));
}
- return out / eigenvector.d[n];
+ return out / eigenvector.getD()[n];
}
public String getDetails()
/**
* DOCUMENT ME!
*/
+ @Override
public void run()
{
PrintStream ps = new PrintStream(System.out)
{
+ @Override
public void print(String x)
{
details.append(x);
}
+ @Override
public void println()
{
details.append("\n");
}
};
+ // long now = System.currentTimeMillis();
try
{
details.append("PCA Calculation Mode is "
+ (jvCalcMode ? "Jalview variant" : "Original SeqSpace")
+ "\n");
- Matrix mt = m.transpose();
- details.append(" --- OrigT * Orig ---- \n");
- if (!jvCalcMode)
- {
- eigenvector = mt.preMultiply(m); // standard seqspace comparison matrix
- }
- else
- {
- eigenvector = mt.preMultiply(m2); // jalview variation on seqsmace
- // method
- }
+ eigenvector = scoreMatrix.computePairwiseScores(seqs);
- eigenvector.print(ps);
+ details.append(" --- OrigT * Orig ---- \n");
+ eigenvector.print(ps, "%8.2f");
symm = eigenvector.copy();
details.append(" ---Tridiag transform matrix ---\n");
details.append(" --- D vector ---\n");
- eigenvector.printD(ps);
+ eigenvector.printD(ps, "%15.4e");
ps.println();
details.append("--- E vector ---\n");
- eigenvector.printE(ps);
+ eigenvector.printE(ps, "%15.4e");
ps.println();
// Now produce the diagonalization matrix
}
details.append(" --- New diagonalization matrix ---\n");
- eigenvector.print(ps);
+ eigenvector.print(ps, "%8.2f");
details.append(" --- Eigenvalues ---\n");
- eigenvector.printD(ps);
+ eigenvector.printD(ps, "%15.4e");
ps.println();
/*
* for (int seq=0;seq<symm.rows;seq++) { ps.print("\"Seq"+seq+"\""); for
*
* ps.print(","+component(seq, ev)); } ps.println(); }
*/
+ // System.out.println(("PCA.run() took "
+ // + (System.currentTimeMillis() - now) + "ms"));
}
- boolean jvCalcMode = true;
-
public void setJvCalcMode(boolean calcMode)
{
this.jvCalcMode = calcMode;
}
+
+ /**
+ * Answers the N dimensions of the NxN PCA matrix. This is the number of
+ * sequences involved in the pairwise score calculation.
+ *
+ * @return
+ */
+ public int getHeight()
+ {
+ // TODO can any of seqs[] be null?
+ return seqs.length;
+ }
}
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.renderer.ResidueShaderI;
import jalview.schemes.ColourSchemeI;
import java.awt.Color;
ColourSchemeI getGlobalColourScheme();
+ /**
+ * Returns an object that describes colouring (including any thresholding or
+ * fading) of the alignment
+ *
+ * @return
+ */
+ ResidueShaderI getResidueShading();
+
AlignmentI getAlignment();
ColumnSelection getColumnSelection();
AlignmentAnnotation getAlignmentConsensusAnnotation();
/**
+ * get the container for alignment gap annotation
+ *
+ * @return
+ */
+ AlignmentAnnotation getAlignmentGapAnnotation();
+
+ /**
* get the container for cDNA complement consensus annotation
*
* @return
/**
*
- * @return the alignment annotatino row for the structure consensus
+ * @return the alignment annotation row for the structure consensus
* calculation
*/
AlignmentAnnotation getAlignmentStrucConsensusAnnotation();
void setRnaStructureConsensusHash(Hashtable[] hStrucConsensus);
/**
- * set global colourscheme
+ * Sets the colour scheme for the background alignment (as distinct from
+ * sub-groups, which may have their own colour schemes). A null value is used
+ * for no residue colour (white).
*
- * @param rhc
+ * @param cs
*/
- void setGlobalColourScheme(ColourSchemeI rhc);
+ void setGlobalColourScheme(ColourSchemeI cs);
Map<SequenceI, SequenceCollectionI> getHiddenRepSequences();
import jalview.datamodel.SequenceI;
import jalview.io.AppletFormatAdapter;
import jalview.io.DataSourceType;
-import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
import jalview.io.SequenceAnnotationReport;
+import jalview.renderer.ResidueShader;
+import jalview.renderer.ResidueShaderI;
import jalview.schemes.Blosum62ColourScheme;
import jalview.schemes.BuriedColourScheme;
import jalview.schemes.ClustalxColourScheme;
import jalview.schemes.HelixColourScheme;
import jalview.schemes.HydrophobicColourScheme;
+import jalview.schemes.JalviewColourScheme;
import jalview.schemes.NucleotideColourScheme;
import jalview.schemes.PIDColourScheme;
+import jalview.schemes.PurinePyrimidineColourScheme;
import jalview.schemes.StrandColourScheme;
import jalview.schemes.TaylorColourScheme;
import jalview.schemes.TurnColourScheme;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Vector;
MenuItem editGroupName = new MenuItem();
- protected MenuItem clustalColour = new MenuItem();
+ CheckboxMenuItem noColour = new CheckboxMenuItem();
- protected MenuItem zappoColour = new MenuItem();
+ protected CheckboxMenuItem clustalColour = new CheckboxMenuItem();
- protected MenuItem taylorColour = new MenuItem();
+ protected CheckboxMenuItem zappoColour = new CheckboxMenuItem();
- protected MenuItem hydrophobicityColour = new MenuItem();
+ protected CheckboxMenuItem taylorColour = new CheckboxMenuItem();
- protected MenuItem helixColour = new MenuItem();
+ protected CheckboxMenuItem hydrophobicityColour = new CheckboxMenuItem();
- protected MenuItem strandColour = new MenuItem();
+ protected CheckboxMenuItem helixColour = new CheckboxMenuItem();
- protected MenuItem turnColour = new MenuItem();
+ protected CheckboxMenuItem strandColour = new CheckboxMenuItem();
- protected MenuItem buriedColour = new MenuItem();
+ protected CheckboxMenuItem turnColour = new CheckboxMenuItem();
- protected CheckboxMenuItem abovePIDColour = new CheckboxMenuItem();
+ protected CheckboxMenuItem buriedColour = new CheckboxMenuItem();
+
+ protected CheckboxMenuItem PIDColour = new CheckboxMenuItem();
+
+ protected CheckboxMenuItem BLOSUM62Colour = new CheckboxMenuItem();
+
+ CheckboxMenuItem nucleotideColour = new CheckboxMenuItem();
+
+ CheckboxMenuItem purinePyrimidineColour = new CheckboxMenuItem();
protected MenuItem userDefinedColour = new MenuItem();
- protected MenuItem PIDColour = new MenuItem();
+ protected CheckboxMenuItem abovePIDColour = new CheckboxMenuItem();
- protected MenuItem BLOSUM62Colour = new MenuItem();
+ MenuItem modifyPID = new MenuItem();
- MenuItem noColourmenuItem = new MenuItem();
+ protected CheckboxMenuItem conservationColour = new CheckboxMenuItem();
- protected CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();
+ MenuItem modifyConservation = new MenuItem();
+
+ MenuItem noColourmenuItem = new MenuItem();
final AlignmentPanel ap;
MenuItem createGroupMenuItem = new MenuItem();
- MenuItem nucleotideMenuItem = new MenuItem();
-
Menu colourMenu = new Menu();
CheckboxMenuItem showBoxes = new CheckboxMenuItem();
Menu menu1 = new Menu();
public APopupMenu(AlignmentPanel apanel, final SequenceI seq,
- Vector<String> links)
+ List<String> links)
{
// /////////////////////////////////////////////////////////
// If this is activated from the sequence panel, the user may want to
e.printStackTrace();
}
- for (String ff : FileFormat.getWritableFormats(true))
+ for (String ff : FileFormats.getInstance().getWritableFormats(true))
{
MenuItem item = new MenuItem(ff);
SequenceGroup sg = ap.av.getSelectionGroup();
if (sg != null && sg.getSize() > 0)
{
+ if (sg.isNucleotide())
+ {
+ conservationColour.setEnabled(false);
+ clustalColour.setEnabled(false);
+ BLOSUM62Colour.setEnabled(false);
+ zappoColour.setEnabled(false);
+ taylorColour.setEnabled(false);
+ hydrophobicityColour.setEnabled(false);
+ helixColour.setEnabled(false);
+ strandColour.setEnabled(false);
+ turnColour.setEnabled(false);
+ buriedColour.setEnabled(false);
+ }
+ else
+ {
+ purinePyrimidineColour.setEnabled(false);
+ nucleotideColour.setEnabled(false);
+ }
editGroupName.setLabel(MessageManager.formatMessage(
"label.name_param", new Object[] { sg.getName() }));
showText.setState(sg.getDisplayText());
{
menu1.setLabel(MessageManager.getString("action.edit_group"));
groupMenu.remove(createGroupMenuItem);
+ if (sg.cs != null)
+ {
+ abovePIDColour.setState(sg.cs.getThreshold() > 0);
+ conservationColour.setState(sg.cs.conservationApplied());
+ modifyPID.setEnabled(abovePIDColour.getState());
+ modifyConservation.setEnabled(conservationColour.getState());
+ }
}
-
+ setSelectedColour(sg.cs);
}
else
{
}
/**
+ * Select the menu item (if any) matching the current colour scheme. This
+ * works by matching the menu item name (not display text) to the canonical
+ * name of the colour scheme.
+ *
+ * @param cs
+ */
+ protected void setSelectedColour(ResidueShaderI cs)
+ {
+ if (cs == null || cs.getColourScheme() == null)
+ {
+ noColour.setState(true);
+ }
+ else
+ {
+ String name = cs.getColourScheme().getSchemeName();
+ for (int i = 0; i < colourMenu.getItemCount(); i++)
+ {
+ MenuItem item = colourMenu.getItem(i);
+ if (item instanceof CheckboxMenuItem)
+ {
+ if (name.equals(item.getName()))
+ {
+ ((CheckboxMenuItem) item).setState(true);
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Adds a 'Link' menu item with a sub-menu item for each hyperlink provided.
*
* @param seq
* Temporary store to hold distinct calcId / type pairs for the tooltip.
* Using TreeMap means calcIds are shown in alphabetical order.
*/
- Map<String, String> tipEntries = new TreeMap<String, String>();
+ SortedMap<String, String> tipEntries = new TreeMap<String, String>();
final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<SequenceI, List<AlignmentAnnotation>>();
AlignmentI al = this.ap.av.getAlignment();
AlignmentUtils.findAddableReferenceAnnotations(forSequences,
linkMenu.add(item);
}
+ /**
+ * Actions on selecting / unselecting a checkbox menu item
+ */
@Override
public void itemStateChanged(ItemEvent evt)
{
- if (evt.getSource() == abovePIDColour)
- {
- abovePIDColour_itemStateChanged();
- }
- else if (evt.getSource() == showColourText)
- {
- showColourText_itemStateChanged();
- }
- else if (evt.getSource() == showText)
+ Object source = evt.getSource();
+ if (source == noColour)
{
- showText_itemStateChanged();
+ noColourmenuItem_actionPerformed();
}
- else if (evt.getSource() == showBoxes)
+ else if (source == clustalColour)
{
- showBoxes_itemStateChanged();
+ clustalColour_actionPerformed();
}
- else if (evt.getSource() == displayNonconserved)
+ else if (source == BLOSUM62Colour)
{
- this.showNonconserved_itemStateChanged();
+ BLOSUM62Colour_actionPerformed();
}
- }
-
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- Object source = evt.getSource();
- if (source == clustalColour)
+ else if (evt.getSource() == PIDColour)
{
- clustalColour_actionPerformed();
+ PIDColour_actionPerformed();
}
else if (source == zappoColour)
{
{
buriedColour_actionPerformed();
}
- else if (source == nucleotideMenuItem)
+ else if (source == nucleotideColour)
{
nucleotideMenuItem_actionPerformed();
}
-
- else if (source == userDefinedColour)
+ else if (source == purinePyrimidineColour)
{
- userDefinedColour_actionPerformed();
+ purinePyrimidineColour_actionPerformed();
}
- else if (source == PIDColour)
+ else if (source == abovePIDColour)
{
- PIDColour_actionPerformed();
+ abovePIDColour_itemStateChanged();
}
- else if (source == BLOSUM62Colour)
+ else if (source == conservationColour)
{
- BLOSUM62Colour_actionPerformed();
+ conservationMenuItem_itemStateChanged();
}
- else if (source == noColourmenuItem)
+ else if (source == showColourText)
{
- noColourmenuItem_actionPerformed();
+ showColourText_itemStateChanged();
}
- else if (source == conservationMenuItem)
+ else if (source == showText)
+ {
+ showText_itemStateChanged();
+ }
+ else if (source == showBoxes)
+ {
+ showBoxes_itemStateChanged();
+ }
+ else if (source == displayNonconserved)
+ {
+ this.showNonconserved_itemStateChanged();
+ }
+ }
+
+ /**
+ * Actions on clicking a menu item
+ */
+ @Override
+ public void actionPerformed(ActionEvent evt)
+ {
+ Object source = evt.getSource();
+ if (source == userDefinedColour)
+ {
+ userDefinedColour_actionPerformed();
+ }
+ else if (source == modifyConservation)
{
conservationMenuItem_itemStateChanged();
}
+ else if (source == modifyPID)
+ {
+ abovePIDColour_itemStateChanged();
+ }
else if (source == unGroupMenuItem)
{
unGroupMenuItem_actionPerformed();
// now returns a full copy of sequence data
// TODO consider using getSequenceSelection instead here
- FileFormat fileFormat = FileFormat.valueOf(e.getActionCommand());
+ FileFormatI fileFormat = FileFormats.getInstance().forName(
+ e.getActionCommand());
cap.setText(new AppletFormatAdapter().formatSequences(fileFormat,
ap.av.getShowJVSuffix(), ap, true));
void addPDB()
{
Vector<PDBEntry> pdbs = seq.getAllPDBEntries();
- if (pdbs != null&& !pdbs.isEmpty())
+ if (pdbs != null && !pdbs.isEmpty())
{
PDBEntry entry = pdbs.firstElement();
if (ap.av.applet.jmolAvailable)
{
- new jalview.appletgui.AppletJmol(entry, new SequenceI[] { seq },
- null, ap, DataSourceType.URL);
+ new AppletJmol(entry, new SequenceI[] { seq }, null, ap,
+ DataSourceType.URL);
}
else
{
cap.setPDBImport(seq);
Frame frame = new Frame();
frame.add(cap);
- jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage(
+ JalviewLite.addFrame(frame, MessageManager.formatMessage(
"label.paste_pdb_file_for_sequence",
new Object[] { seq.getName() }), 400, 300);
}
.getString("action.create_group"));
createGroupMenuItem.addActionListener(this);
- nucleotideMenuItem.setLabel(MessageManager
- .getString("label.nucleotide"));
- nucleotideMenuItem.addActionListener(this);
- conservationMenuItem.addItemListener(this);
- abovePIDColour.addItemListener(this);
+ modifyPID.setEnabled(abovePIDColour.getState());
+ modifyConservation.setEnabled(conservationColour.getState());
colourMenu.setLabel(MessageManager.getString("label.group_colour"));
showBoxes.setLabel(MessageManager.getString("action.boxes"));
showBoxes.setState(true);
sequenceDetails.addActionListener(this);
selSeqDetails.addActionListener(this);
displayNonconserved.setLabel(MessageManager
- .getString("label.show_non_conversed"));
+ .getString("label.show_non_conserved"));
displayNonconserved.setState(false);
displayNonconserved.addItemListener(this);
showText.setLabel(MessageManager.getString("action.text"));
groupMenu.add(unGroupMenuItem);
groupMenu.add(menu1);
- colourMenu.add(noColourmenuItem);
+ colourMenu.add(noColour);
colourMenu.add(clustalColour);
colourMenu.add(BLOSUM62Colour);
colourMenu.add(PIDColour);
colourMenu.add(strandColour);
colourMenu.add(turnColour);
colourMenu.add(buriedColour);
- colourMenu.add(nucleotideMenuItem);
+ colourMenu.add(nucleotideColour);
+ colourMenu.add(purinePyrimidineColour);
colourMenu.add(userDefinedColour);
colourMenu.addSeparator();
+ colourMenu.add(conservationColour);
+ colourMenu.add(modifyConservation);
colourMenu.add(abovePIDColour);
- colourMenu.add(conservationMenuItem);
+ colourMenu.add(modifyPID);
- noColourmenuItem.setLabel(MessageManager.getString("label.none"));
- noColourmenuItem.addActionListener(this);
+ noColour.setLabel(MessageManager.getString("label.none"));
+ noColour.addItemListener(this);
+ /*
+ * setName allows setSelectedColour to do its thing
+ */
clustalColour.setLabel(MessageManager
- .getString("label.clustalx_colours"));
- clustalColour.addActionListener(this);
- zappoColour.setLabel(MessageManager.getString("label.zappo"));
- zappoColour.addActionListener(this);
- taylorColour.setLabel(MessageManager.getString("label.taylor"));
- taylorColour.addActionListener(this);
+ .getString("label.colourScheme_clustal"));
+ clustalColour.setName(JalviewColourScheme.Clustal.toString());
+ clustalColour.addItemListener(this);
+ BLOSUM62Colour.setLabel(MessageManager
+ .getString("label.colourScheme_blosum62"));
+ BLOSUM62Colour.setName(JalviewColourScheme.Blosum62.toString());
+ BLOSUM62Colour.addItemListener(this);
+ PIDColour.setLabel(MessageManager
+ .getString("label.colourScheme_%_identity"));
+ PIDColour.setName(JalviewColourScheme.PID.toString());
+ PIDColour.addItemListener(this);
+ zappoColour.setLabel(MessageManager
+ .getString("label.colourScheme_zappo"));
+ zappoColour.setName(JalviewColourScheme.Zappo.toString());
+ zappoColour.addItemListener(this);
+ taylorColour.setLabel(MessageManager
+ .getString("label.colourScheme_taylor"));
+ taylorColour.setName(JalviewColourScheme.Taylor.toString());
+ taylorColour.addItemListener(this);
hydrophobicityColour.setLabel(MessageManager
- .getString("label.hydrophobicity"));
- hydrophobicityColour.addActionListener(this);
- helixColour
- .setLabel(MessageManager.getString("label.helix_propensity"));
- helixColour.addActionListener(this);
+ .getString("label.colourScheme_hydrophobic"));
+ hydrophobicityColour
+ .setName(JalviewColourScheme.Hydrophobic.toString());
+ hydrophobicityColour.addItemListener(this);
+ helixColour.setLabel(MessageManager
+ .getString("label.colourScheme_helix_propensity"));
+ helixColour.setName(JalviewColourScheme.Helix.toString());
+ helixColour.addItemListener(this);
strandColour.setLabel(MessageManager
- .getString("label.strand_propensity"));
- strandColour.addActionListener(this);
- turnColour.setLabel(MessageManager.getString("label.turn_propensity"));
- turnColour.addActionListener(this);
- buriedColour.setLabel(MessageManager.getString("label.buried_index"));
- buriedColour.addActionListener(this);
- abovePIDColour.setLabel(MessageManager
- .getString("label.above_identity_percentage"));
+ .getString("label.colourScheme_strand_propensity"));
+ strandColour.setName(JalviewColourScheme.Strand.toString());
+ strandColour.addItemListener(this);
+ turnColour.setLabel(MessageManager
+ .getString("label.colourScheme_turn_propensity"));
+ turnColour.setName(JalviewColourScheme.Turn.toString());
+ turnColour.addItemListener(this);
+ buriedColour.setLabel(MessageManager
+ .getString("label.colourScheme_buried_index"));
+ buriedColour.setName(JalviewColourScheme.Buried.toString());
+ buriedColour.addItemListener(this);
+ nucleotideColour.setLabel(MessageManager
+ .getString("label.colourScheme_nucleotide"));
+ nucleotideColour.setName(JalviewColourScheme.Nucleotide.toString());
+ nucleotideColour.addItemListener(this);
+ purinePyrimidineColour.setLabel(MessageManager
+ .getString("label.colourScheme_purine/pyrimidine"));
+ purinePyrimidineColour.setName(JalviewColourScheme.PurinePyrimidine
+ .toString());
+ purinePyrimidineColour.addItemListener(this);
userDefinedColour.setLabel(MessageManager
.getString("action.user_defined"));
userDefinedColour.addActionListener(this);
- PIDColour.setLabel(MessageManager
- .getString("label.percentage_identity"));
+
+ abovePIDColour.setLabel(MessageManager
+ .getString("label.above_identity_threshold"));
+ abovePIDColour.addItemListener(this);
+ modifyPID.setLabel(MessageManager
+ .getString("label.modify_identity_threshold"));
+ modifyPID.addActionListener(this);
+ conservationColour.setLabel(MessageManager
+ .getString("action.by_conservation"));
+ conservationColour.addItemListener(this);
+ modifyConservation.setLabel(MessageManager
+ .getString("label.modify_conservation_threshold"));
+ modifyConservation.addActionListener(this);
+
PIDColour.addActionListener(this);
- BLOSUM62Colour.setLabel("BLOSUM62");
BLOSUM62Colour.addActionListener(this);
- conservationMenuItem.setLabel(MessageManager
- .getString("label.conservation"));
editMenu.add(copy);
copy.addActionListener(this);
protected void clustalColour_actionPerformed()
{
SequenceGroup sg = getGroup();
- sg.cs = new ClustalxColourScheme(sg, ap.av.getHiddenRepSequences());
+ sg.cs = new ResidueShader(new ClustalxColourScheme(sg,
+ ap.av.getHiddenRepSequences()));
refresh();
}
protected void zappoColour_actionPerformed()
{
- getGroup().cs = new ZappoColourScheme();
+ getGroup().cs = new ResidueShader(new ZappoColourScheme());
refresh();
}
protected void taylorColour_actionPerformed()
{
- getGroup().cs = new TaylorColourScheme();
+ getGroup().cs = new ResidueShader(new TaylorColourScheme());
refresh();
}
protected void hydrophobicityColour_actionPerformed()
{
- getGroup().cs = new HydrophobicColourScheme();
+ getGroup().cs = new ResidueShader(new HydrophobicColourScheme());
refresh();
}
protected void helixColour_actionPerformed()
{
- getGroup().cs = new HelixColourScheme();
+ getGroup().cs = new ResidueShader(new HelixColourScheme());
refresh();
}
protected void strandColour_actionPerformed()
{
- getGroup().cs = new StrandColourScheme();
+ getGroup().cs = new ResidueShader(new StrandColourScheme());
refresh();
}
protected void turnColour_actionPerformed()
{
- getGroup().cs = new TurnColourScheme();
+ getGroup().cs = new ResidueShader(new TurnColourScheme());
refresh();
}
protected void buriedColour_actionPerformed()
{
- getGroup().cs = new BuriedColourScheme();
+ getGroup().cs = new ResidueShader(new BuriedColourScheme());
refresh();
}
public void nucleotideMenuItem_actionPerformed()
{
- getGroup().cs = new NucleotideColourScheme();
+ getGroup().cs = new ResidueShader(new NucleotideColourScheme());
+ refresh();
+ }
+
+ public void purinePyrimidineColour_actionPerformed()
+ {
+ getGroup().cs = new ResidueShader(
+ new PurinePyrimidineColourScheme());
refresh();
}
else
// remove PIDColouring
{
+ SliderPanel.hidePIDSlider();
sg.cs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
}
-
+ modifyPID.setEnabled(abovePIDColour.getState());
refresh();
-
}
protected void userDefinedColour_actionPerformed()
protected void PIDColour_actionPerformed()
{
SequenceGroup sg = getGroup();
- sg.cs = new PIDColourScheme();
+ sg.cs = new ResidueShader(new PIDColourScheme());
sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av
.getHiddenRepSequences()), 0, ap.av.getAlignment().getWidth()));
refresh();
{
SequenceGroup sg = getGroup();
- sg.cs = new Blosum62ColourScheme();
+ sg.cs = new ResidueShader(new Blosum62ColourScheme());
sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av
.getHiddenRepSequences()), 0, ap.av.getAlignment().getWidth()));
return;
}
- if (conservationMenuItem.getState())
+ if (conservationColour.getState())
{
- sg.cs.setConservation(Conservation.calculateConservation("Group", sg
+ Conservation conservation = Conservation.calculateConservation(
+ "Group", sg
.getSequences(ap.av.getHiddenRepSequences()), 0, ap.av
.getAlignment().getWidth(), false, ap.av.getConsPercGaps(),
- false));
+ false);
+ sg.getGroupColourScheme().setConservation(conservation);
SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
SliderPanel.showConservationSlider();
}
else
// remove ConservationColouring
{
+ SliderPanel.hideConservationSlider();
sg.cs.setConservation(null);
}
-
+ modifyConservation.setEnabled(conservationColour.getState());
refresh();
}
import jalview.io.DataSourceType;
import jalview.io.FeaturesFile;
import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
import jalview.io.TCoffeeScoreFile;
import jalview.schemes.Blosum62ColourScheme;
import jalview.schemes.BuriedColourScheme;
import jalview.schemes.NucleotideColourScheme;
import jalview.schemes.PIDColourScheme;
import jalview.schemes.PurinePyrimidineColourScheme;
-import jalview.schemes.RNAHelicesColourChooser;
+import jalview.schemes.RNAHelicesColour;
import jalview.schemes.StrandColourScheme;
import jalview.schemes.TCoffeeColourScheme;
import jalview.schemes.TaylorColourScheme;
}
if (viewport.getAlignment().isNucleotide())
{
+ conservationMenuItem.setEnabled(false);
+ clustalColour.setEnabled(false);
+ BLOSUM62Colour.setEnabled(false);
+ zappoColour.setEnabled(false);
+ taylorColour.setEnabled(false);
+ hydrophobicityColour.setEnabled(false);
+ helixColour.setEnabled(false);
+ strandColour.setEnabled(false);
+ turnColour.setEnabled(false);
+ buriedColour.setEnabled(false);
viewport.updateStrucConsensus(alignPanel);
if (viewport.getAlignment().hasRNAStructure())
{
{
RNAHelixColour.setEnabled(false);
purinePyrimidineColour.setEnabled(false);
+ nucleotideColour.setEnabled(false);
}
// Some JVMS send keyevents to Top frame or lowest panel,
// Havent worked out why yet. So add to both this frame and seqCanvas for
// }
else if (source == RNAHelixColour)
{
- new RNAHelicesColourChooser(viewport, alignPanel);
+ changeColour(new RNAHelicesColour(viewport.getAlignment()));
+ // new RNAHelicesColourChooser(viewport, alignPanel);
}
else if (source == modifyPID)
{
"label.alignment_output_command",
new Object[] { e.getActionCommand() }), 600, 500);
- FileFormat fileFormat = FileFormat.valueOf(e.getActionCommand());
+ FileFormatI fileFormat = FileFormats.getInstance().forName(
+ e.getActionCommand());
cap.setText(new AppletFormatAdapter(alignPanel).formatSequences(
fileFormat, viewport.getAlignment(),
viewport.getShowJVSuffix()));
@Override
public void changeColour(ColourSchemeI cs)
{
-
- if (cs != null)
- {
- if (viewport.getAbovePIDThreshold())
- {
- viewport.setThreshold(SliderPanel.setPIDSliderSource(alignPanel,
- cs, "Background"));
- }
-
- if (viewport.getConservationSelected())
- {
- cs.setConservationApplied(true);
- viewport.setIncrement(SliderPanel.setConservationSlider(alignPanel,
- cs, "Background"));
- }
- else
- {
- cs.setConservationApplied(false);
- }
- }
viewport.setGlobalColourScheme(cs);
alignPanel.paintAlignment(true);
&& viewport.getGlobalColourScheme() != null)
{
SliderPanel.setPIDSliderSource(alignPanel,
- viewport.getGlobalColourScheme(), "Background");
+ viewport.getResidueShading(), alignPanel.getViewName());
SliderPanel.showPIDSlider();
}
}
&& viewport.getGlobalColourScheme() != null)
{
SliderPanel.setConservationSlider(alignPanel,
- viewport.getGlobalColourScheme(), "Background");
+ viewport.getResidueShading(), alignPanel.getViewName());
SliderPanel.showConservationSlider();
}
}
protected void conservationMenuItem_actionPerformed()
{
- viewport.setConservationSelected(conservationMenuItem.getState());
+ boolean selected = conservationMenuItem.getState();
+ modifyConservation.setEnabled(selected);
+ viewport.setConservationSelected(selected);
- viewport.setAbovePIDThreshold(false);
- abovePIDThreshold.setState(false);
+ // viewport.setAbovePIDThreshold(false);
+ // abovePIDThreshold.setState(false);
changeColour(viewport.getGlobalColourScheme());
- modifyConservation_actionPerformed();
+ if (selected)
+ {
+ modifyConservation_actionPerformed();
+ }
+ else
+ {
+ SliderPanel.hideConservationSlider();
+ }
}
public void abovePIDThreshold_actionPerformed()
{
- viewport.setAbovePIDThreshold(abovePIDThreshold.getState());
-
- conservationMenuItem.setState(false);
- viewport.setConservationSelected(false);
+ boolean selected = abovePIDThreshold.getState();
+ modifyPID.setEnabled(selected);
+ viewport.setAbovePIDThreshold(selected);
+ // conservationMenuItem.setState(false);
+ // viewport.setConservationSelected(false);
changeColour(viewport.getGlobalColourScheme());
- modifyPID_actionPerformed();
+ if (selected)
+ {
+ modifyPID_actionPerformed();
+ }
+ else
+ {
+ SliderPanel.hidePIDSlider();
+ }
}
public void sortPairwiseMenuItem_actionPerformed()
inputText.addActionListener(this);
Menu outputTextboxMenu = new Menu(
MessageManager.getString("label.out_to_textbox"));
- for (String ff : FileFormat.getWritableFormats(true))
+ for (String ff : FileFormats.getInstance().getWritableFormats(true))
{
MenuItem item = new MenuItem(ff);
.getString("label.colour_text"));
colourTextMenuItem.addItemListener(this);
displayNonconservedMenuItem.setLabel(MessageManager
- .getString("label.show_non_conversed"));
+ .getString("label.show_non_conserved"));
displayNonconservedMenuItem.addItemListener(this);
wrapMenuItem.setLabel(MessageManager.getString("action.wrap"));
wrapMenuItem.addItemListener(this);
.getString("label.apply_colour_to_all_groups"));
applyToAllGroups.setState(true);
applyToAllGroups.addItemListener(this);
- clustalColour.setLabel(MessageManager.getString("label.clustalx"));
+ clustalColour.setLabel(MessageManager
+ .getString("label.colourScheme_clustal"));
clustalColour.addActionListener(this);
- zappoColour.setLabel(MessageManager.getString("label.zappo"));
+ zappoColour.setLabel(MessageManager
+ .getString("label.colourScheme_zappo"));
zappoColour.addActionListener(this);
- taylorColour.setLabel(MessageManager.getString("label.taylor"));
+ taylorColour.setLabel(MessageManager
+ .getString("label.colourScheme_taylor"));
taylorColour.addActionListener(this);
hydrophobicityColour.setLabel(MessageManager
- .getString("label.hydrophobicity"));
+ .getString("label.colourScheme_hydrophobic"));
hydrophobicityColour.addActionListener(this);
- helixColour
- .setLabel(MessageManager.getString("label.helix_propensity"));
+ helixColour.setLabel(MessageManager
+ .getString("label.colourScheme_helix_propensity"));
helixColour.addActionListener(this);
strandColour.setLabel(MessageManager
- .getString("label.strand_propensity"));
+ .getString("label.colourScheme_strand_propensity"));
strandColour.addActionListener(this);
- turnColour.setLabel(MessageManager.getString("label.turn_propensity"));
+ turnColour.setLabel(MessageManager
+ .getString("label.colourScheme_turn_propensity"));
turnColour.addActionListener(this);
- buriedColour.setLabel(MessageManager.getString("label.buried_index"));
+ buriedColour.setLabel(MessageManager
+ .getString("label.colourScheme_buried_index"));
buriedColour.addActionListener(this);
purinePyrimidineColour.setLabel(MessageManager
- .getString("label.purine_pyrimidine"));
+ .getString("label.colourScheme_purine/pyrimidine"));
purinePyrimidineColour.addActionListener(this);
// RNAInteractionColour.setLabel(MessageManager
// .getString("label.rna_interaction"));
// RNAInteractionColour.addActionListener(this);
RNAHelixColour.setLabel(MessageManager
- .getString("action.by_rna_helixes"));
+ .getString("label.colourScheme_rna_helices"));
RNAHelixColour.addActionListener(this);
userDefinedColour.setLabel(MessageManager
.getString("action.user_defined"));
userDefinedColour.addActionListener(this);
PIDColour.setLabel(MessageManager
- .getString("label.percentage_identity"));
+ .getString("label.colourScheme_%_identity"));
PIDColour.addActionListener(this);
BLOSUM62Colour.setLabel(MessageManager
- .getString("label.blosum62_score"));
+ .getString("label.colourScheme_blosum62"));
BLOSUM62Colour.addActionListener(this);
- tcoffeeColour
- .setLabel(MessageManager.getString("label.tcoffee_scores"));
+ tcoffeeColour.setLabel(MessageManager
+ .getString("label.colourScheme_t-coffee_scores"));
// it will be enabled only if a score file is provided
tcoffeeColour.setEnabled(false);
tcoffeeColour.addActionListener(this);
abovePIDThreshold.setLabel(MessageManager
.getString("label.above_identity_threshold"));
abovePIDThreshold.addItemListener(this);
- nucleotideColour.setLabel(MessageManager.getString("label.nucleotide"));
+ nucleotideColour.setLabel(MessageManager
+ .getString("label.colourScheme_nucleotide"));
nucleotideColour.addActionListener(this);
modifyPID.setLabel(MessageManager
.getString("label.modify_identity_threshold"));
+ modifyPID.setEnabled(abovePIDThreshold.getState());
modifyPID.addActionListener(this);
modifyConservation.setLabel(MessageManager
.getString("label.modify_conservation_threshold"));
+ modifyConservation.setEnabled(conservationMenuItem.getState());
modifyConservation.addActionListener(this);
annotationColour.setLabel(MessageManager
.getString("action.by_annotation"));
.getString("label.neighbour_joining_identity"));
neighbourTreeMenuItem.addActionListener(this);
avDistanceTreeBlosumMenuItem.setLabel(MessageManager
- .getString("label.average_distance_bloslum62"));
+ .getString("label.average_distance_blosum62"));
avDistanceTreeBlosumMenuItem.addActionListener(this);
njTreeBlosumMenuItem.setLabel(MessageManager
.getString("label.neighbour_blosum62"));
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.renderer.ResidueShader;
import jalview.schemes.ColourSchemeProperty;
import jalview.schemes.UserColourScheme;
import jalview.structure.CommandListener;
if (colour != null)
{
- globalColourScheme = ColourSchemeProperty.getColour(alignment,
- colour);
- if (globalColourScheme != null)
+ residueShading = new ResidueShader(
+ ColourSchemeProperty.getColourScheme(alignment, colour));
+ if (residueShading != null)
{
- globalColourScheme.setConsensus(hconsensus);
+ residueShading.setConsensus(hconsensus);
}
}
if (applet.getParameter("userDefinedColour") != null)
{
- ((UserColourScheme) globalColourScheme).parseAppletParameter(applet
- .getParameter("userDefinedColour"));
+ residueShading = new ResidueShader(
+ new UserColourScheme(
+ applet.getParameter("userDefinedColour")));
}
}
initAutoAnnotation();
oldgroupColours = new Hashtable();
for (SequenceGroup sg : ap.av.getAlignment().getGroups())
{
- if (sg.cs != null)
+ if (sg.getColourScheme() != null)
{
- oldgroupColours.put(sg, sg.cs);
+ oldgroupColours.put(sg, sg.getColourScheme());
}
else
{
AnnotationColourGradient acg = null;
if (currentColours.getState())
{
- acg = new AnnotationColourGradient(currentAnnotation,
- av.getGlobalColourScheme(), aboveThreshold);
}
else
{
for (SequenceGroup sg : ap.av.getAlignment().getGroups())
{
- if (sg.cs == null)
+ if (sg.getColourScheme() == null)
{
continue;
}
if (currentColours.getState())
{
- sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
- aboveThreshold);
+ sg.setColourScheme(new AnnotationColourGradient(
+ currentAnnotation, sg.getColourScheme(), aboveThreshold));
}
else
{
- sg.cs = new AnnotationColourGradient(currentAnnotation,
- minColour.getBackground(), maxColour.getBackground(),
- aboveThreshold);
+ sg.setColourScheme(new AnnotationColourGradient(
+ currentAnnotation, minColour.getBackground(), maxColour
+ .getBackground(), aboveThreshold));
}
}
Object cs = oldgroupColours.get(sg);
if (cs instanceof ColourSchemeI)
{
- sg.cs = (ColourSchemeI) cs;
+ sg.setColourScheme((ColourSchemeI) cs);
}
else
{
// probably the "null" string we set it to if it was null originally.
- sg.cs = null;
+ sg.setColourScheme(null);
}
}
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
-import jalview.io.FileParse;
import jalview.io.DataSourceType;
+import jalview.io.FileParse;
import jalview.io.StructureFile;
import jalview.schemes.BuriedColourScheme;
import jalview.schemes.HelixColourScheme;
MenuItem charge = new MenuItem(
MessageManager.getString("label.charge_cysteine"));
- MenuItem zappo = new MenuItem(MessageManager.getString("label.zappo"));
+ MenuItem zappo = new MenuItem(
+ MessageManager.getString("label.colourScheme_zappo"));
- MenuItem taylor = new MenuItem(MessageManager.getString("label.taylor"));
+ MenuItem taylor = new MenuItem(
+ MessageManager.getString("label.colourScheme_taylor"));
MenuItem hydro = new MenuItem(
- MessageManager.getString("label.hydrophobicity"));
+ MessageManager.getString("label.colourScheme_hydrophobic"));
MenuItem helix = new MenuItem(
- MessageManager.getString("label.helix_propensity"));
+ MessageManager.getString("label.colourScheme_helix_propensity"));
MenuItem strand = new MenuItem(
- MessageManager.getString("label.strand_propensity"));
+ MessageManager.getString("label.colourScheme_strand_propensity"));
MenuItem turn = new MenuItem(
- MessageManager.getString("label.turn_propensity"));
+ MessageManager.getString("label.colourScheme_turn_propensity"));
MenuItem buried = new MenuItem(
- MessageManager.getString("label.buried_index"));
+ MessageManager.getString("label.colourScheme_buried_index"));
MenuItem purinepyrimidine = new MenuItem(
- MessageManager.getString("label.purine_pyrimidine"));
+ MessageManager.getString("label.colourScheme_purine/pyrimidine"));
MenuItem user = new MenuItem(
MessageManager.getString("label.user_defined_colours"));
public void updateTitleAndMenus()
{
- if (jmb.fileLoadingError != null && jmb.fileLoadingError.length() > 0)
+ if (jmb.hasFileLoadingError())
{
repaint();
return;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
-import jalview.io.AlignmentFileI;
+import jalview.io.AlignmentFileReaderI;
import jalview.io.AnnotationFile;
import jalview.io.AppletFormatAdapter;
import jalview.io.DataSourceType;
AlignFrame alignFrame;
- AlignmentFileI source = null;
+ AlignmentFileReaderI source = null;
public CutAndPasteTransfer(boolean forImport, AlignFrame alignFrame)
{
import jalview.datamodel.SequenceI;
import jalview.io.FeaturesFile;
import jalview.schemes.FeatureColour;
-import jalview.schemes.UserColourScheme;
+import jalview.util.ColorUtils;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
FeatureColourI col = getFeatureStyle(name.getText());
if (col == null)
{
- Color generatedColour = UserColourScheme
+ Color generatedColour = ColorUtils
.createColourFromName(name.getText());
col = new FeatureColour(generatedColour);
}
*/
package jalview.appletgui;
-import static jalview.util.UrlConstants.EMBLEBI_STRING;
-import static jalview.util.UrlConstants.SRS_STRING;
-
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.util.UrlLink;
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.applet.AppletUrlProviderFactory;
import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
+import java.util.HashMap;
import java.util.List;
-import java.util.Vector;
public class IdPanel extends Panel implements MouseListener,
MouseMotionListener
boolean mouseDragging = false;
- java.util.Vector links = new java.util.Vector();
+ UrlProviderI urlProvider = null;
public IdPanel(AlignViewport av, AlignmentPanel parent)
{
String label, url;
// TODO: add in group link parameter
+
+ // make a list of label,url pairs
+ HashMap<String, String> urlList = new HashMap<String, String>();
if (av.applet != null)
{
for (int i = 1; i < 10; i++)
label = av.applet.getParameter("linkLabel_" + i);
url = av.applet.getParameter("linkURL_" + i);
- if (label != null && url != null)
+ // only add non-null parameters
+ if (label != null)
{
- links.addElement(label + "|" + url);
+ urlList.put(label, url);
}
-
}
- }
- {
- // upgrade old SRS link
- int srsPos = links.indexOf(SRS_STRING);
- if (srsPos > -1)
+
+ if (!urlList.isEmpty())
{
- links.setElementAt(EMBLEBI_STRING, srsPos);
+ // set default as first entry in list
+ String defaultUrl = av.applet.getParameter("linkLabel_1");
+ UrlProviderFactoryI factory = new AppletUrlProviderFactory(
+ defaultUrl, urlList);
+ urlProvider = factory.createUrlProvider();
}
}
- if (links.size() < 1)
- {
- links = new java.util.Vector();
- links.addElement(EMBLEBI_STRING);
- }
}
Tooltip tooltip;
return;
}
- // DEFAULT LINK IS FIRST IN THE LINK LIST
+ // get the sequence details
int seq = alignPanel.seqPanel.findSeq(e);
SequenceI sq = av.getAlignment().getSequenceAt(seq);
if (sq == null)
}
String id = sq.getName();
- String target = null;
- String url = null;
- int i = 0;
- while (url == null && i < links.size())
- {
- // DEFAULT LINK IS FIRST IN THE LINK LIST
- // BUT IF ITS A REGEX AND DOES NOT MATCH THE NEXT ONE WILL BE TRIED
- url = links.elementAt(i++).toString();
- jalview.util.UrlLink urlLink = null;
- try
- {
- urlLink = new UrlLink(url);
- target = urlLink.getTarget();
- } catch (Exception foo)
- {
- System.err.println("Exception for URLLink '" + url + "'");
- foo.printStackTrace();
- url = null;
- continue;
- }
-
- if (urlLink.usesDBAccession())
- {
- // this URL requires an accession id, not the name of a sequence
- url = null;
- continue;
- }
-
- if (!urlLink.isValid())
- {
- System.err.println(urlLink.getInvalidMessage());
- url = null;
- continue;
- }
-
- String urls[] = urlLink.makeUrls(id, true);
- if (urls == null || urls[0] == null || urls[0].length() < 1)
- {
- url = null;
- continue;
- }
- // just take first URL made from regex
- url = urls[1];
- }
+ // get the default url with the sequence details filled in
+ String url = urlProvider.getPrimaryUrl(id);
+ String target = urlProvider.getPrimaryTarget(id);
try
{
-
alignPanel.alignFrame.showURL(url, target);
} catch (Exception ex)
{
// build a new links menu based on the current links + any non-positional
// features
- Vector nlinks = new Vector();
- for (int l = 0, lSize = links.size(); l < lSize; l++)
- {
- nlinks.addElement(links.elementAt(l));
- }
+ List<String> nlinks = urlProvider.getLinksForMenu();
+
SequenceFeature sf[] = sq == null ? null : sq.getSequenceFeatures();
for (int sl = 0; sf != null && sl < sf.length; sl++)
{
{
for (int l = 0, lSize = sf[sl].links.size(); l < lSize; l++)
{
- nlinks.addElement(sf[sl].links.elementAt(l));
+ nlinks.add(sf[sl].links.elementAt(l));
}
}
}
slider.addAdjustmentListener(new AdjustmentListener()
{
+ @Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
- valueField.setText(slider.getValue() + "");
+ valueField.setText(String.valueOf(slider.getValue()));
sliderValueChanged();
}
});
*
* @return DOCUMENT ME!
*/
+ @Override
public void run()
{
label.setText(MessageManager.getString("label.calculating"));
}
+ @Override
public void applyButton_actionPerformed()
{
Vector del = new Vector();
}
+ @Override
public void undoButton_actionPerformed()
{
CommandI command = (CommandI) historyList.pop();
}
}
+ @Override
public void windowOpened(WindowEvent evt)
{
}
+ @Override
public void windowClosing(WindowEvent evt)
{
ap.idPanel.idCanvas.setHighlighted(null);
}
+ @Override
public void windowClosed(WindowEvent evt)
{
}
+ @Override
public void windowActivated(WindowEvent evt)
{
}
+ @Override
public void windowDeactivated(WindowEvent evt)
{
}
+ @Override
public void windowIconified(WindowEvent evt)
{
}
+ @Override
public void windowDeiconified(WindowEvent evt)
{
}
av.sendSelection();
}
+ /**
+ * Action on dragging the mouse in the scale panel is to expand or shrink the
+ * selection group range (including any hidden columns that it spans)
+ *
+ * @param evt
+ */
@Override
public void mouseDragged(MouseEvent evt)
{
mouseDragging = true;
+ ColumnSelection cs = av.getColumnSelection();
int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
- if (res < 0)
- {
- res = 0;
- }
-
- if (av.hasHiddenColumns())
- {
- res = av.getColumnSelection().adjustForHiddenColumns(res);
- }
-
- if (res > av.getAlignment().getWidth())
- {
- res = av.getAlignment().getWidth() - 1;
- }
-
- if (res < min)
- {
- min = res;
- }
-
- if (res > max)
- {
- max = res;
- }
+ res = Math.max(0, res);
+ res = cs.adjustForHiddenColumns(res);
+ res = Math.min(res, av.getAlignment().getWidth() - 1);
+ min = Math.min(res, min);
+ max = Math.max(res, max);
SequenceGroup sg = av.getSelectionGroup();
-
if (sg != null)
{
stretchingGroup = true;
-
- if (!av.getColumnSelection().contains(res))
- {
- av.getColumnSelection().addElement(res);
- }
-
- if (res > sg.getStartRes())
- {
- sg.setEndRes(res);
- }
- if (res < sg.getStartRes())
- {
- sg.setStartRes(res);
- }
-
- int col;
- for (int i = min; i <= max; i++)
- {
- col = av.getColumnSelection().adjustForHiddenColumns(i);
-
- if ((col < sg.getStartRes()) || (col > sg.getEndRes()))
- {
- av.getColumnSelection().removeElement(col);
- }
- else
- {
- av.getColumnSelection().addElement(col);
- }
- }
-
+ cs.stretchGroup(res, sg, min, max);
ap.paintAlignment(false);
}
}
stretchGroup = av.getSelectionGroup();
- if (stretchGroup == null)
+ if (stretchGroup == null || !stretchGroup.contains(sequence, res))
{
- stretchGroup = av.getAlignment().findGroup(sequence);
- if (stretchGroup != null && res > stretchGroup.getStartRes()
- && res < stretchGroup.getEndRes())
+ stretchGroup = av.getAlignment().findGroup(sequence, res);
+ if (stretchGroup != null)
{
+ // only update the current selection if the popup menu has a group to
+ // focus on
av.setSelectionGroup(stretchGroup);
}
- else
- {
- stretchGroup = null;
- }
- }
-
- else if (!stretchGroup.getSequences(null).contains(sequence)
- || stretchGroup.getStartRes() > res
- || stretchGroup.getEndRes() < res)
- {
- stretchGroup = null;
-
- SequenceGroup[] allGroups = av.getAlignment().findAllGroups(sequence);
-
- if (allGroups != null)
- {
- for (int i = 0; i < allGroups.length; i++)
- {
- if (allGroups[i].getStartRes() <= res
- && allGroups[i].getEndRes() >= res)
- {
- stretchGroup = allGroups[i];
- break;
- }
- }
- }
- av.setSelectionGroup(stretchGroup);
}
// DETECT RIGHT MOUSE BUTTON IN AWT
if (av.getConservationSelected())
{
- SliderPanel.setConservationSlider(ap, av.getGlobalColourScheme(),
- "Background");
+ SliderPanel.setConservationSlider(ap, av.getResidueShading(),
+ ap.getViewName());
}
if (av.getAbovePIDThreshold())
{
- SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(),
- "Background");
+ SliderPanel.setPIDSliderSource(ap, av.getResidueShading(),
+ ap.getViewName());
}
}
SliderPanel.setConservationSlider(ap, stretchGroup.cs,
stretchGroup.getName());
}
- else
+ if (stretchGroup.cs.getThreshold() > 0)
{
SliderPanel.setPIDSliderSource(ap, stretchGroup.cs,
stretchGroup.getName());
import jalview.api.FeatureRenderer;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.schemes.ColourSchemeI;
+import jalview.renderer.ResidueShaderI;
import java.awt.Color;
import java.awt.Font;
{
if (currentSequenceGroup.getDisplayBoxes())
{
- getBoxColour(currentSequenceGroup.cs, seq, i);
+ getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, i);
}
}
else if (av.getShowBoxes())
{
- getBoxColour(av.getGlobalColourScheme(), seq, i);
+ getBoxColour(av.getResidueShading(), seq, i);
}
return resBoxColour;
return col;
}
- void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)
+ void getBoxColour(ResidueShaderI shader, SequenceI seq, int i)
{
- if (cs != null)
+ if (shader != null)
{
- resBoxColour = cs.findColour(seq.getCharAt(i), i, seq);
+ resBoxColour = shader.findColour(seq.getCharAt(i), i, seq);
}
else if (forOverview
&& !jalview.util.Comparison.isGap(seq.getCharAt(i)))
{
if (currentSequenceGroup.getDisplayBoxes())
{
- getBoxColour(currentSequenceGroup.cs, seq, i);
+ getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq,
+ i);
}
}
else if (av.getShowBoxes())
{
- getBoxColour(av.getGlobalColourScheme(), seq, i);
+ getBoxColour(av.getResidueShading(), seq, i);
}
}
if (currentSequenceGroup.getColourText())
{
- getBoxColour(currentSequenceGroup.cs, seq, i);
+ getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, i);
graphics.setColor(resBoxColour.darker());
}
if (currentSequenceGroup.getShowNonconserved())
if (av.getColourText())
{
- getBoxColour(av.getGlobalColourScheme(), seq, i);
+ getBoxColour(av.getResidueShading(), seq, i);
if (av.getShowBoxes())
{
graphics.setColor(resBoxColour.darker());
package jalview.appletgui;
import jalview.datamodel.SequenceGroup;
-import jalview.schemes.ColourSchemeI;
+import jalview.renderer.ResidueShaderI;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
public class SliderPanel extends Panel implements ActionListener,
AdjustmentListener, MouseListener
{
+ private static final String BACKGROUND = "Background";
+
AlignmentPanel ap;
boolean forConservation = true;
- ColourSchemeI cs;
+ ResidueShaderI cs;
static Frame conservationSlider;
static Frame PIDSlider;
public static int setConservationSlider(AlignmentPanel ap,
- ColourSchemeI cs, String source)
+ ResidueShaderI ccs, String source)
{
SliderPanel sp = null;
if (conservationSlider == null)
{
- sp = new SliderPanel(ap, cs.getConservationInc(), true, cs);
+ sp = new SliderPanel(ap, ccs.getConservationInc(), true, ccs);
conservationSlider = new Frame();
conservationSlider.add(sp);
}
else
{
sp = (SliderPanel) conservationSlider.getComponent(0);
- sp.cs = cs;
+ sp.cs = ccs;
+ sp.valueField.setText(String.valueOf(ccs.getConservationInc()));
}
- conservationSlider
- .setTitle(MessageManager.formatMessage(
- "label.conservation_colour_increment",
- new String[] { source }));
+ conservationSlider.setTitle(MessageManager.formatMessage(
+ "label.conservation_colour_increment",
+ new String[] { source == null ? BACKGROUND : source }));
if (ap.av.getAlignment().getGroups() != null)
{
sp.setAllGroupsCheckEnabled(true);
conservationSlider.getTitle(), 420, 100);
conservationSlider.addWindowListener(new WindowAdapter()
{
+ @Override
public void windowClosing(WindowEvent e)
{
conservationSlider = null;
}
- public static int setPIDSliderSource(AlignmentPanel ap, ColourSchemeI cs,
- String source)
+ public static int setPIDSliderSource(AlignmentPanel ap,
+ ResidueShaderI ccs, String source)
{
SliderPanel pid = null;
if (PIDSlider == null)
{
- pid = new SliderPanel(ap, 50, false, cs);
+ pid = new SliderPanel(ap, ccs.getThreshold(), false, ccs);
PIDSlider = new Frame();
PIDSlider.add(pid);
}
else
{
pid = (SliderPanel) PIDSlider.getComponent(0);
- pid.cs = cs;
+ pid.cs = ccs;
+ pid.valueField.setText(String.valueOf(ccs.getThreshold()));
}
- PIDSlider
- .setTitle(MessageManager.formatMessage(
- "label.percentage_identity_threshold",
- new String[] { source }));
+ PIDSlider.setTitle(MessageManager.formatMessage(
+ "label.percentage_identity_threshold",
+ new String[] { source == null ? BACKGROUND : source }));
if (ap.av.getAlignment().getGroups() != null)
{
420, 100);
PIDSlider.addWindowListener(new WindowAdapter()
{
+ @Override
public void windowClosing(WindowEvent e)
{
PIDSlider = null;
}
+ /**
+ * Hides the PID slider panel if it is shown
+ */
+ public static void hidePIDSlider()
+ {
+ if (PIDSlider != null)
+ {
+ PIDSlider.setVisible(false);
+ PIDSlider = null;
+ }
+ }
+
+ /**
+ * Hides the Conservation slider panel if it is shown
+ */
+ public static void hideConservationSlider()
+ {
+ if (conservationSlider != null)
+ {
+ conservationSlider.setVisible(false);
+ conservationSlider = null;
+ }
+ }
public SliderPanel(AlignmentPanel ap, int value, boolean forConserve,
- ColourSchemeI cs)
+ ResidueShaderI shader)
{
try
{
e.printStackTrace();
}
this.ap = ap;
- this.cs = cs;
+ this.cs = shader;
forConservation = forConserve;
undoButton.setVisible(false);
applyButton.setVisible(false);
else
{
label.setText(MessageManager
- .getString("label.colour_residues_above_occurence"));
+ .getString("label.colour_residues_above_occurrence"));
slider.setMinimum(0);
slider.setMaximum(100 + slider.getVisibleAmount());
slider.setBlockIncrement(1);
return;
}
- ColourSchemeI toChange = cs;
+ ResidueShaderI toChange = cs;
Iterator<SequenceGroup> allGroups = null;
if (allGroupsCheck.getState())
allGroupsCheck.setEnabled(b);
}
+ @Override
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == applyButton)
}
}
+ @Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
valueField.setText(slider.getValue() + "");
{
try
{
- int i = Integer.parseInt(valueField.getText());
+ int i = Integer.valueOf(valueField.getText());
slider.setValue(i);
- } catch (Exception ex)
+ } catch (NumberFormatException ex)
{
- valueField.setText(slider.getValue() + "");
+ valueField.setText(String.valueOf(slider.getValue()));
}
}
valueField.setText(" ");
valueField.addActionListener(this);
valueField.setColumns(3);
+ valueField.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusLost(FocusEvent e)
+ {
+ valueField_actionPerformed();
+ valueChanged(slider.getValue());
+ }
+ });
+
label.setFont(new java.awt.Font("Verdana", 0, 11));
label.setText(MessageManager.getString("label.set_this_label_text"));
jPanel1.setLayout(borderLayout1);
{
}
+ @Override
public void mousePressed(MouseEvent evt)
{
}
+ @Override
public void mouseReleased(MouseEvent evt)
{
ap.paintAlignment(true);
}
+ @Override
public void mouseClicked(MouseEvent evt)
{
}
+ @Override
public void mouseEntered(MouseEvent evt)
{
}
+ @Override
public void mouseExited(MouseEvent evt)
{
}
}
else
{
- cs = ColourSchemeProperty.getColour(sg, ColourSchemeProperty
- .getColourName(av.getGlobalColourScheme()));
+ cs = ColourSchemeProperty.getColourScheme(sg,
+ ColourSchemeProperty.getColourName(av
+ .getGlobalColourScheme()));
}
// cs is null if shading is an annotationColourGradient
- if (cs != null)
- {
- cs.setThreshold(av.getGlobalColourScheme().getThreshold(),
- av.isIgnoreGapsConsensus());
- }
+ // if (cs != null)
+ // {
+ // cs.setThreshold(av.getViewportColourScheme().getThreshold(),
+ // av.isIgnoreGapsConsensus());
+ // }
}
// TODO: cs used to be initialized with a sequence collection and
// recalcConservation called automatically
// instead we set it manually - recalc called after updateAnnotation
- sg.cs = cs;
+ sg.setColourScheme(cs);
+ sg.getGroupColourScheme().setThreshold(
+ av.getResidueShading().getThreshold(),
+ av.isIgnoreGapsConsensus());
sg.setName("JTreeGroup:" + sg.hashCode());
sg.setIdColour(col);
if (av.getGlobalColourScheme() != null
- && av.getGlobalColourScheme().conservationApplied())
+ && av.getResidueShading().conservationApplied())
{
Conservation c = new Conservation("Group", sg.getSequences(null),
sg.getStartRes(), sg.getEndRes());
c.calculate();
c.verdict(false, av.getConsPercGaps());
- cs.setConservation(c);
-
- sg.cs = cs;
+ sg.setColourScheme(cs);
+ sg.getGroupColourScheme().setConservation(c);
}
av.getAlignment().addGroup(sg);
import jalview.api.FeatureColourI;
import jalview.datamodel.SequenceGroup;
+import jalview.renderer.ResidueShader;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.FeatureColour;
import jalview.schemes.ResidueProperties;
if (seqGroup != null)
{
- oldColourScheme = seqGroup.cs;
+ oldColourScheme = seqGroup.getColourScheme();
}
else
{
{
final Button button = new Button();
Color col = Color.white;
- if (oldColourScheme != null)
+ if (oldColourScheme != null && oldColourScheme.isSimple())
{
- try
- {
- col = oldColourScheme.findColour(aa.charAt(0), -1, null);
- } catch (Exception ex)
- {
- }
+ col = oldColourScheme.findColour(aa.charAt(0), 0, null, null, 0f);
}
button.setBackground(col);
oldColours.addElement(col);
}
UserColourScheme ucs = new UserColourScheme(newColours);
- if (ap != null)
- {
- ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
- }
+ // if (ap != null)
+ // {
+ // ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
+ // }
if (ap != null)
{
if (seqGroup != null)
{
- seqGroup.cs = ucs;
+ seqGroup.cs = new ResidueShader(ucs);
+ seqGroup.getGroupColourScheme().setThreshold(0,
+ ap.av.isIgnoreGapsConsensus());
}
else
{
ap.av.setGlobalColourScheme(ucs);
+ ap.av.getResidueShading().setThreshold(0,
+ ap.av.isIgnoreGapsConsensus());
}
ap.seqPanel.seqCanvas.img = null;
ap.paintAlignment(true);
{
if (seqGroup != null)
{
- seqGroup.cs = ucs;
+ seqGroup.cs = new ResidueShader(ucs);
}
else
{
package jalview.bin;
import jalview.datamodel.PDBEntry;
+import jalview.gui.UserDefinedColours;
+import jalview.schemes.ColourSchemes;
+import jalview.schemes.UserColourScheme;
import jalview.structure.StructureImportSettings;
+import jalview.urls.IdOrgSettings;
+import jalview.util.ColorUtils;
import jalview.ws.dbsources.das.api.DasSourceRegistryI;
import jalview.ws.dbsources.das.datamodel.DasSourceRegistry;
import jalview.ws.sifts.SiftsSettings;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Properties;
+import java.util.StringTokenizer;
import java.util.TreeSet;
import org.apache.log4j.ConsoleAppender;
* <li>SORT_ALIGNMENT (No sort|Id|Pairwise Identity)</li>
* <li>SEQUENCE_LINKS list of name|URL pairs for opening a url with
* $SEQUENCE_ID$</li>
+ * <li>STORED_LINKS list of name|url pairs which user has entered but are not
+ * currently used
+ * <li>DEFAULT_LINK name of single url to be used when user double clicks a
+ * sequence id (must be in SEQUENCE_LINKS or STORED_LINKS)
* <li>GROUP_LINKS list of name|URL[|<separator>] tuples - see
* jalview.utils.GroupURLLink for more info</li>
* <li>DAS_REGISTRY_URL the registry to query</li>
* <li>STRUCTURE_DISPLAY choose from JMOL (default) or CHIMERA for 3D structure
* display</li>
* <li>CHIMERA_PATH specify full path to Chimera program (if non-standard)</li>
+ * <li>ID_ORG_HOSTURL location of jalview service providing identifiers.org urls
+ * </li>
*
* </ul>
* Deprecated settings:
public static final String DAS_ACTIVE_SOURCE = "DAS_ACTIVE_SOURCE";
+ /**
+ * Sifts settings
+ */
public static final String DEFAULT_SIFTS_DOWNLOAD_DIR = System
.getProperty("user.home")
+ File.separatorChar
private final static String DEFAULT_FAIL_SAFE_PID_THRESHOLD = "30";
/**
+ * Identifiers.org download settings
+ */
+ private static final String ID_ORG_FILE = System.getProperty("user.home")
+ + File.separatorChar + ".identifiers.org.ids.json";
+
+ /**
* Allowed values are PDB or mmCIF
*/
private final static String PDB_DOWNLOAD_FORMAT = PDBEntry.Type.MMCIF
"sifts_cache_threshold_in_days",
DEFAULT_CACHE_THRESHOLD_IN_DAYS));
+ IdOrgSettings.setUrl(getDefault("ID_ORG_HOSTURL",
+ "http://www.jalview.org/services/identifiers"));
+ IdOrgSettings.setDownloadLocation(ID_ORG_FILE);
+
System.out
.println("Jalview Version: " + codeVersion + codeInstallation);
setProperty("VERSION", codeVersion);
// LOAD USERDEFINED COLOURS
- jalview.gui.UserDefinedColours
+ jalview.bin.Cache
.initUserColourSchemes(getProperty("USER_DEFINED_COLOURS"));
jalview.io.PIRFile.useModellerOutput = Cache.getDefault("PIR_MODELLER",
false);
{
return defcolour;
}
- Color col = jalview.schemes.ColourSchemeProperty
- .getAWTColorFromName(colprop);
+ Color col = ColorUtils.parseColourString(colprop);
if (col == null)
{
- try
- {
- col = new jalview.schemes.UserColourScheme(colprop).findColour('A');
- } catch (Exception ex)
- {
- log.warn("Couldn't parse '" + colprop + "' as a colour for "
- + property);
- col = null;
- }
+ log.warn("Couldn't parse '" + colprop + "' as a colour for "
+ + property);
}
return (col == null) ? defcolour : col;
}
Cache.applicationProperties.setProperty(propName, value);
}
}
+
+ /**
+ * Loads in user colour schemes from files.
+ *
+ * @param files
+ * a '|'-delimited list of file paths
+ */
+ public static void initUserColourSchemes(String files)
+ {
+ if (files == null || files.length() == 0)
+ {
+ return;
+ }
+
+ // In case colours can't be loaded, we'll remove them
+ // from the default list here.
+ StringBuffer coloursFound = new StringBuffer();
+ StringTokenizer st = new StringTokenizer(files, "|");
+ while (st.hasMoreElements())
+ {
+ String file = st.nextToken();
+ try
+ {
+ UserColourScheme ucs = ColourSchemes.loadColourScheme(file);
+ if (ucs != null)
+ {
+ if (coloursFound.length() > 0)
+ {
+ coloursFound.append("|");
+ }
+ coloursFound.append(file);
+ ColourSchemes.getInstance().registerColourScheme(ucs);
+ }
+ } catch (Exception ex)
+ {
+ System.out.println("Error loading User ColourFile\n" + ex);
+ }
+ }
+ if (!files.equals(coloursFound.toString()))
+ {
+ if (coloursFound.toString().length() > 1)
+ {
+ setProperty(UserDefinedColours.USER_DEFINED_COLOURS, coloursFound.toString());
+ }
+ else
+ {
+ applicationProperties.remove(UserDefinedColours.USER_DEFINED_COLOURS);
+ }
+ }
+ }
}
import jalview.io.gff.SequenceOntologyFactory;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.UserColourScheme;
import jalview.util.MessageManager;
import jalview.util.Platform;
import jalview.ws.jws2.Jws2Discoverer;
{
data.replaceAll("%20", " ");
- ColourSchemeI cs = ColourSchemeProperty.getColour(af
+ ColourSchemeI cs = ColourSchemeProperty.getColourScheme(af
.getViewport().getAlignment(), data);
- if (cs == null)
- {
- UserColourScheme ucs = new UserColourScheme("white");
- ucs.parseAppletParameter(data);
- cs = ucs;
- }
- else
+ if (cs != null)
{
System.out.println("CMD [-color " + data
+ "] executed successfully!");
import jalview.io.AnnotationFile;
import jalview.io.AppletFormatAdapter;
import jalview.io.DataSourceType;
-import jalview.io.FileFormat;
import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
import jalview.io.FileParse;
import jalview.io.IdentifyFile;
import jalview.io.JPredFile;
import jalview.javascript.MouseOverStructureListener;
import jalview.structure.SelectionListener;
import jalview.structure.StructureSelectionManager;
+import jalview.util.ColorUtils;
import jalview.util.HttpUtils;
import jalview.util.MessageManager;
{
try
{
- FileFormatI theFormat = FileFormat.valueOf(format);
+ FileFormatI theFormat = FileFormats.getInstance().forName(format);
boolean seqlimits = suffix.equalsIgnoreCase(TRUE);
if (alf.viewport.getSelectionGroup() != null)
{
{
boolean seqlimits = suffix.equalsIgnoreCase(TRUE);
- FileFormatI theFormat = FileFormat.valueOf(format);
+ FileFormatI theFormat = FileFormats.getInstance().forName(format);
String reply = new AppletFormatAdapter().formatSequences(theFormat,
alf.viewport.getAlignment(), seqlimits);
return reply;
{
return defcolour;
}
- Color col = jalview.schemes.ColourSchemeProperty
- .getAWTColorFromName(colprop);
+ Color col = ColorUtils.parseColourString(colprop);
if (col == null)
{
- try
- {
- col = new jalview.schemes.UserColourScheme(colprop).findColour('A');
- } catch (Exception ex)
- {
- System.err.println("Couldn't parse '" + colprop
- + "' as a colour for " + colparam);
- col = null;
- }
+ System.err.println("Couldn't parse '" + colprop
+ + "' as a colour for " + colparam);
}
return (col == null) ? defcolour : col;
-
}
public void openJalviewHelpUrl()
import jalview.io.DataSourceType;
import jalview.io.FileFormat;
import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
import jalview.io.FileParse;
import jalview.io.IdentifyFile;
+ " cannot be read with protocol==" + protocol);
return;
}
- FileFormatI format = FileFormat.valueOf(getParameter("format"));
+ FileFormatI format = FileFormats.getInstance().forName(
+ getParameter("format"));
if (format == null)
{
format = new IdentifyFile().identify(file, protocol);
protected char gapCharacter = '-';
- protected int type = NUCLEOTIDE;
-
- public static final int PROTEIN = 0;
-
- public static final int NUCLEOTIDE = 1;
+ private boolean nucleotide = true;
public boolean hasRNAStructure = false;
hiddenSequences = new HiddenSequences(this);
codonFrameList = new ArrayList<AlignedCodonFrame>();
- if (Comparison.isNucleotide(seqs))
- {
- type = NUCLEOTIDE;
- }
- else
- {
- type = PROTEIN;
- }
+ nucleotide = Comparison.isNucleotide(seqs);
sequences = Collections.synchronizedList(new ArrayList<SequenceI>());
}
/**
- * Adds a sequence to the alignment. Recalculates maxLength and size.
+ * Adds a sequence to the alignment. Recalculates maxLength and size. Note
+ * this currently does not recalculate whether or not the alignment is
+ * nucleotide, so mixed alignments may have undefined behaviour.
*
* @param snew
*/
* @see jalview.datamodel.AlignmentI#findGroup(jalview.datamodel.SequenceI)
*/
@Override
- public SequenceGroup findGroup(SequenceI s)
+ public SequenceGroup findGroup(SequenceI seq, int position)
{
synchronized (groups)
{
- for (int i = 0; i < this.groups.size(); i++)
+ for (SequenceGroup sg : groups)
{
- SequenceGroup sg = groups.get(i);
-
- if (sg.getSequences(null).contains(s))
+ if (sg.getSequences(null).contains(seq))
{
- return sg;
+ if (position >= sg.getStartRes() && position <= sg.getEndRes())
+ {
+ return sg;
+ }
}
}
}
}
@Override
- public void setNucleotide(boolean b)
- {
- if (b)
- {
- type = NUCLEOTIDE;
- }
- else
- {
- type = PROTEIN;
- }
- }
-
- @Override
public boolean isNucleotide()
{
- if (type == NUCLEOTIDE)
- {
- return true;
- }
- else
- {
- return false;
- }
+ return nucleotide;
}
@Override
String calcId, boolean autoCalc, SequenceI seqRef,
SequenceGroup groupRef)
{
- assert (name != null);
if (annotations != null)
{
for (AlignmentAnnotation annot : getAlignmentAnnotation())
@Override
public Iterable<AlignmentAnnotation> findAnnotation(String calcId)
{
- ArrayList<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
- for (AlignmentAnnotation a : getAlignmentAnnotation())
+ List<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
+ AlignmentAnnotation[] alignmentAnnotation = getAlignmentAnnotation();
+ if (alignmentAnnotation != null)
{
- if (a.getCalcId() == calcId
- || (a.getCalcId() != null && calcId != null && a.getCalcId()
- .equals(calcId)))
+ for (AlignmentAnnotation a : alignmentAnnotation)
{
- aa.add(a);
+ if (a.getCalcId() == calcId
+ || (a.getCalcId() != null && calcId != null && a
+ .getCalcId().equals(calcId)))
+ {
+ aa.add(a);
+ }
}
}
return aa;
*/
private Map<Integer, Annotation> sequenceMapping;
- /** DOCUMENT ME!! */
+ /**
+ * lower range for quantitative data
+ */
public float graphMin;
- /** DOCUMENT ME!! */
+ /**
+ * Upper range for quantitative data
+ */
public float graphMax;
/**
int findIndex(SequenceI s);
/**
- * Finds group that given sequence is part of.
+ * Returns the first group (in the order in which groups were added) that
+ * includes the given sequence instance and aligned position (base 0), or null
+ * if none found
*
- * @param s
- * Sequence in alignment.
+ * @param seq
+ * - must be contained in the alignment (not a dataset sequence)
+ * @param position
*
- * @return First group found for sequence. WARNING : Sequences may be members
- * of several groups. This method is incomplete.
+ * @return
*/
- SequenceGroup findGroup(SequenceI s);
+ SequenceGroup findGroup(SequenceI seq, int position);
/**
* Finds all groups that a given sequence is part of.
char getGapCharacter();
/**
- * Test for all nucleotide alignment
- *
- * @return true if alignment is nucleotide sequence
- */
- boolean isNucleotide();
-
- /**
* Test if alignment contains RNA structure
*
* @return true if RNA structure AligmnentAnnotation was added to alignment
boolean hasRNAStructure();
/**
- * Set alignment to be a nucleotide sequence
- *
- */
- void setNucleotide(boolean b);
-
- /**
* Get the associated dataset for the alignment.
*
* @return Alignment containing dataset sequences or null of this is a
*/
AlignmentAnnotation[] getAlignmentAnnotation();
+ /**
+ * Returns a list of annotations matching the given calc id, or an empty list
+ * if calcId is null
+ *
+ * @param calcId
+ * @return
+ */
Iterable<AlignmentAnnotation> findAnnotation(String calcId);
Iterable<AlignmentAnnotation> findAnnotations(SequenceI seq,
{
int nores = (isNa) ? ResidueProperties.maxNucleotideIndex
: ResidueProperties.maxProteinIndex;
- // Set all matrix to 0
+
dbinary = new double[getSequence().length * nores];
- for (int i = 0; i < dbinary.length; i++)
- {
- dbinary[i] = 0.0;
- }
return nores;
}
private void matrixEncode(final int[] aaIndex, final int[][] matrix)
{
- // Set all matrix to 0
- // dbinary = new double[getSequence().length * 21];
-
int nores = initMatrixGetNoRes();
- // for (int i = 0; i < dbinary.length; i++) {
- // dbinary[i] = 0.0;
- // }
for (int i = 0, iSize = getSequence().length; i < iSize; i++)
{
int aanum = nores - 1;
*/
region[0] = Math.min(region[0], start);
region[1] = Math.max(region[1], end);
+
+ /*
+ * also update or remove any subsequent ranges
+ * that are overlapped
+ */
+ while (i < hiddenColumns.size() - 1)
+ {
+ int[] nextRegion = hiddenColumns.get(i + 1);
+ if (nextRegion[0] > end + 1)
+ {
+ /*
+ * gap to next hidden range - no more to update
+ */
+ break;
+ }
+ region[1] = Math.max(nextRegion[1], end);
+ hiddenColumns.remove(i + 1);
+ }
return;
}
}
return changed;
}
+ /**
+ * Adjusts column selections, and the given selection group, to match the
+ * range of a stretch (e.g. mouse drag) operation
+ * <p>
+ * Method refactored from ScalePanel.mouseDragged
+ *
+ * @param res
+ * current column position, adjusted for hidden columns
+ * @param sg
+ * current selection group
+ * @param min
+ * start position of the stretch group
+ * @param max
+ * end position of the stretch group
+ */
+ public void stretchGroup(int res, SequenceGroup sg, int min, int max)
+ {
+ if (!contains(res))
+ {
+ addElement(res);
+ }
+
+ if (res > sg.getStartRes())
+ {
+ // expand selection group to the right
+ sg.setEndRes(res);
+ }
+ if (res < sg.getStartRes())
+ {
+ // expand selection group to the left
+ sg.setStartRes(res);
+ }
+
+ /*
+ * expand or shrink column selection to match the
+ * range of the drag operation
+ */
+ for (int col = min; col <= max; col++)
+ {
+ if (col < sg.getStartRes() || col > sg.getEndRes())
+ {
+ // shrinking drag - remove from selection
+ removeElement(col);
+ }
+ else
+ {
+ // expanding drag - add to selection
+ addElement(col);
+ }
+ }
+ }
}
}
@Override
- public synchronized void addSequenceFeature(SequenceFeature sf)
+ public synchronized boolean addSequenceFeature(SequenceFeature sf)
{
if (sequenceFeatures == null && datasetSequence != null)
{
- datasetSequence.addSequenceFeature(sf);
- return;
+ return datasetSequence.addSequenceFeature(sf);
}
if (sequenceFeatures == null)
{
{
if (sequenceFeatures[i].equals(sf))
{
- return;
+ return false;
}
}
temp[sequenceFeatures.length] = sf;
sequenceFeatures = temp;
+ return true;
}
@Override
*/
int getEndRes();
+ /**
+ * Answers true if sequence data is nucleotide (according to some heuristic)
+ *
+ * @return
+ */
+ boolean isNucleotide();
}
import jalview.analysis.AAFrequency;
import jalview.analysis.Conservation;
+import jalview.renderer.ResidueShader;
+import jalview.renderer.ResidueShaderI;
import jalview.schemes.ColourSchemeI;
import java.awt.Color;
/**
* Colourscheme applied to group if any
*/
- public ColourSchemeI cs;
+ public ResidueShaderI cs;
// start column (base 0)
int startRes = 0;
public SequenceGroup()
{
groupName = "JGroup:" + this.hashCode();
+ cs = new ResidueShader();
}
/**
ColourSchemeI scheme, boolean displayBoxes, boolean displayText,
boolean colourText, int start, int end)
{
+ this();
this.sequences = sequences;
this.groupName = groupName;
this.displayBoxes = displayBoxes;
this.displayText = displayText;
this.colourText = colourText;
- this.cs = scheme;
+ this.cs = new ResidueShader(scheme);
startRes = start;
endRes = end;
recalcConservation();
*/
public SequenceGroup(SequenceGroup seqsel)
{
+ this();
if (seqsel != null)
{
sequences = new ArrayList<SequenceI>();
@Override
public Iterable<AlignmentAnnotation> findAnnotation(String calcId)
{
- ArrayList<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
+ List<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
+ if (calcId == null)
+ {
+ return aa;
+ }
for (AlignmentAnnotation a : getAlignmentAnnotation())
{
- if (a.getCalcId() == calcId)
+ if (calcId.equals(a.getCalcId()))
{
aa.add(a);
}
private AnnotatedCollectionI context;
/**
- * set the alignment or group context for this group
+ * Sets the alignment or group context for this group
*
- * @param context
+ * @param ctx
+ * @throws IllegalArgumentException
+ * if setting the context would result in a circular reference chain
*/
- public void setContext(AnnotatedCollectionI context)
+ public void setContext(AnnotatedCollectionI ctx)
{
- this.context = context;
+ AnnotatedCollectionI ref = ctx;
+ while (ref != null)
+ {
+ if (ref == this)
+ {
+ throw new IllegalArgumentException(
+ "Circular reference in SequenceGroup.context");
+ }
+ ref = ref.getContext();
+ }
+ this.context = ctx;
}
/*
{
return context;
}
+
+ public void setColourScheme(ColourSchemeI scheme)
+ {
+ if (cs == null)
+ {
+ cs = new ResidueShader();
+ }
+ cs.setColourScheme(scheme);
+ }
+
+ public void setGroupColourScheme(ResidueShaderI scheme)
+ {
+ cs = scheme;
+ }
+
+ public ColourSchemeI getColourScheme()
+ {
+ return cs == null ? null : cs.getColourScheme();
+ }
+
+ public ResidueShaderI getGroupColourScheme()
+ {
+ return cs;
+ }
+
+ @Override
+ public boolean isNucleotide()
+ {
+ if (context != null) {
+ return context.isNucleotide();
+ }
+ return false;
+ }
+
+ /**
+ * @param seq
+ * @return true if seq is a member of the group
+ */
+
+ public boolean contains(SequenceI seq1)
+ {
+ return sequences.contains(seq1);
+ }
+
+ /**
+ * @param seq
+ * @param apos
+ * @return true if startRes<=apos and endRes>=apos and seq is in the group
+ */
+ public boolean contains(SequenceI seq, int apos)
+ {
+ return (startRes <= apos && endRes >= apos) && sequences.contains(seq);
+ }
}
*/
public void addDBRef(DBRefEntry entry);
- public void addSequenceFeature(SequenceFeature sf);
+ /**
+ * Adds the given sequence feature and returns true, or returns false if it is
+ * already present on the sequence
+ *
+ * @param sf
+ * @return
+ */
+ public boolean addSequenceFeature(SequenceFeature sf);
public void deleteFeature(SequenceFeature sf);
/*
* Copied to Jalview September 2016.
* Only the members of this class required for SparseIntArray were copied.
- * Method binarySearch(short[] array, int size, short value) added to support
+ * Change Log:
+ * Sep 2016: Method binarySearch(short[] array, int size, short value) added to support
* SparseShortArray.
+ * Jan 2017: EMPTY_DOUBLES added
*/
class ContainerHelpers
{
static final int[] EMPTY_INTS = new int[0];
+ static final double[] EMPTY_DOUBLES = new double[0];
+
static final long[] EMPTY_LONGS = new long[0];
static final Object[] EMPTY_OBJECTS = new Object[0];
--- /dev/null
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * SparseDoubleArray map integers to doubles. Unlike a normal array of integers,
+ * there can be gaps in the indices. It is intended to be more memory efficient
+ * than using a HashMap to map Integer to Double, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra
+ * entry object for each mapping.
+ *
+ * <p>
+ * Note that this container keeps its mappings in an array data structure, using
+ * a binary search to find keys. The implementation is not intended to be
+ * appropriate for data structures that may contain large numbers of items. It
+ * is generally slower than a traditional HashMap, since lookups require a
+ * binary search and adds and removes require inserting and deleting entries in
+ * the array. For containers holding up to hundreds of items, the performance
+ * difference is not significant, less than 50%.
+ * </p>
+ *
+ * <p>
+ * It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.
+ * </p>
+ */
+
+/*
+ * Change log:
+ * Jan 2017 cloned from SparseIntArray for Jalview to support SparseMatrix
+ * - SparseDoubleArray(double[]) constructor added
+ * - multiply() added for more efficient multiply (or divide) of a value
+ */
+public class SparseDoubleArray implements Cloneable
+{
+ private int[] mKeys;
+
+ private double[] mValues;
+
+ private int mSize;
+
+ /**
+ * Creates a new SparseDoubleArray containing no mappings.
+ */
+ public SparseDoubleArray()
+ {
+ this(10);
+ }
+
+ /**
+ * Creates a new SparseDoubleArray containing no mappings that will not
+ * require any additional memory allocation to store the specified number of
+ * mappings. If you supply an initial capacity of 0, the sparse array will be
+ * initialized with a light-weight representation not requiring any additional
+ * array allocations.
+ */
+ public SparseDoubleArray(int initialCapacity)
+ {
+ if (initialCapacity == 0)
+ {
+ mKeys = ContainerHelpers.EMPTY_INTS;
+ mValues = ContainerHelpers.EMPTY_DOUBLES;
+ }
+ else
+ {
+ initialCapacity = idealDoubleArraySize(initialCapacity);
+ mKeys = new int[initialCapacity];
+ mValues = new double[initialCapacity];
+ }
+ mSize = 0;
+ }
+
+ /**
+ * Constructor given an array of double values; stores the non-zero values
+ *
+ * @param row
+ */
+ public SparseDoubleArray(double[] row)
+ {
+ this();
+ for (int i = 0; i < row.length; i++)
+ {
+ if (row[i] != 0d)
+ {
+ put(i, row[i]);
+ }
+ }
+ }
+
+ @Override
+ public SparseDoubleArray clone()
+ {
+ SparseDoubleArray clone = null;
+ try
+ {
+ clone = (SparseDoubleArray) super.clone();
+ clone.mKeys = mKeys.clone();
+ clone.mValues = mValues.clone();
+ } catch (CloneNotSupportedException cnse)
+ {
+ /* ignore */
+ }
+ return clone;
+ }
+
+ /**
+ * Gets the value mapped from the specified key, or <code>0</code> if no such
+ * mapping has been made.
+ */
+ public double get(int key)
+ {
+ return get(key, 0d);
+ }
+
+ /**
+ * Gets the int mapped from the specified key, or the specified value if no
+ * such mapping has been made.
+ */
+ public double get(int key, double valueIfKeyNotFound)
+ {
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+ if (i < 0)
+ {
+ return valueIfKeyNotFound;
+ }
+ else
+ {
+ return mValues[i];
+ }
+ }
+
+ /**
+ * Removes the mapping from the specified key, if there was any.
+ */
+ public void delete(int key)
+ {
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+ if (i >= 0)
+ {
+ removeAt(i);
+ }
+ }
+
+ /**
+ * Removes the mapping at the given index.
+ */
+ public void removeAt(int index)
+ {
+ System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+ System.arraycopy(mValues, index + 1, mValues, index, mSize
+ - (index + 1));
+ mSize--;
+ }
+
+ /**
+ * Adds a mapping from the specified key to the specified value, replacing the
+ * previous mapping from the specified key if there was one.
+ */
+ public void put(int key, double value)
+ {
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+ if (i >= 0)
+ {
+ mValues[i] = value;
+ }
+ else
+ {
+ i = ~i;
+ if (mSize >= mKeys.length)
+ {
+ int n = idealDoubleArraySize(mSize + 1);
+ int[] nkeys = new int[n];
+ double[] nvalues = new double[n];
+ // Log.e("SparseDoubleArray", "grow " + mKeys.length + " to " + n);
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+ if (mSize - i != 0)
+ {
+ // Log.e("SparseDoubleArray", "move " + (mSize - i));
+ System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+ System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+ }
+ mKeys[i] = key;
+ mValues[i] = value;
+ mSize++;
+ }
+ }
+
+ /**
+ * Returns the number of key-value mappings that this SparseDoubleArray
+ * currently stores.
+ */
+ public int size()
+ {
+ return mSize;
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns the key from
+ * the <code>index</code>th key-value mapping that this SparseDoubleArray
+ * stores.
+ *
+ * <p>
+ * The keys corresponding to indices in ascending order are guaranteed to be
+ * in ascending order, e.g., <code>keyAt(0)</code> will return the smallest
+ * key and <code>keyAt(size()-1)</code> will return the largest key.
+ * </p>
+ */
+ public int keyAt(int index)
+ {
+ return mKeys[index];
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns the value
+ * from the <code>index</code>th key-value mapping that this SparseDoubleArray
+ * stores.
+ *
+ * <p>
+ * The values corresponding to indices in ascending order are guaranteed to be
+ * associated with keys in ascending order, e.g., <code>valueAt(0)</code> will
+ * return the value associated with the smallest key and
+ * <code>valueAt(size()-1)</code> will return the value associated with the
+ * largest key.
+ * </p>
+ */
+ public double valueAt(int index)
+ {
+ return mValues[index];
+ }
+
+ /**
+ * Returns the index for which {@link #keyAt} would return the specified key,
+ * or a negative number if the specified key is not mapped.
+ */
+ public int indexOfKey(int key)
+ {
+ return ContainerHelpers.binarySearch(mKeys, mSize, key);
+ }
+
+ /**
+ * Returns an index for which {@link #valueAt} would return the specified key,
+ * or a negative number if no keys map to the specified value. Beware that
+ * this is a linear search, unlike lookups by key, and that multiple keys can
+ * map to the same value and this will find only one of them.
+ */
+ public int indexOfValue(double value)
+ {
+ for (int i = 0; i < mSize; i++)
+ {
+ if (mValues[i] == value)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Removes all key-value mappings from this SparseDoubleArray.
+ */
+ public void clear()
+ {
+ mSize = 0;
+ }
+
+ /**
+ * Puts a key/value pair into the array, optimizing for the case where the key
+ * is greater than all existing keys in the array.
+ */
+ public void append(int key, double value)
+ {
+ if (mSize != 0 && key <= mKeys[mSize - 1])
+ {
+ put(key, value);
+ return;
+ }
+ int pos = mSize;
+ if (pos >= mKeys.length)
+ {
+ int n = idealDoubleArraySize(pos + 1);
+ int[] nkeys = new int[n];
+ double[] nvalues = new double[n];
+ // Log.e("SparseDoubleArray", "grow " + mKeys.length + " to " + n);
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+ mKeys[pos] = key;
+ mValues[pos] = value;
+ mSize = pos + 1;
+ }
+
+ /**
+ * Created by analogy with
+ * com.android.internal.util.ArrayUtils#idealLongArraySize
+ *
+ * @param i
+ * @return
+ */
+ public static int idealDoubleArraySize(int need)
+ {
+ return idealByteArraySize(need * 8) / 8;
+ }
+
+ /**
+ * Inlined here by copying from com.android.internal.util.ArrayUtils
+ *
+ * @param i
+ * @return
+ */
+ public static int idealByteArraySize(int need)
+ {
+ for (int i = 4; i < 32; i++)
+ {
+ if (need <= (1 << i) - 12)
+ {
+ return (1 << i) - 12;
+ }
+ }
+
+ return need;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * This implementation composes a string by iterating over its mappings.
+ */
+ @Override
+ public String toString()
+ {
+ if (size() <= 0)
+ {
+ return "{}";
+ }
+ StringBuilder buffer = new StringBuilder(mSize * 28);
+ buffer.append('{');
+ for (int i = 0; i < mSize; i++)
+ {
+ if (i > 0)
+ {
+ buffer.append(", ");
+ }
+ int key = keyAt(i);
+ buffer.append(key);
+ buffer.append('=');
+ double value = valueAt(i);
+ buffer.append(value);
+ }
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
+ * Method (copied from put) added for Jalview to efficiently increment a key's
+ * value if present, else add it with the given value. This avoids a double
+ * binary search (once to get the value, again to put the updated value).
+ *
+ * @param key
+ * @oparam toAdd
+ * @return the new value for the key
+ */
+ public double add(int key, double toAdd)
+ {
+ double newValue = toAdd;
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+ if (i >= 0)
+ {
+ mValues[i] += toAdd;
+ newValue = mValues[i];
+ }
+ else
+ {
+ i = ~i;
+ if (mSize >= mKeys.length)
+ {
+ int n = idealDoubleArraySize(mSize + 1);
+ int[] nkeys = new int[n];
+ double[] nvalues = new double[n];
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+ if (mSize - i != 0)
+ {
+ System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+ System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+ }
+ mKeys[i] = key;
+ mValues[i] = toAdd;
+ mSize++;
+ }
+ return newValue;
+ }
+
+ /**
+ * Method added for Jalview to efficiently multiply a key's value if present,
+ * else do nothing. This avoids a double binary search (once to get the value,
+ * again to put the updated value).
+ *
+ * @param key
+ * @oparam toAdd
+ * @return the new value for the key
+ */
+ public double divide(int key, double divisor)
+ {
+ double newValue = 0d;
+ if (divisor == 0d)
+ {
+ return newValue;
+ }
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+ if (i >= 0)
+ {
+ mValues[i] /= divisor;
+ newValue = mValues[i];
+ }
+ return newValue;
+ }
+}
import jalview.util.Comparison;
import jalview.util.DBRefUtils;
import jalview.util.MapList;
+import jalview.util.RangeComparator;
import java.io.IOException;
import java.net.MalformedURLException;
}
/**
- * A comparator to sort ranges into ascending start position order
- */
- private class RangeSorter implements Comparator<int[]>
- {
- boolean forwards;
-
- RangeSorter(boolean forward)
- {
- forwards = forward;
- }
-
- @Override
- public int compare(int[] o1, int[] o2)
- {
- return (forwards ? 1 : -1) * Integer.compare(o1[0], o2[0]);
- }
-
- }
-
- /**
* Default constructor (to use rest.ensembl.org)
*/
public EnsemblSeqProxy()
* a final sort is needed since Ensembl returns CDS sorted within source
* (havana / ensembl_havana)
*/
- Collections.sort(regions, new RangeSorter(direction == 1));
+ Collections.sort(regions, new RangeComparator(direction == 1));
List<int[]> to = Arrays.asList(new int[] { start,
start + mappedLength - 1 });
*/
package jalview.ext.jmol;
-import jalview.api.AlignmentViewPanel;
+import jalview.api.AlignViewportI;
import jalview.api.FeatureRenderer;
import jalview.api.SequenceRenderer;
import jalview.datamodel.AlignmentI;
import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import jalview.structures.models.AAStructureBindingModel;
+import jalview.util.MessageManager;
import java.awt.Color;
import java.awt.Container;
import java.net.URL;
import java.security.AccessControlException;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
Hashtable<String, String> chainFile;
- public String fileLoadingError;
-
/*
* the default or current model displayed if the model cannot be identified
* from the selection message
releaseUIResources();
}
+ @Override
public void colourByChain()
{
colourBySequence = false;
evalStateCommand("select *;color chain");
}
+ @Override
public void colourByCharge()
{
colourBySequence = false;
}
/**
- * Construct and send a command to align structures against a reference
- * structure, based on one or more sequence alignments
- *
- * @param _alignment
- * an array of alignments to process
- * @param _refStructure
- * an array of corresponding reference structures (index into pdb
- * file array); if a negative value is passed, the first PDB file
- * mapped to an alignment sequence is used as the reference for
- * superposition
- * @param _hiddenCols
- * an array of corresponding hidden columns for each alignment
+ * {@inheritDoc}
*/
- public void superposeStructures(AlignmentI[] _alignment,
+ @Override
+ public String superposeStructures(AlignmentI[] _alignment,
int[] _refStructure, ColumnSelection[] _hiddenCols)
{
while (viewer.isScriptExecuting())
String[] files = getPdbFile();
if (!waitForFileLoad(files))
{
- return;
+ return null;
}
StringBuilder selectioncom = new StringBuilder(256);
nSeconds = " " + (2.0 / files.length) + " ";
// if (nSeconds).substring(0,5)+" ";
}
+
// see JAL-1345 - should really automatically turn off the animation for
// large numbers of structures, but Jmol doesn't seem to allow that.
// nSeconds = " ";
}
/*
- * 'matched' array will hold 'true' for visible alignment columns where
+ * 'matched' bit j will be set for visible alignment columns j where
* all sequences have a residue with a mapping to the PDB structure
*/
- // TODO could use a BitSet for matched
- boolean matched[] = new boolean[alignment.getWidth()];
- for (int m = 0; m < matched.length; m++)
+ BitSet matched = new BitSet();
+ for (int m = 0; m < alignment.getWidth(); m++)
{
- matched[m] = (hiddenCols != null) ? hiddenCols.isVisible(m) : true;
+ if (hiddenCols == null || hiddenCols.isVisible(m))
+ {
+ matched.set(m);
+ }
}
SuperposeData[] structures = new SuperposeData[files.length];
}
String[] selcom = new String[files.length];
- int nmatched = 0;
- for (boolean b : matched)
- {
- if (b)
- {
- nmatched++;
- }
- }
+ int nmatched = matched.cardinality();
if (nmatched < 4)
{
- // TODO: bail out here because superposition illdefined?
+ return (MessageManager.formatMessage(
+"label.insufficient_residues",
+ nmatched));
}
/*
boolean run = false;
StringBuilder molsel = new StringBuilder();
molsel.append("{");
- for (int r = 0; r < matched.length; r++)
+
+ int nextColumnMatch = matched.nextSetBit(0);
+ while (nextColumnMatch != -1)
{
- if (matched[r])
+ int pdbResNo = structures[pdbfnum].pdbResNo[nextColumnMatch];
+ if (lpos != pdbResNo - 1)
{
- int pdbResNo = structures[pdbfnum].pdbResNo[r];
- if (lpos != pdbResNo - 1)
+ // discontinuity
+ if (lpos != -1)
{
- // discontinuity
- if (lpos != -1)
- {
- molsel.append(lpos);
- molsel.append(chainCd);
- molsel.append("|");
- }
- run = false;
+ molsel.append(lpos);
+ molsel.append(chainCd);
+ molsel.append("|");
}
- else
+ run = false;
+ }
+ else
+ {
+ // continuous run - and lpos >-1
+ if (!run)
{
- // continuous run - and lpos >-1
- if (!run)
- {
- // at the beginning, so add dash
- molsel.append(lpos);
- molsel.append("-");
- }
- run = true;
+ // at the beginning, so add dash
+ molsel.append(lpos);
+ molsel.append("-");
}
- lpos = pdbResNo;
+ run = true;
}
+ lpos = pdbResNo;
+ nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
}
/*
* add final selection phrase
+ selectioncom.toString() + "); cartoons; ");
// evalStateCommand("select *; backbone; select "+selcom.toString()+"; cartoons; center "+selcom.toString());
}
+
+ return null;
}
public void evalStateCommand(String command)
}
/**
- * colour any structures associated with sequences in the given alignment
- * using the getFeatureRenderer() and getSequenceRenderer() renderers but only
- * if colourBySequence is enabled.
+ * Sends a set of colour commands to the structure viewer
+ *
+ * @param colourBySequenceCommands
*/
- public void colourBySequence(AlignmentViewPanel alignmentv)
+ @Override
+ protected void colourBySequence(
+ StructureMappingcommandSet[] colourBySequenceCommands)
{
- boolean showFeatures = alignmentv.getAlignViewport()
- .isShowSequenceFeatures();
- if (!colourBySequence || !isLoadingFinished())
- {
- return;
- }
- if (getSsm() == null)
- {
- return;
- }
- String[] files = getPdbFile();
-
- SequenceRenderer sr = getSequenceRenderer(alignmentv);
-
- FeatureRenderer fr = null;
- if (showFeatures)
- {
- fr = getFeatureRenderer(alignmentv);
- }
- AlignmentI alignment = alignmentv.getAlignment();
-
- for (jalview.structure.StructureMappingcommandSet cpdbbyseq : getColourBySequenceCommands(
- files, sr, fr, alignment))
+ for (StructureMappingcommandSet cpdbbyseq : colourBySequenceCommands)
{
for (String cbyseq : cpdbbyseq.commands)
{
* @param files
* @param sr
* @param fr
- * @param alignment
+ * @param viewport
* @return
*/
+ @Override
protected StructureMappingcommandSet[] getColourBySequenceCommands(
String[] files, SequenceRenderer sr, FeatureRenderer fr,
- AlignmentI alignment)
+ AlignViewportI viewport)
{
return JmolCommands.getColourBySequenceCommand(getSsm(), files,
- getSequence(), sr, fr, alignment);
+ getSequence(), sr, fr, viewport);
}
/**
}
/**
- * returns the current featureRenderer that should be used to colour the
- * structures
- *
- * @param alignment
- *
- * @return
- */
- public abstract FeatureRenderer getFeatureRenderer(
- AlignmentViewPanel alignment);
-
- /**
* instruct the Jalview binding to update the pdbentries vector if necessary
* prior to matching the jmol view's contents to the list of structure files
* Jalview knows about.
return null;
}
- /**
- * returns the current sequenceRenderer that should be used to colour the
- * structures
- *
- * @param alignment
- *
- * @return
- */
- public abstract SequenceRenderer getSequenceRenderer(
- AlignmentViewPanel alignment);
+
// ///////////////////////////////
// JmolStatusListener
}
+ @Override
public void setJalviewColourScheme(ColourSchemeI cs)
{
colourBySequence = false;
command.append("select *;color white;");
List<String> residueSet = ResidueProperties.getResidues(isNucleotide(),
false);
- for (String res : residueSet)
+ for (String resName : residueSet)
{
- Color col = cs.findColour(res.charAt(0));
- command.append("select " + res + ";color[" + col.getRed() + ","
+ char res = resName.length() == 3 ? ResidueProperties
+ .getSingleCharacterCode(resName) : resName.charAt(0);
+ Color col = cs.findColour(res, 0, null, null, 0f);
+ command.append("select " + resName + ";color[" + col.getRed() + ","
+ col.getGreen() + "," + col.getBlue() + "];");
}
protected org.jmol.api.JmolAppConsoleInterface console = null;
+ @Override
public void setBackgroundColour(java.awt.Color col)
{
jmolHistory(false);
*/
package jalview.ext.jmol;
+import jalview.api.AlignViewportI;
import jalview.api.FeatureRenderer;
import jalview.api.SequenceRenderer;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SequenceI;
import jalview.structure.StructureMapping;
import jalview.structure.StructureMappingcommandSet;
import java.awt.Color;
import java.util.ArrayList;
+import java.util.List;
/**
* Routines for generating Jmol commands for Jalview/Jmol binding another
public static StructureMappingcommandSet[] getColourBySequenceCommand(
StructureSelectionManager ssm, String[] files,
SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr,
- AlignmentI alignment)
+ AlignViewportI viewport)
{
-
- ArrayList<StructureMappingcommandSet> cset = new ArrayList<StructureMappingcommandSet>();
+ ColumnSelection cs = viewport.getColumnSelection();
+ AlignmentI al = viewport.getAlignment();
+ List<StructureMappingcommandSet> cset = new ArrayList<StructureMappingcommandSet>();
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
for (int sp, m = 0; m < mapping.length; m++)
{
if (mapping[m].getSequence() == sequence[pdbfnum][s]
- && (sp = alignment.findIndex(sequence[pdbfnum][s])) > -1)
+ && (sp = al.findIndex(sequence[pdbfnum][s])) > -1)
{
- SequenceI asp = alignment.getSequenceAt(sp);
+ SequenceI asp = al.getSequenceAt(sp);
for (int r = 0; r < asp.getLength(); r++)
{
// no mapping to gaps in sequence
{
col = fr.findFeatureColour(col, sequence[pdbfnum][s], r);
}
+
+ /*
+ * shade hidden regions darker
+ */
+ if (!cs.isVisible(r))
+ {
+ // col = ColorUtils.darkerThan(col);
+ col = Color.GRAY;
+ }
+
String newSelcom = (mapping[m].getChain() != " " ? ":"
+ mapping[m].getChain() : "")
+ "/"
--- /dev/null
+package jalview.ext.rbvi.chimera;
+
+import jalview.util.RangeComparator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * A class to model a Chimera atomspec pattern, for example
+ *
+ * <pre>
+ * #0:15.A,28.A,54.A,63.A,70-72.A,83-84.A,97-98.A|#1:2.A,6.A,11.A,13-14.A,70.A,82.A,96-97.A
+ * </pre>
+ *
+ * where
+ * <ul>
+ * <li>#0 is a model number</li>
+ * <li>15 or 70-72 is a residue number, or range of residue numbers</li>
+ * <li>.A is a chain identifier</li>
+ * <li>residue ranges are separated by comma</li>
+ * <li>atomspecs for distinct models are separated by | (or)</li>
+ * </ul>
+ *
+ * <pre>
+ * @see http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec.html
+ * </pre>
+ */
+public class AtomSpecModel
+{
+ private Map<Integer, Map<String, List<int[]>>> atomSpec;
+
+ /**
+ * Constructor
+ */
+ public AtomSpecModel()
+ {
+ atomSpec = new TreeMap<Integer, Map<String, List<int[]>>>();
+ }
+
+ /**
+ * Adds one contiguous range to this atom spec
+ *
+ * @param model
+ * @param startPos
+ * @param endPos
+ * @param chain
+ */
+ public void addRange(int model, int startPos, int endPos, String chain)
+ {
+ /*
+ * Get/initialize map of data for the colour and model
+ */
+ Map<String, List<int[]>> modelData = atomSpec.get(model);
+ if (modelData == null)
+ {
+ atomSpec.put(model, modelData = new TreeMap<String, List<int[]>>());
+ }
+
+ /*
+ * Get/initialize map of data for colour, model and chain
+ */
+ List<int[]> chainData = modelData.get(chain);
+ if (chainData == null)
+ {
+ chainData = new ArrayList<int[]>();
+ modelData.put(chain, chainData);
+ }
+
+ /*
+ * Add the start/end positions
+ */
+ chainData.add(new int[] { startPos, endPos });
+ // TODO add intelligently, using a RangeList class
+ }
+
+ /**
+ * Returns the range(s) formatted as a Chimera atomspec
+ *
+ * @return
+ */
+ public String getAtomSpec()
+ {
+ StringBuilder sb = new StringBuilder(128);
+ boolean firstModel = true;
+ for (Integer model : atomSpec.keySet())
+ {
+ if (!firstModel)
+ {
+ sb.append("|");
+ }
+ firstModel = false;
+ sb.append("#").append(model).append(":");
+
+ boolean firstPositionForModel = true;
+ final Map<String, List<int[]>> modelData = atomSpec.get(model);
+
+ for (String chain : modelData.keySet())
+ {
+ // chain = chain.trim();
+
+ List<int[]> rangeList = modelData.get(chain);
+
+ /*
+ * sort ranges into ascending start position order
+ */
+ Collections.sort(rangeList, new RangeComparator(true));
+
+ int start = rangeList.isEmpty() ? 0 : rangeList.get(0)[0];
+ int end = rangeList.isEmpty() ? 0 : rangeList.get(0)[1];
+
+ Iterator<int[]> iterator = rangeList.iterator();
+ while (iterator.hasNext())
+ {
+ int[] range = iterator.next();
+ if (range[0] <= end + 1)
+ {
+ /*
+ * range overlaps or is contiguous with the last one
+ * - so just extend the end position, and carry on
+ * (unless this is the last in the list)
+ */
+ end = Math.max(end, range[1]);
+ }
+ else
+ {
+ /*
+ * we have a break so append the last range
+ */
+ appendRange(sb, start, end, chain, firstPositionForModel);
+ firstPositionForModel = false;
+ start = range[0];
+ end = range[1];
+ }
+ }
+
+ /*
+ * and append the last range
+ */
+ if (!rangeList.isEmpty())
+ {
+ appendRange(sb, start, end, chain, firstPositionForModel);
+ firstPositionForModel = false;
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * @param sb
+ * @param start
+ * @param end
+ * @param chain
+ * @param firstPositionForModel
+ */
+ protected void appendRange(StringBuilder sb, int start, int end,
+ String chain, boolean firstPositionForModel)
+ {
+ if (!firstPositionForModel)
+ {
+ sb.append(",");
+ }
+ if (end == start)
+ {
+ sb.append(start);
+ }
+ else
+ {
+ sb.append(start).append("-").append(end);
+ }
+ if (chain.length() > 0)
+ {
+ sb.append(".").append(chain);
+ }
+ }
+}
*/
package jalview.ext.rbvi.chimera;
+import jalview.api.AlignViewportI;
import jalview.api.FeatureRenderer;
import jalview.api.SequenceRenderer;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.structure.StructureMapping;
import jalview.structure.StructureMappingcommandSet;
import java.awt.Color;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
/**
* Routines for generating Chimera commands for Jalview/Chimera binding
public class ChimeraCommands
{
+ public static final String NAMESPACE_PREFIX = "jv_";
+
/**
- * utility to construct the commands to colour chains by the given alignment
- * for passing to Chimera
- *
- * @returns Object[] { Object[] { <model being coloured>,
+ * Constructs Chimera commands to colour residues as per the Jalview alignment
*
+ * @param ssm
+ * @param files
+ * @param sequence
+ * @param sr
+ * @param fr
+ * @param viewport
+ * @return
*/
public static StructureMappingcommandSet[] getColourBySequenceCommand(
StructureSelectionManager ssm, String[] files,
SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr,
- AlignmentI alignment)
+ AlignViewportI viewport)
{
- Map<Color, Map<Integer, Map<String, List<int[]>>>> colourMap = buildColoursMap(
- ssm, files, sequence, sr, fr, alignment);
+ Map<Object, AtomSpecModel> colourMap = buildColoursMap(ssm, files,
+ sequence, sr, fr, viewport);
List<String> colourCommands = buildColourCommands(colourMap);
StructureMappingcommandSet cs = new StructureMappingcommandSet(
ChimeraCommands.class, null,
- colourCommands.toArray(new String[0]));
+ colourCommands.toArray(new String[colourCommands.size()]));
return new StructureMappingcommandSet[] { cs };
}
* 'color' commands (one per distinct colour used). The format of each command
* is
*
- * <blockquote> color colorname #modelnumber:range.chain e.g. color #00ff00
- * #0:2.B,4.B,9-12.B|#1:1.A,2-6.A,...
- *
- * @see http
- * ://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec
- * .html </pre>
+ * <pre>
+ * <blockquote>
+ * color colorname #modelnumber:range.chain
+ * e.g. color #00ff00 #0:2.B,4.B,9-12.B|#1:1.A,2-6.A,...
+ * </blockquote>
+ * </pre>
*
* @param colourMap
* @return
*/
protected static List<String> buildColourCommands(
- Map<Color, Map<Integer, Map<String, List<int[]>>>> colourMap)
+ Map<Object, AtomSpecModel> colourMap)
{
/*
* This version concatenates all commands into a single String (semi-colon
List<String> commands = new ArrayList<String>();
StringBuilder sb = new StringBuilder(256);
boolean firstColour = true;
- for (Color colour : colourMap.keySet())
+ for (Object key : colourMap.keySet())
{
+ Color colour = (Color) key;
String colourCode = ColorUtils.toTkCode(colour);
if (!firstColour)
{
}
sb.append("color ").append(colourCode).append(" ");
firstColour = false;
- boolean firstModelForColour = true;
- final Map<Integer, Map<String, List<int[]>>> colourData = colourMap
- .get(colour);
- for (Integer model : colourData.keySet())
+ final AtomSpecModel colourData = colourMap.get(colour);
+ sb.append(colourData.getAtomSpec());
+ }
+ commands.add(sb.toString());
+ return commands;
+ }
+
+ /**
+ * Traverses a map of { modelNumber, {chain, {list of from-to ranges} } } and
+ * builds a Chimera format atom spec
+ *
+ * @param modelAndChainRanges
+ */
+ protected static String getAtomSpec(
+ Map<Integer, Map<String, List<int[]>>> modelAndChainRanges)
+ {
+ StringBuilder sb = new StringBuilder(128);
+ boolean firstModelForColour = true;
+ for (Integer model : modelAndChainRanges.keySet())
+ {
+ boolean firstPositionForModel = true;
+ if (!firstModelForColour)
{
- boolean firstPositionForModel = true;
- if (!firstModelForColour)
- {
- sb.append("|");
- }
- firstModelForColour = false;
- sb.append("#").append(model).append(":");
+ sb.append("|");
+ }
+ firstModelForColour = false;
+ sb.append("#").append(model).append(":");
- final Map<String, List<int[]>> modelData = colourData.get(model);
- for (String chain : modelData.keySet())
+ final Map<String, List<int[]>> modelData = modelAndChainRanges
+ .get(model);
+ for (String chain : modelData.keySet())
+ {
+ boolean hasChain = !"".equals(chain.trim());
+ for (int[] range : modelData.get(chain))
{
- boolean hasChain = !"".equals(chain.trim());
- for (int[] range : modelData.get(chain))
+ if (!firstPositionForModel)
{
- if (!firstPositionForModel)
- {
- sb.append(",");
- }
- if (range[0] == range[1])
- {
- sb.append(range[0]);
- }
- else
- {
- sb.append(range[0]).append("-").append(range[1]);
- }
- if (hasChain)
- {
- sb.append(".").append(chain);
- }
- firstPositionForModel = false;
+ sb.append(",");
}
+ if (range[0] == range[1])
+ {
+ sb.append(range[0]);
+ }
+ else
+ {
+ sb.append(range[0]).append("-").append(range[1]);
+ }
+ if (hasChain)
+ {
+ sb.append(".").append(chain);
+ }
+ firstPositionForModel = false;
}
}
}
- commands.add(sb.toString());
- return commands;
+ return sb.toString();
}
/**
* <pre>
- * Build a data structure which maps contiguous subsequences for each colour.
- * This generates a data structure from which we can easily generate the
- * Chimera command for colour by sequence.
+ * Build a data structure which records contiguous subsequences for each colour.
+ * From this we can easily generate the Chimera command for colour by sequence.
* Color
* Model number
* Chain
* Ordering is by order of addition (for colours and positions), natural ordering (for models and chains)
* </pre>
*/
- protected static Map<Color, Map<Integer, Map<String, List<int[]>>>> buildColoursMap(
+ protected static Map<Object, AtomSpecModel> buildColoursMap(
StructureSelectionManager ssm, String[] files,
SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr,
- AlignmentI alignment)
+ AlignViewportI viewport)
{
- Map<Color, Map<Integer, Map<String, List<int[]>>>> colourMap = new LinkedHashMap<Color, Map<Integer, Map<String, List<int[]>>>>();
+ ColumnSelection cs = viewport.getColumnSelection();
+ AlignmentI al = viewport.getAlignment();
+ Map<Object, AtomSpecModel> colourMap = new LinkedHashMap<Object, AtomSpecModel>();
Color lastColour = null;
+
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
{
final SequenceI seq = sequence[pdbfnum][s];
if (mapping[m].getSequence() == seq
- && (sp = alignment.findIndex(seq)) > -1)
+ && (sp = al.findIndex(seq)) > -1)
{
- SequenceI asp = alignment.getSequenceAt(sp);
+ SequenceI asp = al.getSequenceAt(sp);
for (int r = 0; r < asp.getLength(); r++)
{
// no mapping to gaps in sequence
}
Color colour = sr.getResidueColour(seq, r, fr);
+
+ /*
+ * darker colour for hidden regions
+ */
+ if (!cs.isVisible(r))
+ {
+ // colour = ColorUtils.darkerThan(colour);
+ colour = Color.GRAY;
+ }
+
final String chain = mapping[m].getChain();
/*
// final colour range
if (lastColour != null)
{
- addColourRange(colourMap, lastColour, pdbfnum, startPos,
- lastPos, lastChain);
+ addColourRange(colourMap, lastColour, pdbfnum, startPos, lastPos,
+ lastChain);
}
// break;
}
/**
* Helper method to add one contiguous colour range to the colour map.
*
- * @param colourMap
- * @param colour
+ * @param map
+ * @param key
* @param model
* @param startPos
* @param endPos
* @param chain
*/
- protected static void addColourRange(
- Map<Color, Map<Integer, Map<String, List<int[]>>>> colourMap,
- Color colour, int model, int startPos, int endPos, String chain)
+ protected static void addColourRange(Map<Object, AtomSpecModel> map,
+ Object key, int model, int startPos, int endPos, String chain)
{
/*
* Get/initialize map of data for the colour
*/
- Map<Integer, Map<String, List<int[]>>> colourData = colourMap
- .get(colour);
- if (colourData == null)
+ AtomSpecModel atomSpec = map.get(key);
+ if (atomSpec == null)
{
- colourMap
- .put(colour,
- colourData = new TreeMap<Integer, Map<String, List<int[]>>>());
+ atomSpec = new AtomSpecModel();
+ map.put(key, atomSpec);
}
- /*
- * Get/initialize map of data for the colour and model
- */
- Map<String, List<int[]>> modelData = colourData.get(model);
- if (modelData == null)
+ atomSpec.addRange(model, startPos, endPos, chain);
+ }
+
+ /**
+ * Constructs and returns Chimera commands to set attributes on residues
+ * corresponding to features in Jalview. Attribute names are the Jalview
+ * feature type, with a "jv_" prefix.
+ *
+ * @param ssm
+ * @param files
+ * @param seqs
+ * @param fr
+ * @param alignment
+ * @return
+ */
+ public static StructureMappingcommandSet getSetAttributeCommandsForFeatures(
+ StructureSelectionManager ssm, String[] files,
+ SequenceI[][] seqs, FeatureRenderer fr, AlignmentI alignment)
+ {
+ Map<String, Map<Object, AtomSpecModel>> featureMap = buildFeaturesMap(
+ ssm, files, seqs, fr, alignment);
+
+ List<String> commands = buildSetAttributeCommands(featureMap);
+
+ StructureMappingcommandSet cs = new StructureMappingcommandSet(
+ ChimeraCommands.class, null,
+ commands.toArray(new String[commands.size()]));
+
+ return cs;
+ }
+
+ /**
+ * <pre>
+ * Helper method to build a map of
+ * { featureType, { feature value, AtomSpecModel } }
+ * </pre>
+ *
+ * @param ssm
+ * @param files
+ * @param seqs
+ * @param fr
+ * @param alignment
+ * @return
+ */
+ protected static Map<String, Map<Object, AtomSpecModel>> buildFeaturesMap(
+ StructureSelectionManager ssm, String[] files,
+ SequenceI[][] seqs, FeatureRenderer fr, AlignmentI alignment)
+ {
+ Map<String, Map<Object, AtomSpecModel>> theMap = new LinkedHashMap<String, Map<Object, AtomSpecModel>>();
+
+ List<String> visibleFeatures = fr.getDisplayedFeatureTypes();
+ if (visibleFeatures.isEmpty())
{
- colourData.put(model, modelData = new TreeMap<String, List<int[]>>());
+ return theMap;
}
- /*
- * Get/initialize map of data for colour, model and chain
- */
- List<int[]> chainData = modelData.get(chain);
- if (chainData == null)
+ for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
- modelData.put(chain, chainData = new ArrayList<int[]>());
+ StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
+
+ if (mapping == null || mapping.length < 1)
+ {
+ continue;
+ }
+
+ for (int seqNo = 0; seqNo < seqs[pdbfnum].length; seqNo++)
+ {
+ for (int m = 0; m < mapping.length; m++)
+ {
+ final SequenceI seq = seqs[pdbfnum][seqNo];
+ int sp = alignment.findIndex(seq);
+ if (mapping[m].getSequence() == seq && sp > -1)
+ {
+ /*
+ * found a sequence with a mapping to a structure;
+ * now scan its features
+ */
+ SequenceI asp = alignment.getSequenceAt(sp);
+
+ scanSequenceFeatures(visibleFeatures, mapping[m], asp, theMap,
+ pdbfnum);
+ }
+ }
+ }
+ }
+ return theMap;
+ }
+
+ /**
+ * Inspect features on the sequence; for each feature that is visible,
+ * determine its mapped ranges in the structure (if any) according to the
+ * given mapping, and add them to the map
+ *
+ * @param visibleFeatures
+ * @param mapping
+ * @param seq
+ * @param theMap
+ * @param modelNumber
+ */
+ protected static void scanSequenceFeatures(List<String> visibleFeatures,
+ StructureMapping mapping, SequenceI seq,
+ Map<String, Map<Object, AtomSpecModel>> theMap, int modelNumber)
+ {
+ SequenceFeature[] sfs = seq.getSequenceFeatures();
+ if (sfs == null)
+ {
+ return;
+ }
+
+ for (SequenceFeature sf : sfs)
+ {
+ String type = sf.getType();
+
+ /*
+ * Only copy visible features, don't copy any which originated
+ * from Chimera, and suppress uninteresting ones (e.g. RESNUM)
+ */
+ boolean isFromViewer = JalviewChimeraBinding.CHIMERA_FEATURE_GROUP
+ .equals(sf.getFeatureGroup());
+ if (isFromViewer || !visibleFeatures.contains(type))
+ {
+ continue;
+ }
+ List<int[]> mappedRanges = mapping.getPDBResNumRanges(sf.getBegin(),
+ sf.getEnd());
+
+ if (!mappedRanges.isEmpty())
+ {
+ String value = sf.getDescription();
+ if (value == null || value.length() == 0)
+ {
+ value = type;
+ }
+ float score = sf.getScore();
+ if (score != 0f && !Float.isNaN(score))
+ {
+ value = Float.toString(score);
+ }
+ Map<Object, AtomSpecModel> featureValues = theMap.get(type);
+ if (featureValues == null)
+ {
+ featureValues = new HashMap<Object, AtomSpecModel>();
+ theMap.put(type, featureValues);
+ }
+ for (int[] range : mappedRanges)
+ {
+ addColourRange(featureValues, value, modelNumber, range[0], range[1],
+ mapping.getChain());
+ }
+ }
}
+ }
+
+ /**
+ * Traverse the map of features/values/models/chains/positions to construct a
+ * list of 'setattr' commands (one per distinct feature type and value).
+ * <p>
+ * The format of each command is
+ *
+ * <pre>
+ * <blockquote> setattr r <featureName> " " #modelnumber:range.chain
+ * e.g. setattr r jv:chain <value> #0:2.B,4.B,9-12.B|#1:1.A,2-6.A,...
+ * </blockquote>
+ * </pre>
+ *
+ * @param featureMap
+ * @return
+ */
+ protected static List<String> buildSetAttributeCommands(
+ Map<String, Map<Object, AtomSpecModel>> featureMap)
+ {
+ List<String> commands = new ArrayList<String>();
+ for (String featureType : featureMap.keySet())
+ {
+ String attributeName = makeAttributeName(featureType);
+
+ /*
+ * clear down existing attributes for this feature
+ */
+ // 'problem' - sets attribute to None on all residues - overkill?
+ // commands.add("~setattr r " + attributeName + " :*");
+
+ Map<Object, AtomSpecModel> values = featureMap.get(featureType);
+ for (Object value : values.keySet())
+ {
+ /*
+ * for each distinct value recorded for this feature type,
+ * add a command to set the attribute on the mapped residues
+ * Put values in single quotes, encoding any embedded single quotes
+ */
+ StringBuilder sb = new StringBuilder(128);
+ String featureValue = value.toString();
+ featureValue = featureValue.replaceAll("\\'", "'");
+ sb.append("setattr r ").append(attributeName).append(" '")
+ .append(featureValue).append("' ");
+ sb.append(values.get(value).getAtomSpec());
+ commands.add(sb.toString());
+ }
+ }
+
+ return commands;
+ }
+
+ /**
+ * Makes a prefixed and valid Chimera attribute name. A jv_ prefix is applied
+ * for a 'Jalview' namespace, and any non-alphanumeric character is converted
+ * to an underscore.
+ *
+ * @param featureType
+ * @return <pre>
+ * @see https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/setattr.html
+ * </pre>
+ */
+ protected static String makeAttributeName(String featureType)
+ {
+ StringBuilder sb = new StringBuilder();
+ if (featureType != null)
+ {
+ for (char c : featureType.toCharArray())
+ {
+ sb.append(Character.isLetterOrDigit(c) ? c : '_');
+ }
+ }
+ String attName = NAMESPACE_PREFIX + sb.toString();
/*
- * Add the start/end positions
+ * Chimera treats an attribute name ending in 'color' as colour-valued;
+ * Jalview doesn't, so prevent this by appending an underscore
*/
- chainData.add(new int[] { startPos, endPos });
+ if (attName.toUpperCase().endsWith("COLOR"))
+ {
+ attName += "_";
+ }
+
+ return attName;
}
}
}
/**
- * Handler a ModelChanged notification from Chimera
+ * Handle a ModelChanged notification from Chimera
*
* @param substring
*/
*/
package jalview.ext.rbvi.chimera;
+import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureRenderer;
import jalview.api.SequenceRenderer;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.httpserver.AbstractRequestHandler;
import jalview.io.DataSourceType;
import jalview.util.MessageManager;
import java.awt.Color;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
import java.net.BindException;
import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collections;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;
public abstract class JalviewChimeraBinding extends AAStructureBindingModel
{
+ public static final String CHIMERA_FEATURE_GROUP = "Chimera";
+
// Chimera clause to exclude alternate locations in atom selection
private static final String NO_ALTLOCS = "&~@.B-Z&~@.2-9";
*/
private boolean loadingFinished = true;
- public String fileLoadingError;
-
/*
* Map of ChimeraModel objects keyed by PDB full local file name
*/
private Map<String, List<ChimeraModel>> chimeraMaps = new LinkedHashMap<String, List<ChimeraModel>>();
- /*
- * the default or current model displayed if the model cannot be identified
- * from the selection message
- */
- private int frameNo = 0;
-
- private String lastCommand;
-
String lastHighlightCommand;
/*
}
/**
- * Construct a title string for the viewer window based on the data Jalview
- * knows about
- *
- * @param verbose
- * @return
- */
- public String getViewerTitle(boolean verbose)
- {
- return getViewerTitle("Chimera", verbose);
- }
-
- /**
* Tells Chimera to display only the specified chains
*
* @param toshow
chimeraListener.shutdown();
chimeraListener = null;
}
- lastCommand = null;
viewer = null;
if (chimeraMonitor != null)
releaseUIResources();
}
+ @Override
public void colourByChain()
{
colourBySequence = false;
* <li>all others - white</li>
* </ul>
*/
+ @Override
public void colourByCharge()
{
colourBySequence = false;
}
/**
- * Construct and send a command to align structures against a reference
- * structure, based on one or more sequence alignments
- *
- * @param _alignment
- * an array of alignments to process
- * @param _refStructure
- * an array of corresponding reference structures (index into pdb
- * file array); if a negative value is passed, the first PDB file
- * mapped to an alignment sequence is used as the reference for
- * superposition
- * @param _hiddenCols
- * an array of corresponding hidden columns for each alignment
+ * {@inheritDoc}
*/
- public void superposeStructures(AlignmentI[] _alignment,
+ @Override
+ public String superposeStructures(AlignmentI[] _alignment,
int[] _refStructure, ColumnSelection[] _hiddenCols)
{
StringBuilder allComs = new StringBuilder(128);
if (!waitForFileLoad(files))
{
- return;
+ return null;
}
refreshPdbEntries();
}
/*
- * 'matched' array will hold 'true' for visible alignment columns where
+ * 'matched' bit i will be set for visible alignment columns i where
* all sequences have a residue with a mapping to the PDB structure
*/
- boolean matched[] = new boolean[alignment.getWidth()];
- for (int m = 0; m < matched.length; m++)
+ BitSet matched = new BitSet();
+ for (int m = 0; m < alignment.getWidth(); m++)
{
- matched[m] = (hiddenCols != null) ? hiddenCols.isVisible(m) : true;
+ if (hiddenCols == null || hiddenCols.isVisible(m))
+ {
+ matched.set(m);
+ }
}
SuperposeData[] structures = new SuperposeData[files.length];
refStructure = candidateRefStructure;
}
- int nmatched = 0;
- for (boolean b : matched)
- {
- if (b)
- {
- nmatched++;
- }
- }
+ int nmatched = matched.cardinality();
if (nmatched < 4)
{
- // TODO: bail out here because superposition illdefined?
+ return MessageManager.formatMessage("label.insufficient_residues",
+ nmatched);
}
/*
int lpos = -1;
boolean run = false;
StringBuilder molsel = new StringBuilder();
- for (int r = 0; r < matched.length; r++)
+
+ int nextColumnMatch = matched.nextSetBit(0);
+ while (nextColumnMatch != -1)
{
- if (matched[r])
+ int pdbResNum = structures[pdbfnum].pdbResNo[nextColumnMatch];
+ if (lpos != pdbResNum - 1)
{
- int pdbResNum = structures[pdbfnum].pdbResNo[r];
- if (lpos != pdbResNum - 1)
+ /*
+ * discontiguous - append last residue now
+ */
+ if (lpos != -1)
{
- /*
- * discontiguous - append last residue now
- */
- if (lpos != -1)
- {
- molsel.append(String.valueOf(lpos));
- molsel.append(chainCd);
- molsel.append(",");
- }
- run = false;
+ molsel.append(String.valueOf(lpos));
+ molsel.append(chainCd);
+ molsel.append(",");
}
- else
+ run = false;
+ }
+ else
+ {
+ /*
+ * extending a contiguous run
+ */
+ if (!run)
{
/*
- * extending a contiguous run
+ * start the range selection
*/
- if (!run)
- {
- /*
- * start the range selection
- */
- molsel.append(String.valueOf(lpos));
- molsel.append("-");
- }
- run = true;
+ molsel.append(String.valueOf(lpos));
+ molsel.append("-");
}
- lpos = pdbResNum;
+ run = true;
}
+ lpos = pdbResNum;
+ nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
}
/*
.append(";" + command.toString());
}
}
+
+ String error = null;
if (selectioncom.length() > 0)
{
// TODO: visually distinguish regions that were superposed
}
allComs.append("; ~display all; chain @CA|P; ribbon ")
.append(selectioncom.toString()).append("; focus");
- sendChimeraCommand(allComs.toString(), false);
+ List<String> chimeraReplies = sendChimeraCommand(allComs.toString(),
+ true);
+ for (String reply : chimeraReplies)
+ {
+ if (reply.toLowerCase().contains("unequal numbers of atoms"))
+ {
+ error = reply;
+ }
+ }
}
-
+ return error;
}
/**
}
/**
- * Send a command to Chimera, and optionally log any responses.
+ * Send a command to Chimera, and optionally log and return any responses.
+ * <p>
+ * Does nothing, and returns null, if the command is the same as the last one
+ * sent [why?].
*
* @param command
- * @param logResponse
+ * @param getResponse
*/
- public void sendChimeraCommand(final String command, boolean logResponse)
+ public List<String> sendChimeraCommand(final String command,
+ boolean getResponse)
{
if (viewer == null)
{
// ? thread running after viewer shut down
- return;
+ return null;
}
+ List<String> reply = null;
viewerCommandHistory(false);
- if (lastCommand == null || !lastCommand.equals(command))
+ if (true /*lastCommand == null || !lastCommand.equals(command)*/)
{
// trim command or it may never find a match in the replyLog!!
List<String> lastReply = viewer.sendChimeraCommand(command.trim(),
- logResponse);
- if (logResponse && debug)
+ getResponse);
+ if (getResponse)
{
- log("Response from command ('" + command + "') was:\n" + lastReply);
+ reply = lastReply;
+ if (debug)
+ {
+ log("Response from command ('" + command + "') was:\n"
+ + lastReply);
+ }
}
}
viewerCommandHistory(true);
- lastCommand = command;
+
+ return reply;
}
/**
String progressMsg);
/**
- * colour any structures associated with sequences in the given alignment
- * using the getFeatureRenderer() and getSequenceRenderer() renderers but only
- * if colourBySequence is enabled.
+ * Sends a set of colour commands to the structure viewer
+ *
+ * @param colourBySequenceCommands
*/
- public void colourBySequence(boolean showFeatures,
- jalview.api.AlignmentViewPanel alignmentv)
+ @Override
+ protected void colourBySequence(
+ StructureMappingcommandSet[] colourBySequenceCommands)
{
- if (!colourBySequence || !loadingFinished)
- {
- return;
- }
- if (getSsm() == null)
- {
- return;
- }
- String[] files = getPdbFile();
-
- SequenceRenderer sr = getSequenceRenderer(alignmentv);
-
- FeatureRenderer fr = null;
- if (showFeatures)
- {
- fr = getFeatureRenderer(alignmentv);
- }
- AlignmentI alignment = alignmentv.getAlignment();
-
- for (jalview.structure.StructureMappingcommandSet cpdbbyseq : getColourBySequenceCommands(
- files, sr, fr, alignment))
+ for (StructureMappingcommandSet cpdbbyseq : colourBySequenceCommands)
{
for (String command : cpdbbyseq.commands)
{
* @param files
* @param sr
* @param fr
- * @param alignment
+ * @param viewport
* @return
*/
+ @Override
protected StructureMappingcommandSet[] getColourBySequenceCommands(
String[] files, SequenceRenderer sr, FeatureRenderer fr,
- AlignmentI alignment)
+ AlignViewportI viewport)
{
return ChimeraCommands.getColourBySequenceCommand(getSsm(), files,
- getSequence(), sr, fr, alignment);
+ getSequence(), sr, fr, viewport);
}
/**
// //////////////////////////
/**
- * returns the current featureRenderer that should be used to colour the
- * structures
- *
- * @param alignment
- *
- * @return
- */
- public abstract FeatureRenderer getFeatureRenderer(
- AlignmentViewPanel alignment);
-
- /**
* instruct the Jalview binding to update the pdbentries vector if necessary
* prior to matching the viewer's contents to the list of structure files
* Jalview knows about.
*/
public abstract void refreshPdbEntries();
- private int getModelNum(String modelFileName)
- {
- String[] mfn = getPdbFile();
- if (mfn == null)
- {
- return -1;
- }
- for (int i = 0; i < mfn.length; i++)
- {
- if (mfn[i].equalsIgnoreCase(modelFileName))
- {
- return i;
- }
- }
- return -1;
- }
-
/**
* map between index of model filename returned from getPdbFile and the first
* index of models from this file in the viewer. Note - this is not trimmed -
*/
private int _modelFileNameMap[];
+
// ////////////////////////////////
// /StructureListener
@Override
}
/**
- * returns the current sequenceRenderer that should be used to colour the
- * structures
- *
- * @param alignment
- *
- * @return
- */
- public abstract SequenceRenderer getSequenceRenderer(
- AlignmentViewPanel alignment);
-
- /**
* Construct and send a command to highlight zero, one or more atoms. We do
* this by sending an "rlabel" command to show the residue label at that
* position.
* Parse model number, residue and chain for each selected position,
* formatted as #0:123.A or #1.2:87.B (#model.submodel:residue.chain)
*/
+ List<AtomSpec> atomSpecs = convertStructureResiduesToAlignment(selection);
+
+ /*
+ * Broadcast the selection (which may be empty, if the user just cleared all
+ * selections)
+ */
+ getSsm().mouseOverStructure(atomSpecs);
+ }
+
+ /**
+ * Converts a list of Chimera atomspecs to a list of AtomSpec representing the
+ * corresponding residues (if any) in Jalview
+ *
+ * @param structureSelection
+ * @return
+ */
+ protected List<AtomSpec> convertStructureResiduesToAlignment(
+ List<String> structureSelection)
+ {
List<AtomSpec> atomSpecs = new ArrayList<AtomSpec>();
- for (String atomSpec : selection)
+ for (String atomSpec : structureSelection)
{
- int colonPos = atomSpec.indexOf(":");
- if (colonPos == -1)
- {
- continue; // malformed
- }
-
- int hashPos = atomSpec.indexOf("#");
- String modelSubmodel = atomSpec.substring(hashPos + 1, colonPos);
- int dotPos = modelSubmodel.indexOf(".");
- int modelId = 0;
try
{
- modelId = Integer.valueOf(dotPos == -1 ? modelSubmodel
- : modelSubmodel.substring(0, dotPos));
- } catch (NumberFormatException e)
+ AtomSpec spec = AtomSpec.fromChimeraAtomspec(atomSpec);
+ String pdbfilename = getPdbFileForModel(spec.getModelNumber());
+ spec.setPdbFile(pdbfilename);
+ atomSpecs.add(spec);
+ } catch (IllegalArgumentException e)
{
- // ignore, default to model 0
+ System.err.println("Failed to parse atomspec: " + atomSpec);
}
+ }
+ return atomSpecs;
+ }
- String residueChain = atomSpec.substring(colonPos + 1);
- dotPos = residueChain.indexOf(".");
- int pdbResNum = Integer.parseInt(dotPos == -1 ? residueChain
- : residueChain.substring(0, dotPos));
-
- String chainId = dotPos == -1 ? "" : residueChain
- .substring(dotPos + 1);
-
- /*
- * Work out the pdbfilename from the model number
- */
- String pdbfilename = modelFileNames[frameNo];
- findfileloop: for (String pdbfile : this.chimeraMaps.keySet())
+ /**
+ * @param modelId
+ * @return
+ */
+ protected String getPdbFileForModel(int modelId)
+ {
+ /*
+ * Work out the pdbfilename from the model number
+ */
+ String pdbfilename = modelFileNames[0];
+ findfileloop: for (String pdbfile : this.chimeraMaps.keySet())
+ {
+ for (ChimeraModel cm : chimeraMaps.get(pdbfile))
{
- for (ChimeraModel cm : chimeraMaps.get(pdbfile))
+ if (cm.getModelNumber() == modelId)
{
- if (cm.getModelNumber() == modelId)
- {
- pdbfilename = pdbfile;
- break findfileloop;
- }
+ pdbfilename = pdbfile;
+ break findfileloop;
}
}
- atomSpecs.add(new AtomSpec(pdbfilename, chainId, pdbResNum, 0));
}
-
- /*
- * Broadcast the selection (which may be empty, if the user just cleared all
- * selections)
- */
- getSsm().mouseOverStructure(atomSpecs);
+ return pdbfilename;
}
private void log(String message)
return loadNotifiesHandled;
}
+ @Override
public void setJalviewColourScheme(ColourSchemeI cs)
{
colourBySequence = false;
List<String> residueSet = ResidueProperties.getResidues(isNucleotide(),
false);
- for (String res : residueSet)
+ for (String resName : residueSet)
{
- Color col = cs.findColour(res.charAt(0));
+ char res = resName.length() == 3 ? ResidueProperties
+ .getSingleCharacterCode(resName) : resName.charAt(0);
+ Color col = cs.findColour(res, 0, null, null, 0f);
command.append("color " + col.getRed() / normalise + ","
+ col.getGreen() / normalise + "," + col.getBlue()
- / normalise + " ::" + res + ";");
+ / normalise + " ::" + resName + ";");
}
sendAsynchronousCommand(command.toString(), COLOURING_CHIMERA);
* .html
* @param col
*/
+ @Override
public void setBackgroundColour(Color col)
{
viewerCommandHistory(false);
}
/**
+ * Returns a list of chains mapped in this viewer. Note this list is not
+ * currently scoped per structure.
+ *
+ * @return
+ */
+ @Override
+ public List<String> getChainNames()
+ {
+ return chainNames;
+ }
+
+ /**
* Send a 'focus' command to Chimera to recentre the visible display
*/
public void focusView()
}
}
+ /**
+ * Constructs and send commands to Chimera to set attributes on residues for
+ * features visible in Jalview
+ *
+ * @param avp
+ * @return
+ */
+ public int sendFeaturesToViewer(AlignmentViewPanel avp)
+ {
+ // TODO refactor as required to pull up to an interface
+ AlignmentI alignment = avp.getAlignment();
+ FeatureRenderer fr = getFeatureRenderer(avp);
- @Override
- public List<String> getChainNames()
+ /*
+ * fr is null if feature display is turned off
+ */
+ if (fr == null)
+ {
+ return 0;
+ }
+
+ String[] files = getPdbFile();
+ if (files == null)
+ {
+ return 0;
+ }
+
+ StructureMappingcommandSet commandSet = ChimeraCommands
+ .getSetAttributeCommandsForFeatures(getSsm(), files,
+ getSequence(), fr, alignment);
+ String[] commands = commandSet.commands;
+ if (commands.length > 10)
+ {
+ sendCommandsByFile(commands);
+ }
+ else
+ {
+ for (String command : commands)
+ {
+ sendAsynchronousCommand(command, null);
+ }
+ }
+ return commands.length;
+ }
+
+ /**
+ * Write commands to a temporary file, and send a command to Chimera to open
+ * the file as a commands script. For use when sending a large number of
+ * separate commands would overload the REST interface mechanism.
+ *
+ * @param commands
+ */
+ protected void sendCommandsByFile(String[] commands)
{
- return chainNames;
+ try
+ {
+ File tmp = File.createTempFile("chim", ".com");
+ tmp.deleteOnExit();
+ PrintWriter out = new PrintWriter(new FileOutputStream(tmp));
+ for (String command : commands)
+ {
+ out.println(command);
+ }
+ out.flush();
+ out.close();
+ String path = tmp.getAbsolutePath();
+ sendAsynchronousCommand("open cmd:" + path, null);
+ } catch (IOException e)
+ {
+ System.err
+ .println("Sending commands to Chimera via file failed with "
+ + e.getMessage());
+ }
+ }
+
+ /**
+ * Get Chimera residues which have the named attribute, find the mapped
+ * positions in the Jalview sequence(s), and set as sequence features
+ *
+ * @param attName
+ * @param alignmentPanel
+ */
+ public void copyStructureAttributesToFeatures(String attName,
+ AlignmentViewPanel alignmentPanel)
+ {
+ // todo pull up to AAStructureBindingModel (and interface?)
+
+ /*
+ * ask Chimera to list residues with the attribute, reporting its value
+ */
+ // this alternative command
+ // list residues spec ':*/attName' attr attName
+ // doesn't report 'None' values (which is good), but
+ // fails for 'average.bfactor' (which is bad):
+
+ String cmd = "list residues attr '" + attName + "'";
+ List<String> residues = sendChimeraCommand(cmd, true);
+
+ boolean featureAdded = createFeaturesForAttributes(attName, residues);
+ if (featureAdded)
+ {
+ alignmentPanel.getFeatureRenderer().featuresAdded();
+ }
+ }
+
+ /**
+ * Create features in Jalview for the given attribute name and structure
+ * residues.
+ *
+ * <pre>
+ * The residue list should be 0, 1 or more reply lines of the format:
+ * residue id #0:5.A isHelix -155.000836316 index 5
+ * or
+ * residue id #0:6.A isHelix None
+ * </pre>
+ *
+ * @param attName
+ * @param residues
+ * @return
+ */
+ protected boolean createFeaturesForAttributes(String attName,
+ List<String> residues)
+ {
+ boolean featureAdded = false;
+ String featureGroup = getViewerFeatureGroup();
+
+ for (String residue : residues)
+ {
+ AtomSpec spec = null;
+ String[] tokens = residue.split(" ");
+ if (tokens.length < 5)
+ {
+ continue;
+ }
+ String atomSpec = tokens[2];
+ String attValue = tokens[4];
+
+ /*
+ * ignore 'None' (e.g. for phi) or 'False' (e.g. for isHelix)
+ */
+ if ("None".equalsIgnoreCase(attValue)
+ || "False".equalsIgnoreCase(attValue))
+ {
+ continue;
+ }
+
+ try
+ {
+ spec = AtomSpec.fromChimeraAtomspec(atomSpec);
+ } catch (IllegalArgumentException e)
+ {
+ System.err.println("Problem parsing atomspec " + atomSpec);
+ continue;
+ }
+
+ String chainId = spec.getChain();
+ String description = attValue;
+ float score = Float.NaN;
+ try
+ {
+ score = Float.valueOf(attValue);
+ description = chainId;
+ } catch (NumberFormatException e)
+ {
+ // was not a float value
+ }
+
+ String pdbFile = getPdbFileForModel(spec.getModelNumber());
+ spec.setPdbFile(pdbFile);
+
+ List<AtomSpec> atoms = Collections.singletonList(spec);
+
+ /*
+ * locate the mapped position in the alignment (if any)
+ */
+ SearchResultsI sr = getSsm()
+ .findAlignmentPositionsForStructurePositions(atoms);
+
+ /*
+ * expect one matched alignment position, or none
+ * (if the structure position is not mapped)
+ */
+ for (SearchResultMatchI m : sr.getResults())
+ {
+ SequenceI seq = m.getSequence();
+ int start = m.getStart();
+ int end = m.getEnd();
+ SequenceFeature sf = new SequenceFeature(attName, description,
+ start, end, score, featureGroup);
+ // todo: should SequenceFeature have an explicit property for chain?
+ // note: repeating the action shouldn't duplicate features
+ featureAdded |= seq.addSequenceFeature(sf);
+ }
+ }
+ return featureAdded;
+ }
+
+ /**
+ * Answers the feature group name to apply to features created in Jalview from
+ * Chimera attributes
+ *
+ * @return
+ */
+ protected String getViewerFeatureGroup()
+ {
+ // todo pull up to interface
+ return CHIMERA_FEATURE_GROUP;
}
+
public Hashtable<String, String> getChainFile()
{
return chainFile;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.gui.ColourMenuHelper.ColourChangeListener;
import jalview.gui.ViewSelectionMenu.ViewSetProvider;
import jalview.io.AlignmentProperties;
import jalview.io.AnnotationFile;
import jalview.io.DataSourceType;
import jalview.io.FileFormat;
import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
import jalview.io.FileLoader;
import jalview.io.FormatAdapter;
import jalview.io.HtmlSvgOutput;
import jalview.io.NewickFile;
import jalview.io.TCoffeeScoreFile;
import jalview.jbgui.GAlignFrame;
-import jalview.schemes.Blosum62ColourScheme;
-import jalview.schemes.BuriedColourScheme;
-import jalview.schemes.ClustalxColourScheme;
import jalview.schemes.ColourSchemeI;
-import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.HelixColourScheme;
-import jalview.schemes.HydrophobicColourScheme;
-import jalview.schemes.NucleotideColourScheme;
-import jalview.schemes.PIDColourScheme;
-import jalview.schemes.PurinePyrimidineColourScheme;
-import jalview.schemes.RNAHelicesColourChooser;
+import jalview.schemes.ColourSchemes;
+import jalview.schemes.ResidueColourScheme;
import jalview.schemes.ResidueProperties;
-import jalview.schemes.StrandColourScheme;
import jalview.schemes.TCoffeeColourScheme;
-import jalview.schemes.TaylorColourScheme;
-import jalview.schemes.TurnColourScheme;
-import jalview.schemes.UserColourScheme;
-import jalview.schemes.ZappoColourScheme;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
import jalview.ws.DBRefFetcher;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
import java.beans.PropertyChangeEvent;
import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.JLayeredPane;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
-import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
* @version $Revision$
*/
public class AlignFrame extends GAlignFrame implements DropTargetListener,
- IProgressIndicator, AlignViewControllerGuiI
+ IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
{
public static final int DEFAULT_WIDTH = 700;
alignPanel);
if (viewport.getAlignmentConservationAnnotation() == null)
{
- BLOSUM62Colour.setEnabled(false);
+ // BLOSUM62Colour.setEnabled(false);
conservationMenuItem.setEnabled(false);
modifyConservation.setEnabled(false);
// PIDColour.setEnabled(false);
sortPairwiseMenuItem_actionPerformed(null);
}
- if (Desktop.desktop != null)
- {
- this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
- addServiceListeners();
- setGUINucleotide(viewport.getAlignment().isNucleotide());
- }
-
this.alignPanel.av
.setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
setMenusFromViewport(viewport);
buildSortByAnnotationScoresMenu();
buildTreeMenu();
+ buildColourMenu();
+
+ if (Desktop.desktop != null)
+ {
+ this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
+ addServiceListeners();
+ setGUINucleotide();
+ }
if (viewport.getWrapAlignment())
{
/**
* Configure menu items that vary according to whether the alignment is
* nucleotide or protein
- *
- * @param nucleotide
*/
- public void setGUINucleotide(boolean nucleotide)
+ public void setGUINucleotide()
{
+ AlignmentI al = getViewport().getAlignment();
+ boolean nucleotide = al.isNucleotide();
+
showTranslation.setVisible(nucleotide);
showReverse.setVisible(nucleotide);
showReverseComplement.setVisible(nucleotide);
conservationMenuItem.setEnabled(!nucleotide);
- modifyConservation.setEnabled(!nucleotide);
+ modifyConservation.setEnabled(!nucleotide
+ && conservationMenuItem.isSelected());
showGroupConservation.setEnabled(!nucleotide);
- rnahelicesColour.setEnabled(nucleotide);
- nucleotideColour.setEnabled(nucleotide);
- purinePyrimidineColour.setEnabled(nucleotide);
- RNAInteractionColour.setEnabled(nucleotide);
+
showComplementMenuItem.setText(nucleotide ? MessageManager
.getString("label.protein") : MessageManager
.getString("label.nucleotide"));
- setColourSelected(jalview.bin.Cache.getDefault(
- nucleotide ? Preferences.DEFAULT_COLOUR_NUC
- : Preferences.DEFAULT_COLOUR_PROT, "None"));
}
/**
padGapsMenuitem.setSelected(av.isPadGaps());
colourTextMenuItem.setSelected(av.isShowColourText());
abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
+ modifyPID.setEnabled(abovePIDThreshold.isSelected());
conservationMenuItem.setSelected(av.getConservationSelected());
+ modifyConservation.setEnabled(conservationMenuItem.isSelected());
seqLimits.setSelected(av.getShowJVSuffix());
idRightAlign.setSelected(av.isRightAlignIds());
centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
showSequenceLogo.setSelected(av.isShowSequenceLogo());
normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
- setColourSelected(ColourSchemeProperty.getColourName(av
- .getGlobalColourScheme()));
+ ColourMenuHelper.setColourSelected(colourMenu,
+ av.getGlobalColourScheme());
showSeqFeatures.setSelected(av.isShowSequenceFeatures());
hiddenMarkers.setState(av.getShowHiddenMarkers());
autoCalculate.setSelected(av.autoCalculateConsensus);
sortByTree.setSelected(av.sortByTree);
listenToViewSelections.setSelected(av.followSelection);
- rnahelicesColour.setEnabled(av.getAlignment().hasRNAStructure());
- rnahelicesColour
- .setSelected(av.getGlobalColourScheme() instanceof jalview.schemes.RNAHelicesColour);
showProducts.setEnabled(canShowProducts());
setGroovyEnabled(Desktop.getGroovyConsole() != null);
public void saveAs_actionPerformed(ActionEvent e)
{
String format = currentFileFormat == null ? null : currentFileFormat
- .toString();
+ .getName();
JalviewFileChooser chooser = JalviewFileChooser.forWrite(
Cache.getProperty("LAST_DIRECTORY"), format);
fileName = chooser.getSelectedFile().getPath();
- Cache.setProperty("DEFAULT_FILE_FORMAT",
- currentFileFormat.toString());
+ Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
Cache.setProperty("LAST_DIRECTORY", fileName);
saveAlignment(fileName, currentFileFormat);
}
else
{
- // if (!jalview.io.AppletFormatAdapter.isValidFormat(format, true))
- // {
- // warningMessage("Cannot save file " + fileName + " using format "
- // + format, "Alignment output format not supported");
- // if (!Jalview.isHeadlessMode())
- // {
- // saveAs_actionPerformed(null);
- // }
- // return false;
- // }
-
AlignmentExportData exportData = getAlignmentForExport(format,
viewport, null);
if (exportData.getSettings().isCancelled())
{
try
{
- java.io.PrintWriter out = new java.io.PrintWriter(
- new java.io.FileWriter(file));
+ PrintWriter out = new PrintWriter(new FileWriter(file));
out.print(output);
out.close();
this.setTitle(file);
statusBar.setText(MessageManager.formatMessage(
"label.successfully_saved_to_file_in_format",
- new Object[] { fileName, format }));
+ new Object[] { fileName, format.getName() }));
} catch (Exception ex)
{
success = false;
@Override
protected void outputText_actionPerformed(ActionEvent e)
{
-
- FileFormatI fileFormat = FileFormat.forName(e.getActionCommand());
+ FileFormatI fileFormat = FileFormats.getInstance().forName(
+ e.getActionCommand());
AlignmentExportData exportData = getAlignmentForExport(fileFormat,
viewport, null);
if (exportData.getSettings().isCancelled())
{
FileFormatI format = fileFormat;
cap.setText(new FormatAdapter(alignPanel, exportData.getSettings())
- .formatSequences(format,
- exportData.getAlignment(),
+ .formatSequences(format, exportData.getAlignment(),
exportData.getOmitHidden(),
exportData.getStartEndPostions(),
viewport.getColumnSelection()));
}
String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
- seqs,
- omitHidden, null);
+ seqs, omitHidden, null);
StringSelection ss = new StringSelection(output);
}
@Override
- public void textColour_actionPerformed(ActionEvent e)
+ public void textColour_actionPerformed()
{
new TextColourChooser().chooseColour(alignPanel, null);
}
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- protected void noColourmenuItem_actionPerformed(ActionEvent e)
- {
- changeColour(null);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void clustalColour_actionPerformed(ActionEvent e)
- {
- changeColour(new ClustalxColourScheme(viewport.getAlignment(),
- viewport.getHiddenRepSequences()));
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void zappoColour_actionPerformed(ActionEvent e)
- {
- changeColour(new ZappoColourScheme());
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void taylorColour_actionPerformed(ActionEvent e)
- {
- changeColour(new TaylorColourScheme());
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void hydrophobicityColour_actionPerformed(ActionEvent e)
- {
- changeColour(new HydrophobicColourScheme());
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void helixColour_actionPerformed(ActionEvent e)
- {
- changeColour(new HelixColourScheme());
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void strandColour_actionPerformed(ActionEvent e)
- {
- changeColour(new StrandColourScheme());
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void turnColour_actionPerformed(ActionEvent e)
- {
- changeColour(new TurnColourScheme());
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void buriedColour_actionPerformed(ActionEvent e)
- {
- changeColour(new BuriedColourScheme());
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void nucleotideColour_actionPerformed(ActionEvent e)
- {
- changeColour(new NucleotideColourScheme());
- }
-
- @Override
- public void purinePyrimidineColour_actionPerformed(ActionEvent e)
- {
- changeColour(new PurinePyrimidineColourScheme());
- }
-
/*
- * public void covariationColour_actionPerformed(ActionEvent e) {
+ * public void covariationColour_actionPerformed() {
* changeColour(new
* CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
* ()[0])); }
*/
@Override
- public void annotationColour_actionPerformed(ActionEvent e)
+ public void annotationColour_actionPerformed()
{
new AnnotationColourChooser(viewport, alignPanel);
}
new AnnotationColumnChooser(viewport, alignPanel);
}
+ /**
+ * Action on the user checking or unchecking the option to apply the selected
+ * colour scheme to all groups. If unchecked, groups may have their own
+ * independent colour schemes.
+ *
+ * @param selected
+ */
@Override
- public void rnahelicesColour_actionPerformed(ActionEvent e)
+ public void applyToAllGroups_actionPerformed(boolean selected)
{
- new RNAHelicesColourChooser(viewport, alignPanel);
+ viewport.setColourAppliesToAllGroups(selected);
}
/**
- * DOCUMENT ME!
+ * Action on user selecting a colour from the colour menu
*
- * @param e
- * DOCUMENT ME!
+ * @param name
+ * the name (not the menu item label!) of the colour scheme
*/
@Override
- protected void applyToAllGroups_actionPerformed(ActionEvent e)
+ public void changeColour_actionPerformed(String name)
{
- viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());
+ /*
+ * 'User Defined' opens a panel to configure or load a
+ * user-defined colour scheme
+ */
+ if (ResidueColourScheme.USER_DEFINED.equals(name))
+ {
+ new UserDefinedColours(alignPanel, null);
+ return;
+ }
+
+ /*
+ * otherwise set the chosen colour scheme (or null for 'None')
+ */
+ ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
+ viewport.getAlignment(), viewport.getHiddenRepSequences());
+ changeColour(cs);
}
/**
- * DOCUMENT ME!
+ * Actions on setting or changing the alignment colour scheme
*
* @param cs
- * DOCUMENT ME!
*/
@Override
public void changeColour(ColourSchemeI cs)
{
// TODO: pull up to controller method
-
if (cs != null)
{
- // Make sure viewport is up to date w.r.t. any sliders
- if (viewport.getAbovePIDThreshold())
- {
- int threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,
- "Background");
- viewport.setThreshold(threshold);
- }
-
- if (viewport.getConservationSelected())
- {
- cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel,
- cs, "Background"));
- }
- if (cs instanceof TCoffeeColourScheme)
- {
- tcoffeeColour.setEnabled(true);
- tcoffeeColour.setSelected(true);
- }
+ ColourMenuHelper.setColourSelected(colourMenu, cs.getSchemeName());
}
viewport.setGlobalColourScheme(cs);
}
/**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
+ * Show the PID threshold slider panel
*/
@Override
- protected void modifyPID_actionPerformed(ActionEvent e)
+ protected void modifyPID_actionPerformed()
{
- if (viewport.getAbovePIDThreshold()
- && viewport.getGlobalColourScheme() != null)
- {
- SliderPanel.setPIDSliderSource(alignPanel,
- viewport.getGlobalColourScheme(), "Background");
- SliderPanel.showPIDSlider();
- }
+ SliderPanel.setPIDSliderSource(alignPanel,
+ viewport.getResidueShading(), alignPanel.getViewName());
+ SliderPanel.showPIDSlider();
}
/**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
+ * Show the Conservation slider panel
*/
@Override
- protected void modifyConservation_actionPerformed(ActionEvent e)
+ protected void modifyConservation_actionPerformed()
{
- if (viewport.getConservationSelected()
- && viewport.getGlobalColourScheme() != null)
- {
- SliderPanel.setConservationSlider(alignPanel,
- viewport.getGlobalColourScheme(), "Background");
- SliderPanel.showConservationSlider();
- }
+ SliderPanel.setConservationSlider(alignPanel,
+ viewport.getResidueShading(), alignPanel.getViewName());
+ SliderPanel.showConservationSlider();
}
/**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
+ * Action on selecting or deselecting (Colour) By Conservation
*/
@Override
- protected void conservationMenuItem_actionPerformed(ActionEvent e)
+ public void conservationMenuItem_actionPerformed(boolean selected)
{
- viewport.setConservationSelected(conservationMenuItem.isSelected());
-
- viewport.setAbovePIDThreshold(false);
- abovePIDThreshold.setSelected(false);
+ modifyConservation.setEnabled(selected);
+ viewport.setConservationSelected(selected);
+ viewport.getResidueShading().setConservationApplied(selected);
changeColour(viewport.getGlobalColourScheme());
-
- modifyConservation_actionPerformed(null);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void abovePIDThreshold_actionPerformed(ActionEvent e)
- {
- viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());
-
- conservationMenuItem.setSelected(false);
- viewport.setConservationSelected(false);
-
- changeColour(viewport.getGlobalColourScheme());
-
- modifyPID_actionPerformed(null);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void userDefinedColour_actionPerformed(ActionEvent e)
- {
- if (e.getActionCommand().equals(
- MessageManager.getString("action.user_defined")))
+ if (selected)
{
- new UserDefinedColours(alignPanel, null);
+ modifyConservation_actionPerformed();
}
else
{
- UserColourScheme udc = (UserColourScheme) UserDefinedColours
- .getUserColourSchemes().get(e.getActionCommand());
-
- changeColour(udc);
+ SliderPanel.hideConservationSlider();
}
}
- public void updateUserColourMenu()
+ /**
+ * Action on selecting or deselecting (Colour) Above PID Threshold
+ */
+ @Override
+ public void abovePIDThreshold_actionPerformed(boolean selected)
{
+ modifyPID.setEnabled(selected);
+ viewport.setAbovePIDThreshold(selected);
+ if (!selected)
+ {
+ viewport.getResidueShading().setThreshold(0,
+ viewport.isIgnoreGapsConsensus());
+ }
- Component[] menuItems = colourMenu.getMenuComponents();
- int iSize = menuItems.length;
- for (int i = 0; i < iSize; i++)
+ changeColour(viewport.getGlobalColourScheme());
+ if (selected)
{
- if (menuItems[i].getName() != null
- && menuItems[i].getName().equals("USER_DEFINED"))
- {
- colourMenu.remove(menuItems[i]);
- iSize--;
- }
+ modifyPID_actionPerformed();
}
- if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
+ else
{
- java.util.Enumeration userColours = jalview.gui.UserDefinedColours
- .getUserColourSchemes().keys();
-
- while (userColours.hasMoreElements())
- {
- final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(
- userColours.nextElement().toString());
- radioItem.setName("USER_DEFINED");
- radioItem.addMouseListener(new MouseAdapter()
- {
- @Override
- public void mousePressed(MouseEvent evt)
- {
- if (evt.isPopupTrigger()) // Mac
- {
- offerRemoval(radioItem);
- }
- }
-
- @Override
- public void mouseReleased(MouseEvent evt)
- {
- if (evt.isPopupTrigger()) // Windows
- {
- offerRemoval(radioItem);
- }
- }
-
- /**
- * @param radioItem
- */
- void offerRemoval(final JRadioButtonMenuItem radioItem)
- {
- radioItem.removeActionListener(radioItem.getActionListeners()[0]);
-
- int option = JvOptionPane.showInternalConfirmDialog(
- jalview.gui.Desktop.desktop, MessageManager
- .getString("label.remove_from_default_list"),
- MessageManager
- .getString("label.remove_user_defined_colour"),
- JvOptionPane.YES_NO_OPTION);
- if (option == JvOptionPane.YES_OPTION)
- {
- jalview.gui.UserDefinedColours
- .removeColourFromDefaults(radioItem.getText());
- colourMenu.remove(radioItem);
- }
- else
- {
- radioItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- userDefinedColour_actionPerformed(evt);
- }
- });
- }
- }
- });
- radioItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- userDefinedColour_actionPerformed(evt);
- }
- });
-
- colourMenu.insert(radioItem, 15);
- colours.add(radioItem);
- }
+ SliderPanel.hidePIDSlider();
}
}
* DOCUMENT ME!
*/
@Override
- public void PIDColour_actionPerformed(ActionEvent e)
- {
- changeColour(new PIDColourScheme());
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
- public void BLOSUM62Colour_actionPerformed(ActionEvent e)
- {
- changeColour(new Blosum62ColourScheme());
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- @Override
public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
{
SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
}
}
- @Override
- protected void tcoffeeColorScheme_actionPerformed(ActionEvent e)
- {
- changeColour(new TCoffeeColourScheme(alignPanel.getAlignment()));
- }
-
public TreePanel ShowNewickTree(NewickFile nf, String title)
{
return ShowNewickTree(nf, title, 600, 500, 4, 5);
{
if (tcf.annotateAlignment(viewport.getAlignment(), true))
{
- tcoffeeColour.setEnabled(true);
- tcoffeeColour.setSelected(true);
+ buildColourMenu();
changeColour(new TCoffeeColourScheme(viewport.getAlignment()));
isAnnotation = true;
statusBar
}
if (FileFormat.Jnet.equals(format))
{
- JPredFile predictions = new JPredFile(
- file, sourceType);
+ JPredFile predictions = new JPredFile(file, sourceType);
new JnetAnnotationMaker();
JnetAnnotationMaker.add_annotation(predictions,
viewport.getAlignment(), 0, false);
}
/*
+ * 'focus' any colour slider that is open to the selected viewport
+ */
+ if (viewport.getConservationSelected())
+ {
+ SliderPanel.setConservationSlider(alignPanel,
+ viewport.getResidueShading(), alignPanel.getViewName());
+ }
+ else
+ {
+ SliderPanel.hideConservationSlider();
+ }
+ if (viewport.getAbovePIDThreshold())
+ {
+ SliderPanel.setPIDSliderSource(alignPanel,
+ viewport.getResidueShading(), alignPanel.getViewName());
+ }
+ else
+ {
+ SliderPanel.hidePIDSlider();
+ }
+
+ /*
* If there is a frame linked to this one in a SplitPane, switch it to the
* same view tab index. No infinite recursion of calls should happen, since
* tabSelectionChanged() should not get invoked on setting the selected
}
AlignmentI cdna = new Alignment(cdnaSeqs.toArray(new SequenceI[cdnaSeqs
.size()]));
- AlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
+ GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
cdna.alignAs(alignment);
String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
true,
(actionEvent.getModifiers() & (ActionEvent.META_MASK | ActionEvent.CTRL_MASK)) != 0);
}
+
+ /**
+ * Rebuilds the Colour menu, including any user-defined colours which have
+ * been loaded either on startup or during the session
+ */
+ public void buildColourMenu()
+ {
+ colourMenu.removeAll();
+
+ colourMenu.add(applyToAllGroups);
+ colourMenu.add(textColour);
+ colourMenu.addSeparator();
+
+ ColourMenuHelper.addMenuItems(colourMenu, this,
+ viewport.getAlignment(), false);
+
+ colourMenu.addSeparator();
+ colourMenu.add(conservationMenuItem);
+ colourMenu.add(modifyConservation);
+ colourMenu.add(abovePIDThreshold);
+ colourMenu.add(modifyPID);
+ colourMenu.add(annotationColour);
+
+ ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
+ String schemeName = colourScheme == null ? null : colourScheme
+ .getSchemeName();
+
+ ColourMenuHelper.setColourSelected(colourMenu, schemeName);
+ }
}
class PrintThread extends Thread
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.renderer.ResidueShader;
+import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.ResidueColourScheme;
import jalview.schemes.UserColourScheme;
import jalview.structure.CommandListener;
import jalview.structure.SelectionSource;
import java.util.Vector;
import javax.swing.JInternalFrame;
-import javax.swing.JOptionPane;
/**
* DOCUMENT ME!
initAutoAnnotation();
String colourProperty = alignment.isNucleotide() ? Preferences.DEFAULT_COLOUR_NUC
: Preferences.DEFAULT_COLOUR_PROT;
- String propertyValue = Cache.getProperty(colourProperty);
- if (propertyValue == null)
+ String schemeName = Cache.getProperty(colourProperty);
+ if (schemeName == null)
{
- // fall back on this property for backwards compatibility
- propertyValue = Cache.getProperty(Preferences.DEFAULT_COLOUR);
+ // only DEFAULT_COLOUR available in Jalview before 2.9
+ schemeName = Cache.getDefault(Preferences.DEFAULT_COLOUR,
+ ResidueColourScheme.NONE);
}
- if (propertyValue != null)
- {
- globalColourScheme = ColourSchemeProperty.getColour(alignment,
- propertyValue);
+ ColourSchemeI colourScheme = ColourSchemeProperty.getColourScheme(
+ alignment, schemeName);
+ residueShading = new ResidueShader(colourScheme);
- if (globalColourScheme instanceof UserColourScheme)
- {
- globalColourScheme = UserDefinedColours.loadDefaultColours();
- ((UserColourScheme) globalColourScheme).setThreshold(0,
- isIgnoreGapsConsensus());
- }
+ if (colourScheme instanceof UserColourScheme)
+ {
+ residueShading = new ResidueShader(
+ UserDefinedColours.loadDefaultColours());
+ residueShading.setThreshold(0, isIgnoreGapsConsensus());
+ }
- if (globalColourScheme != null)
- {
- globalColourScheme.setConsensus(hconsensus);
- }
+ if (residueShading != null)
+ {
+ residueShading.setConsensus(hconsensus);
}
}
super.setViewStyle(settingsForView);
setFont(new Font(viewStyle.getFontName(), viewStyle.getFontStyle(),
viewStyle.getFontSize()), false);
-
}
/**
oldgroupColours = new Hashtable<SequenceGroup, ColourSchemeI>();
for (SequenceGroup sg : ap.av.getAlignment().getGroups())
{
- if (sg.cs != null)
+ if (sg.getColourScheme() != null)
{
- oldgroupColours.put(sg, sg.cs);
+ oldgroupColours.put(sg, sg.getColourScheme());
}
}
}
for (SequenceGroup sg : ap.av.getAlignment().getGroups())
{
- sg.cs = oldgroupColours.get(sg);
+ sg.setColourScheme(oldgroupColours.get(sg));
}
}
}
import jalview.schemes.AnnotationColourGradient;
import jalview.util.MessageManager;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;
{
this.av = av;
this.ap = ap;
+ thresholdValue.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusLost(FocusEvent e)
+ {
+ thresholdValue_actionPerformed();
+ }
+ });
}
public AnnotationRowFilter()
continue;
}
+ AnnotationColourGradient scheme = null;
if (currentColours.isSelected())
{
- sg.cs = new AnnotationColourGradient(currentAnn, sg.cs,
- selectedThresholdOption);
- ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
- .isSelected());
-
+ scheme = new AnnotationColourGradient(currentAnn,
+ sg.getColourScheme(), selectedThresholdOption);
}
else
{
- sg.cs = new AnnotationColourGradient(currentAnn,
+ scheme = new AnnotationColourGradient(currentAnn,
minColour.getBackground(), maxColour.getBackground(),
selectedThresholdOption);
- ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
- .isSelected());
}
-
+ scheme.setSeqAssociated(seqAssociated.isSelected());
+ sg.setColourScheme(scheme);
}
}
return false;
package jalview.gui;
import jalview.bin.Cache;
-import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
-import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.gui.StructureViewer.ViewerType;
-import jalview.io.JalviewFileChooser;
-import jalview.io.JalviewFileView;
-import jalview.schemes.BuriedColourScheme;
-import jalview.schemes.ColourSchemeI;
-import jalview.schemes.HelixColourScheme;
-import jalview.schemes.HydrophobicColourScheme;
-import jalview.schemes.PurinePyrimidineColourScheme;
-import jalview.schemes.StrandColourScheme;
-import jalview.schemes.TaylorColourScheme;
-import jalview.schemes.TurnColourScheme;
-import jalview.schemes.ZappoColourScheme;
import jalview.structures.models.AAStructureBindingModel;
+import jalview.util.BrowserLauncher;
import jalview.util.MessageManager;
import jalview.util.Platform;
import jalview.ws.dbsources.Pdb;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JColorChooser;
import javax.swing.JInternalFrame;
-import javax.swing.JMenu;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
-import javax.swing.event.MenuEvent;
-import javax.swing.event.MenuListener;
public class AppJmol extends StructureViewerBase
{
RenderPanel renderPanel;
- ViewSelectionMenu seqColourBy;
-
/**
*
* @param files
{
useAlignmentPanelForSuperposition(ap);
}
+ initMenus();
if (leaveColouringToJmol || !usetoColour)
{
jmb.setColourBySequence(false);
viewerColour.setSelected(false);
}
this.setBounds(bounds);
- initMenus();
setViewId(viewid);
// jalview.gui.Desktop.addInternalFrame(this, "Loading File",
// bounds.width,bounds.height);
}
- private void initMenus()
+ @Override
+ protected void initMenus()
{
- seqColour.setSelected(jmb.isColourBySequence());
- viewerColour.setSelected(!jmb.isColourBySequence());
- if (_colourwith == null)
- {
- _colourwith = new Vector<AlignmentPanel>();
- }
- if (_alignwith == null)
- {
- _alignwith = new Vector<AlignmentPanel>();
- }
-
- seqColourBy = new ViewSelectionMenu(
- MessageManager.getString("label.colour_by"), this, _colourwith,
- new ItemListener()
- {
-
- @Override
- public void itemStateChanged(ItemEvent e)
- {
- if (!seqColour.isSelected())
- {
- seqColour.doClick();
- }
- else
- {
- // update the jmol display now.
- seqColour_actionPerformed(null);
- }
- }
- });
- viewMenu.add(seqColourBy);
- final ItemListener handler;
- JMenu alpanels = new ViewSelectionMenu(
- MessageManager.getString("label.superpose_with"), this,
- _alignwith, handler = new ItemListener()
- {
-
- @Override
- public void itemStateChanged(ItemEvent e)
- {
- alignStructs.setEnabled(_alignwith.size() > 0);
- alignStructs.setToolTipText(MessageManager
- .formatMessage(
- "label.align_structures_using_linked_alignment_views",
- new String[] { new Integer(_alignwith
- .size()).toString() }));
- }
- });
- handler.itemStateChanged(null);
- viewerActionMenu.add(alpanels);
- viewerActionMenu.addMenuListener(new MenuListener()
- {
-
- @Override
- public void menuSelected(MenuEvent e)
- {
- handler.itemStateChanged(null);
- }
-
- @Override
- public void menuDeselected(MenuEvent e)
- {
- // TODO Auto-generated method stub
+ super.initMenus();
- }
-
- @Override
- public void menuCanceled(MenuEvent e)
- {
- // TODO Auto-generated method stub
+ viewerActionMenu.setText(MessageManager.getString("label.jmol"));
- }
- });
+ viewerColour
+ .setText(MessageManager.getString("label.colour_with_jmol"));
+ viewerColour.setToolTipText(MessageManager
+ .getString("label.let_jmol_manage_structure_colours"));
}
IProgressIndicator progressBar = null;
openNewJmol(ap, new PDBEntry[] { pdbentry }, new SequenceI[][] { seq });
}
- /**
- * Answers true if this viewer already involves the given PDB ID
- */
- @Override
- protected boolean hasPdbId(String pdbId)
- {
- return jmb.hasPdbId(pdbId);
- }
-
private void openNewJmol(AlignmentPanel ap, PDBEntry[] pdbentrys,
SequenceI[][] seqs)
{
pdbentrys, seqs, null);
addAlignmentPanel(ap);
useAlignmentPanelForColourbyseq(ap);
+
if (pdbentrys.length > 1)
{
alignAddedStructures = true;
}
@Override
- public void pdbFile_actionPerformed(ActionEvent actionEvent)
- {
- JalviewFileChooser chooser = new JalviewFileChooser(
- jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
-
- chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle(MessageManager.getString("label.save_pdb_file"));
- chooser.setToolTipText(MessageManager.getString("action.save"));
-
- int value = chooser.showSaveDialog(this);
-
- if (value == JalviewFileChooser.APPROVE_OPTION)
- {
- BufferedReader in = null;
- try
- {
- // TODO: cope with multiple PDB files in view
- in = new BufferedReader(new FileReader(jmb.getPdbFile()[0]));
- File outFile = chooser.getSelectedFile();
-
- PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
- String data;
- while ((data = in.readLine()) != null)
- {
- if (!(data.indexOf("<PRE>") > -1 || data.indexOf("</PRE>") > -1))
- {
- out.println(data);
- }
- }
- out.close();
- } catch (Exception ex)
- {
- ex.printStackTrace();
- } finally
- {
- if (in != null)
- {
- try
- {
- in.close();
- } catch (IOException e)
- {
- // ignore
- }
- }
- }
- }
- }
-
- @Override
- public void viewMapping_actionPerformed(ActionEvent actionEvent)
- {
- jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer();
- try
- {
- cap.appendText(jmb.printMappings());
- } catch (OutOfMemoryError e)
- {
- new OOMWarning(
- "composing sequence-structure alignments for display in text box.",
- e);
- cap.dispose();
- return;
- }
- jalview.gui.Desktop.addInternalFrame(cap,
- MessageManager.getString("label.pdb_sequence_mapping"), 550,
- 600);
- }
-
- @Override
public void eps_actionPerformed(ActionEvent e)
{
makePDBImage(jalview.util.ImageMaker.TYPE.EPS);
}
@Override
- public void viewerColour_actionPerformed(ActionEvent actionEvent)
- {
- if (viewerColour.isSelected())
- {
- // disable automatic sequence colouring.
- jmb.setColourBySequence(false);
- }
- }
-
- @Override
- public void seqColour_actionPerformed(ActionEvent actionEvent)
- {
- jmb.setColourBySequence(seqColour.isSelected());
- if (_colourwith == null)
- {
- _colourwith = new Vector<AlignmentPanel>();
- }
- if (jmb.isColourBySequence())
- {
- if (!jmb.isLoadingFromArchive())
- {
- if (_colourwith.size() == 0 && getAlignmentPanel() != null)
- {
- // Make the currently displayed alignment panel the associated view
- _colourwith.add(getAlignmentPanel().alignFrame.alignPanel);
- }
- }
- // Set the colour using the current view for the associated alignframe
- for (AlignmentPanel ap : _colourwith)
- {
- jmb.colourBySequence(ap);
- }
- }
- }
-
- @Override
- public void chainColour_actionPerformed(ActionEvent actionEvent)
- {
- chainColour.setSelected(true);
- jmb.colourByChain();
- }
-
- @Override
- public void chargeColour_actionPerformed(ActionEvent actionEvent)
- {
- chargeColour.setSelected(true);
- jmb.colourByCharge();
- }
-
- @Override
- public void zappoColour_actionPerformed(ActionEvent actionEvent)
- {
- zappoColour.setSelected(true);
- jmb.setJalviewColourScheme(new ZappoColourScheme());
- }
-
- @Override
- public void taylorColour_actionPerformed(ActionEvent actionEvent)
- {
- taylorColour.setSelected(true);
- jmb.setJalviewColourScheme(new TaylorColourScheme());
- }
-
- @Override
- public void hydroColour_actionPerformed(ActionEvent actionEvent)
- {
- hydroColour.setSelected(true);
- jmb.setJalviewColourScheme(new HydrophobicColourScheme());
- }
-
- @Override
- public void helixColour_actionPerformed(ActionEvent actionEvent)
- {
- helixColour.setSelected(true);
- jmb.setJalviewColourScheme(new HelixColourScheme());
- }
-
- @Override
- public void strandColour_actionPerformed(ActionEvent actionEvent)
- {
- strandColour.setSelected(true);
- jmb.setJalviewColourScheme(new StrandColourScheme());
- }
-
- @Override
- public void turnColour_actionPerformed(ActionEvent actionEvent)
- {
- turnColour.setSelected(true);
- jmb.setJalviewColourScheme(new TurnColourScheme());
- }
-
- @Override
- public void buriedColour_actionPerformed(ActionEvent actionEvent)
- {
- buriedColour.setSelected(true);
- jmb.setJalviewColourScheme(new BuriedColourScheme());
- }
-
- @Override
- public void purinePyrimidineColour_actionPerformed(ActionEvent actionEvent)
- {
- setJalviewColourScheme(new PurinePyrimidineColourScheme());
- }
-
- @Override
- public void userColour_actionPerformed(ActionEvent actionEvent)
- {
- userColour.setSelected(true);
- new UserDefinedColours(this, null);
- }
-
- @Override
- public void backGround_actionPerformed(ActionEvent actionEvent)
- {
- java.awt.Color col = JColorChooser
- .showDialog(this, MessageManager
- .getString("label.select_backgroud_colour"), null);
- if (col != null)
- {
- jmb.setBackgroundColour(col);
- }
- }
-
- @Override
public void showHelp_actionPerformed(ActionEvent actionEvent)
{
try
{
- jalview.util.BrowserLauncher
+ BrowserLauncher
.openURL("http://jmol.sourceforge.net/docs/JmolUserGuide/");
} catch (Exception ex)
{
{
getSize(currentSize);
- if (jmb != null && jmb.fileLoadingError != null)
+ if (jmb != null && jmb.hasFileLoadingError())
{
g.setColor(Color.black);
g.fillRect(0, 0, currentSize.width, currentSize.height);
}
}
- public void updateTitleAndMenus()
- {
- if (jmb.fileLoadingError != null && jmb.fileLoadingError.length() > 0)
- {
- repaint();
- return;
- }
- setChainMenuItems(jmb.getChainNames());
-
- this.setTitle(jmb.getViewerTitle());
- if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1)
- {
- viewerActionMenu.setVisible(true);
- }
- if (!jmb.isLoadingFromArchive())
- {
- seqColour_actionPerformed(null);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * jalview.jbgui.GStructureViewer#alignStructs_actionPerformed(java.awt.event
- * .ActionEvent)
- */
- @Override
- protected void alignStructs_actionPerformed(ActionEvent actionEvent)
- {
- alignStructs_withAllAlignPanels();
- }
-
- private void alignStructs_withAllAlignPanels()
- {
- if (getAlignmentPanel() == null)
- {
- return;
- }
- ;
- if (_alignwith.size() == 0)
- {
- _alignwith.add(getAlignmentPanel());
- }
- ;
- try
- {
- AlignmentI[] als = new Alignment[_alignwith.size()];
- ColumnSelection[] alc = new ColumnSelection[_alignwith.size()];
- int[] alm = new int[_alignwith.size()];
- int a = 0;
-
- for (AlignmentPanel ap : _alignwith)
- {
- als[a] = ap.av.getAlignment();
- alm[a] = -1;
- alc[a++] = ap.av.getColumnSelection();
- }
- jmb.superposeStructures(als, alm, alc);
- } catch (Exception e)
- {
- StringBuffer sp = new StringBuffer();
- for (AlignmentPanel ap : _alignwith)
- {
- sp.append("'" + ap.alignFrame.getTitle() + "' ");
- }
- Cache.log.info("Couldn't align structures with the " + sp.toString()
- + "associated alignment panels.", e);
-
- }
-
- }
-
- @Override
- public void setJalviewColourScheme(ColourSchemeI ucs)
- {
- jmb.setJalviewColourScheme(ucs);
-
- }
-
- /**
- *
- * @param alignment
- * @return first alignment panel displaying given alignment, or the default
- * alignment panel
- */
- public AlignmentPanel getAlignmentPanelFor(AlignmentI alignment)
- {
- for (AlignmentPanel ap : getAllAlignmentPanels())
- {
- if (ap.av.getAlignment() == alignment)
- {
- return ap;
- }
- }
- return getAlignmentPanel();
- }
-
@Override
public AAStructureBindingModel getBinding()
{
}
@Override
+ protected String getViewerName()
+ {
+ return "Jmol";
+ }
+
+ @Override
protected AAStructureBindingModel getBindingModel()
{
return jmb;
}
-
}
package jalview.gui;
import jalview.bin.Cache;
-import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
-import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
+import jalview.ext.rbvi.chimera.ChimeraCommands;
import jalview.ext.rbvi.chimera.JalviewChimeraBinding;
import jalview.gui.StructureViewer.ViewerType;
import jalview.io.DataSourceType;
-import jalview.io.JalviewFileChooser;
-import jalview.io.JalviewFileView;
import jalview.io.StructureFile;
-import jalview.schemes.BuriedColourScheme;
-import jalview.schemes.ColourSchemeI;
-import jalview.schemes.HelixColourScheme;
-import jalview.schemes.HydrophobicColourScheme;
-import jalview.schemes.PurinePyrimidineColourScheme;
-import jalview.schemes.StrandColourScheme;
-import jalview.schemes.TaylorColourScheme;
-import jalview.schemes.TurnColourScheme;
-import jalview.schemes.ZappoColourScheme;
import jalview.structures.models.AAStructureBindingModel;
+import jalview.util.BrowserLauncher;
import jalview.util.MessageManager;
import jalview.util.Platform;
import jalview.ws.dbsources.Pdb;
import java.awt.event.ActionEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.io.BufferedReader;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Random;
-import java.util.Vector;
import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JColorChooser;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
+import javax.swing.JMenuItem;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
-import javax.swing.event.MenuEvent;
-import javax.swing.event.MenuListener;
/**
* GUI elements for handling an external chimera display
{
private JalviewChimeraBinding jmb;
- private boolean allChainsSelected = false;
-
private IProgressIndicator progressBar = null;
/*
private Random random = new Random();
+ private int myWidth = 500;
+
+ private int myHeight = 150;
+
/**
* Initialise menu options.
*/
- private void initMenus()
+ @Override
+ protected void initMenus()
{
+ super.initMenus();
+
viewerActionMenu.setText(MessageManager.getString("label.chimera"));
+
viewerColour.setText(MessageManager
.getString("label.colour_with_chimera"));
viewerColour.setToolTipText(MessageManager
.getString("label.let_chimera_manage_structure_colours"));
- helpItem.setText(MessageManager.getString("label.chimera_help"));
- seqColour.setSelected(jmb.isColourBySequence());
- viewerColour.setSelected(!jmb.isColourBySequence());
- if (_colourwith == null)
- {
- _colourwith = new Vector<AlignmentPanel>();
- }
- if (_alignwith == null)
- {
- _alignwith = new Vector<AlignmentPanel>();
- }
-
- // save As not yet implemented
- savemenu.setVisible(false);
- ViewSelectionMenu seqColourBy = new ViewSelectionMenu(
- MessageManager.getString("label.colour_by"), this, _colourwith,
- new ItemListener()
- {
- @Override
- public void itemStateChanged(ItemEvent e)
- {
- if (!seqColour.isSelected())
- {
- seqColour.doClick();
- }
- else
- {
- // update the Chimera display now.
- seqColour_actionPerformed(null);
- }
- }
- });
- viewMenu.add(seqColourBy);
+ helpItem.setText(MessageManager.getString("label.chimera_help"));
+ savemenu.setVisible(false); // not yet implemented
viewMenu.add(fitToWindow);
- final ItemListener handler;
- JMenu alpanels = new ViewSelectionMenu(
- MessageManager.getString("label.superpose_with"), this,
- _alignwith, handler = new ItemListener()
- {
- @Override
- public void itemStateChanged(ItemEvent e)
- {
- alignStructs.setEnabled(_alignwith.size() > 0);
- alignStructs.setToolTipText(MessageManager
- .formatMessage(
- "label.align_structures_using_linked_alignment_views",
- new Object[] { new Integer(_alignwith
- .size()).toString() }));
- }
- });
- handler.itemStateChanged(null);
- viewerActionMenu.add(alpanels);
- viewerActionMenu.addMenuListener(new MenuListener()
+ JMenuItem writeFeatures = new JMenuItem(
+ MessageManager.getString("label.create_chimera_attributes"));
+ writeFeatures.setToolTipText(MessageManager
+ .getString("label.create_chimera_attributes_tip"));
+ writeFeatures.addActionListener(new ActionListener()
{
-
@Override
- public void menuSelected(MenuEvent e)
+ public void actionPerformed(ActionEvent e)
{
- handler.itemStateChanged(null);
+ sendFeaturesToChimera();
}
+ });
+ viewerActionMenu.add(writeFeatures);
+
+ final JMenu fetchAttributes = new JMenu(
+ MessageManager.getString("label.fetch_chimera_attributes"));
+ fetchAttributes.setToolTipText(MessageManager
+ .getString("label.fetch_chimera_attributes_tip"));
+ fetchAttributes.addMouseListener(new MouseAdapter()
+ {
@Override
- public void menuDeselected(MenuEvent e)
+ public void mouseEntered(MouseEvent e)
{
- // TODO Auto-generated method stub
+ buildAttributesMenu(fetchAttributes);
}
+ });
+ viewerActionMenu.add(fetchAttributes);
- @Override
- public void menuCanceled(MenuEvent e)
+ }
+
+ /**
+ * Query Chimera for its residue attribute names and add them as items off the
+ * attributes menu
+ *
+ * @param attributesMenu
+ */
+ protected void buildAttributesMenu(JMenu attributesMenu)
+ {
+ List<String> atts = jmb.sendChimeraCommand("list resattr", true);
+ if (atts == null)
+ {
+ return;
+ }
+ attributesMenu.removeAll();
+ Collections.sort(atts);
+ for (String att : atts)
+ {
+ final String attName = att.split(" ")[1];
+
+ /*
+ * ignore 'jv_*' attributes, as these are Jalview features that have
+ * been transferred to residue attributes in Chimera!
+ */
+ if (!attName.startsWith(ChimeraCommands.NAMESPACE_PREFIX))
{
- // TODO Auto-generated method stub
+ JMenuItem menuItem = new JMenuItem(attName);
+ menuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ getChimeraAttributes(attName);
+ }
+ });
+ attributesMenu.add(menuItem);
}
- });
+ }
+ }
+
+ /**
+ * Read residues in Chimera with the given attribute name, and set as features
+ * on the corresponding sequence positions (if any)
+ *
+ * @param attName
+ */
+ protected void getChimeraAttributes(String attName)
+ {
+ jmb.copyStructureAttributesToFeatures(attName, getAlignmentPanel());
+ }
+
+ /**
+ * Send a command to Chimera to create residue attributes for Jalview features
+ * <p>
+ * The syntax is: setattr r <attName> <attValue> <atomSpec>
+ * <p>
+ * For example: setattr r jv:chain "Ferredoxin-1, Chloroplastic" #0:94.A
+ */
+ protected void sendFeaturesToChimera()
+ {
+ int count = jmb.sendFeaturesToViewer(getAlignmentPanel());
+ statusBar.setText(MessageManager.formatMessage("label.attributes_set",
+ count));
}
/**
}
}
- /**
- * Answers true if this viewer already involves the given PDB ID
- */
- @Override
- protected boolean hasPdbId(String pdbId)
- {
- return jmb.hasPdbId(pdbId);
- }
-
private void openNewChimera(AlignmentPanel ap, PDBEntry[] pdbentrys,
SequenceI[][] seqs)
{
createProgressBar();
- // FIXME extractChains needs pdbentries to match IDs to PDBEntry(s) on seqs
jmb = new JalviewChimeraBindingModel(this,
ap.getStructureSelectionManager(), pdbentrys, seqs, null);
addAlignmentPanel(ap);
useAlignmentPanelForColourbyseq(ap);
+
if (pdbentrys.length > 1)
{
alignAddedStructures = true;
useAlignmentPanelForSuperposition(ap);
}
jmb.setColourBySequence(true);
- setSize(400, 400); // probably should be a configurable/dynamic default here
+ setSize(myWidth, myHeight);
initMenus();
addingStructures = false;
}
-
-
/**
* Create a new viewer from saved session state data including Chimera session
* file
void initChimera()
{
jmb.setFinishedInit(false);
- jalview.gui.Desktop.addInternalFrame(this,
- jmb.getViewerTitle("Chimera", true), getBounds().width,
+ Desktop.addInternalFrame(this,
+ jmb.getViewerTitle(getViewerName(), true), getBounds().width,
getBounds().height);
if (!jmb.launchChimera())
+ chimeraSessionFile);
}
}
- jmb.setFinishedInit(true);
jmb.startChimeraListener();
}
-
/**
* Show only the selected chain(s) in the viewer
*/
{
String prompt = MessageManager.formatMessage(
"label.confirm_close_chimera",
- new Object[] { jmb.getViewerTitle("Chimera", false) });
+ new Object[] { jmb.getViewerTitle(getViewerName(),
+ false) });
prompt = JvSwingUtils.wrapTooltip(true, prompt);
int confirm = JvOptionPane.showConfirmDialog(this, prompt,
MessageManager.getString("label.close_viewer"),
if (files.length() > 0)
{
+ jmb.setFinishedInit(false);
if (!addingStructures)
{
try
try
{
int pos = filePDBpos.get(num).intValue();
- long startTime = startProgressBar("Chimera "
+ long startTime = startProgressBar(getViewerName() + " "
+ MessageManager.getString("status.opening_file_for")
+ " " + pe.getId());
jmb.openFile(pe);
}
}
}
+
jmb.refreshGUI();
jmb.setFinishedInit(true);
jmb.setLoadingFromArchive(false);
}
@Override
- public void pdbFile_actionPerformed(ActionEvent actionEvent)
- {
- JalviewFileChooser chooser = new JalviewFileChooser(
- jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
-
- chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle(MessageManager.getString("label.save_pdb_file"));
- chooser.setToolTipText(MessageManager.getString("action.save"));
-
- int value = chooser.showSaveDialog(this);
-
- if (value == JalviewFileChooser.APPROVE_OPTION)
- {
- BufferedReader in = null;
- try
- {
- // TODO: cope with multiple PDB files in view
- in = new BufferedReader(new FileReader(jmb.getPdbFile()[0]));
- File outFile = chooser.getSelectedFile();
-
- PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
- String data;
- while ((data = in.readLine()) != null)
- {
- if (!(data.indexOf("<PRE>") > -1 || data.indexOf("</PRE>") > -1))
- {
- out.println(data);
- }
- }
- out.close();
- } catch (Exception ex)
- {
- ex.printStackTrace();
- } finally
- {
- if (in != null)
- {
- try
- {
- in.close();
- } catch (IOException e)
- {
- e.printStackTrace();
- }
- }
- }
- }
- }
-
- @Override
- public void viewMapping_actionPerformed(ActionEvent actionEvent)
- {
- jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer();
- try
- {
- cap.appendText(jmb.printMappings());
- } catch (OutOfMemoryError e)
- {
- new OOMWarning(
- "composing sequence-structure alignments for display in text box.",
- e);
- cap.dispose();
- return;
- }
- jalview.gui.Desktop.addInternalFrame(cap,
- MessageManager.getString("label.pdb_sequence_mapping"), 550,
- 600);
- }
-
- @Override
public void eps_actionPerformed(ActionEvent e)
{
throw new Error(
}
@Override
- public void viewerColour_actionPerformed(ActionEvent actionEvent)
- {
- if (viewerColour.isSelected())
- {
- // disable automatic sequence colouring.
- jmb.setColourBySequence(false);
- }
- }
-
- @Override
- public void seqColour_actionPerformed(ActionEvent actionEvent)
- {
- jmb.setColourBySequence(seqColour.isSelected());
- if (_colourwith == null)
- {
- _colourwith = new Vector<AlignmentPanel>();
- }
- if (jmb.isColourBySequence())
- {
- if (!jmb.isLoadingFromArchive())
- {
- if (_colourwith.size() == 0 && getAlignmentPanel() != null)
- {
- // Make the currently displayed alignment panel the associated view
- _colourwith.add(getAlignmentPanel().alignFrame.alignPanel);
- }
- }
- // Set the colour using the current view for the associated alignframe
- for (AlignmentPanel ap : _colourwith)
- {
- jmb.colourBySequence(ap.av.isShowSequenceFeatures(), ap);
- }
- }
- }
-
- @Override
- public void chainColour_actionPerformed(ActionEvent actionEvent)
- {
- chainColour.setSelected(true);
- jmb.colourByChain();
- }
-
- @Override
- public void chargeColour_actionPerformed(ActionEvent actionEvent)
- {
- chargeColour.setSelected(true);
- jmb.colourByCharge();
- }
-
- @Override
- public void zappoColour_actionPerformed(ActionEvent actionEvent)
- {
- zappoColour.setSelected(true);
- jmb.setJalviewColourScheme(new ZappoColourScheme());
- }
-
- @Override
- public void taylorColour_actionPerformed(ActionEvent actionEvent)
- {
- taylorColour.setSelected(true);
- jmb.setJalviewColourScheme(new TaylorColourScheme());
- }
-
- @Override
- public void hydroColour_actionPerformed(ActionEvent actionEvent)
- {
- hydroColour.setSelected(true);
- jmb.setJalviewColourScheme(new HydrophobicColourScheme());
- }
-
- @Override
- public void helixColour_actionPerformed(ActionEvent actionEvent)
- {
- helixColour.setSelected(true);
- jmb.setJalviewColourScheme(new HelixColourScheme());
- }
-
- @Override
- public void strandColour_actionPerformed(ActionEvent actionEvent)
- {
- strandColour.setSelected(true);
- jmb.setJalviewColourScheme(new StrandColourScheme());
- }
-
- @Override
- public void turnColour_actionPerformed(ActionEvent actionEvent)
- {
- turnColour.setSelected(true);
- jmb.setJalviewColourScheme(new TurnColourScheme());
- }
-
- @Override
- public void buriedColour_actionPerformed(ActionEvent actionEvent)
- {
- buriedColour.setSelected(true);
- jmb.setJalviewColourScheme(new BuriedColourScheme());
- }
-
- @Override
- public void purinePyrimidineColour_actionPerformed(ActionEvent actionEvent)
- {
- setJalviewColourScheme(new PurinePyrimidineColourScheme());
- }
-
- @Override
- public void userColour_actionPerformed(ActionEvent actionEvent)
- {
- userColour.setSelected(true);
- new UserDefinedColours(this, null);
- }
-
- @Override
- public void backGround_actionPerformed(ActionEvent actionEvent)
- {
- java.awt.Color col = JColorChooser
- .showDialog(this, MessageManager
- .getString("label.select_backgroud_colour"), null);
- if (col != null)
- {
- jmb.setBackgroundColour(col);
- }
- }
-
- @Override
public void showHelp_actionPerformed(ActionEvent actionEvent)
{
try
{
- jalview.util.BrowserLauncher
+ BrowserLauncher
.openURL("https://www.cgl.ucsf.edu/chimera/docs/UsersGuide");
- } catch (Exception ex)
- {
- }
- }
-
- public void updateTitleAndMenus()
- {
- if (jmb.fileLoadingError != null && jmb.fileLoadingError.length() > 0)
- {
- repaint();
- return;
- }
- setChainMenuItems(jmb.getChainNames());
-
- this.setTitle(jmb.getViewerTitle("Chimera", true));
- if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1)
- {
- viewerActionMenu.setVisible(true);
- }
- if (!jmb.isLoadingFromArchive())
- {
- seqColour_actionPerformed(null);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * jalview.jbgui.GStructureViewer#alignStructs_actionPerformed(java.awt.event
- * .ActionEvent)
- */
- @Override
- protected void alignStructs_actionPerformed(ActionEvent actionEvent)
- {
- alignStructs_withAllAlignPanels();
- }
-
- private void alignStructs_withAllAlignPanels()
- {
- if (getAlignmentPanel() == null)
- {
- return;
- }
-
- if (_alignwith.size() == 0)
- {
- _alignwith.add(getAlignmentPanel());
- }
-
- try
- {
- AlignmentI[] als = new Alignment[_alignwith.size()];
- ColumnSelection[] alc = new ColumnSelection[_alignwith.size()];
- int[] alm = new int[_alignwith.size()];
- int a = 0;
-
- for (AlignmentPanel ap : _alignwith)
- {
- als[a] = ap.av.getAlignment();
- alm[a] = -1;
- alc[a++] = ap.av.getColumnSelection();
- }
- jmb.superposeStructures(als, alm, alc);
- } catch (Exception e)
- {
- StringBuffer sp = new StringBuffer();
- for (AlignmentPanel ap : _alignwith)
- {
- sp.append("'" + ap.alignFrame.getTitle() + "' ");
- }
- Cache.log.info("Couldn't align structures with the " + sp.toString()
- + "associated alignment panels.", e);
- }
- }
-
- @Override
- public void setJalviewColourScheme(ColourSchemeI ucs)
- {
- jmb.setJalviewColourScheme(ucs);
-
- }
-
- /**
- *
- * @param alignment
- * @return first alignment panel displaying given alignment, or the default
- * alignment panel
- */
- public AlignmentPanel getAlignmentPanelFor(AlignmentI alignment)
- {
- for (AlignmentPanel ap : getAllAlignmentPanels())
+ } catch (IOException ex)
{
- if (ap.av.getAlignment() == alignment)
- {
- return ap;
- }
}
- return getAlignmentPanel();
}
@Override
}
@Override
- protected AAStructureBindingModel getBindingModel()
+ protected String getViewerName()
{
- return jmb;
+ return "Chimera";
+ }
+
+ /**
+ * Sends commands to align structures according to associated alignment(s).
+ *
+ * @return
+ */
+ @Override
+ protected String alignStructs_withAllAlignPanels()
+ {
+ String reply = super.alignStructs_withAllAlignPanels();
+ if (reply != null)
+ {
+ statusBar.setText("Superposition failed: " + reply);
+ }
+ return reply;
}
@Override
{
return progressBar;
}
+
+ @Override
+ protected AAStructureBindingModel getBindingModel()
+ {
+ return jmb;
+ }
}
--- /dev/null
+package jalview.gui;
+
+import jalview.bin.Cache;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemes;
+import jalview.schemes.ResidueColourScheme;
+import jalview.schemes.UserColourScheme;
+import jalview.util.MessageManager;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JMenu;
+import javax.swing.JRadioButtonMenuItem;
+
+public class ColourMenuHelper
+{
+ public interface ColourChangeListener
+ {
+ void changeColour_actionPerformed(String name);
+ }
+
+ /**
+ * Adds items to the colour menu, as mutually exclusive members of a button
+ * group. The callback handler is responsible for the action on selecting any
+ * of these options. The callback method receives the name of the selected
+ * colour, or "None" or "User Defined". This method returns the ButtonGroup to
+ * which items were added.
+ * <ul>
+ * <li>None</li>
+ * <li>Clustal</li>
+ * <li>...other 'built-in' colours</li>
+ * <li>...any user-defined colours</li>
+ * <li>User Defined..</li>
+ * </ul>
+ *
+ * @param colourMenu
+ * the menu to attach items to
+ * @param client
+ * a callback to handle menu selection
+ * @param coll
+ * the data the menu is being built for
+ * @param simpleOnly
+ * if true, only simple per-residue colour schemes are included
+ */
+ public static ButtonGroup addMenuItems(final JMenu colourMenu,
+ final ColourChangeListener client, AnnotatedCollectionI coll,
+ boolean simpleOnly)
+ {
+ /*
+ * ButtonGroup groups those items whose
+ * selection is mutually exclusive
+ */
+ ButtonGroup colours = new ButtonGroup();
+
+ if (!simpleOnly)
+ {
+ JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem(
+ MessageManager.getString("label.none"));
+ noColourmenuItem.setName(ResidueColourScheme.NONE);
+ noColourmenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ client.changeColour_actionPerformed(ResidueColourScheme.NONE);
+ }
+ });
+ colourMenu.add(noColourmenuItem);
+ colours.add(noColourmenuItem);
+ }
+
+ /*
+ * scan registered colour schemes (built-in or user-defined
+ * and add them to the menu (in the order they were registered)
+ */
+ Iterable<ColourSchemeI> colourSchemes = ColourSchemes.getInstance()
+ .getColourSchemes();
+ for (ColourSchemeI scheme : colourSchemes)
+ {
+ if (simpleOnly && !scheme.isSimple())
+ {
+ continue;
+ }
+
+ /*
+ * button text is i18n'd but the name is the canonical name of
+ * the colour scheme (inspected in setColourSelected())
+ */
+ final String name = scheme.getSchemeName();
+ String label = MessageManager.getStringOrReturn("label.colourScheme_"
+ + name.toLowerCase().replace(" ", "_"), name);
+ final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(label);
+ radioItem.setName(name);
+ radioItem.setEnabled(scheme.isApplicableTo(coll));
+ if (scheme instanceof UserColourScheme)
+ {
+ /*
+ * user-defined colour scheme loaded on startup or during the
+ * Jalview session; right-click on this offers the option to
+ * remove it as a colour choice
+ */
+ radioItem.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mousePressed(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Mac
+ {
+ offerRemoval();
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Windows
+ {
+ offerRemoval();
+ }
+ }
+
+ void offerRemoval()
+ {
+ ActionListener al = radioItem.getActionListeners()[0];
+ radioItem.removeActionListener(al);
+ int option = JvOptionPane.showInternalConfirmDialog(
+ Desktop.desktop, MessageManager
+ .getString("label.remove_from_default_list"),
+ MessageManager
+ .getString("label.remove_user_defined_colour"),
+ JvOptionPane.YES_NO_OPTION);
+ if (option == JvOptionPane.YES_OPTION)
+ {
+ ColourSchemes.getInstance().removeColourScheme(
+ radioItem.getName());
+ colourMenu.remove(radioItem);
+ updatePreferences();
+ }
+ else
+ {
+ radioItem.addActionListener(al);
+ }
+ }
+ });
+ }
+ radioItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent evt)
+ {
+ client.changeColour_actionPerformed(name);
+ }
+ });
+ colourMenu.add(radioItem);
+ colours.add(radioItem);
+ }
+
+ /*
+ * only add the option to load/configure a user-defined colour
+ * to the AlignFrame colour menu
+ */
+ if (client instanceof AlignFrame)
+ {
+ final String label = MessageManager.getString("action.user_defined");
+ JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem(
+ label);
+ userDefinedColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ client.changeColour_actionPerformed(ResidueColourScheme.USER_DEFINED);
+ }
+ });
+ colourMenu.add(userDefinedColour);
+ colours.add(userDefinedColour);
+ }
+
+ return colours;
+ }
+
+ /**
+ * Marks as selected the colour menu item matching the given name, or the
+ * first item ('None') if no match is found
+ *
+ * @param colourMenu
+ * @param colourName
+ */
+ public static void setColourSelected(JMenu colourMenu, String colourName)
+ {
+ if (colourName == null)
+ {
+ return;
+ }
+
+ JRadioButtonMenuItem none = null;
+
+ /*
+ * select the radio button whose name matches the colour name
+ * (not the button text, as it may be internationalised)
+ */
+ for (Component menuItem : colourMenu.getMenuComponents())
+ {
+ if (menuItem instanceof JRadioButtonMenuItem)
+ {
+ String buttonName = ((JRadioButtonMenuItem) menuItem).getName();
+ if (colourName.equals(buttonName))
+ {
+ ((JRadioButtonMenuItem) menuItem).setSelected(true);
+ return;
+ }
+ if (ResidueColourScheme.NONE.equals(buttonName))
+ {
+ none = (JRadioButtonMenuItem) menuItem;
+ }
+ }
+ }
+ if (none != null)
+ {
+ none.setSelected(true);
+ }
+ }
+
+ /**
+ * Marks as selected the colour menu item matching the given colour scheme, or
+ * the first item ('None') if no match is found
+ *
+ * @param colourMenu
+ * @param cs
+ */
+ public static void setColourSelected(JMenu colourMenu, ColourSchemeI cs)
+ {
+ setColourSelected(colourMenu, cs == null ? ResidueColourScheme.NONE
+ : cs.getSchemeName());
+ }
+
+ /**
+ * Updates the USER_DEFINE_COLOURS preference to remove any de-registered
+ * colour scheme
+ */
+ static void updatePreferences()
+ {
+ StringBuilder coloursFound = new StringBuilder();
+ String[] files = Cache.getProperty("USER_DEFINED_COLOURS").split("\\|");
+
+ /*
+ * the property does not include the scheme name, it is in the file;
+ * so just load the colour schemes and discard any whose name is not
+ * registered
+ */
+ for (String file : files)
+ {
+ try
+ {
+ UserColourScheme ucs = ColourSchemes.loadColourScheme(file);
+ if (ucs != null
+ && ColourSchemes.getInstance().nameExists(ucs.getName()))
+ {
+ if (coloursFound.length() > 0)
+ {
+ coloursFound.append("|");
+ }
+ coloursFound.append(file);
+ }
+ } catch (Exception ex)
+ {
+ System.out.println("Error loading User ColourFile\n" + ex);
+ }
+ }
+
+ if (coloursFound.toString().length() > 1)
+ {
+ Cache.setProperty("USER_DEFINED_COLOURS", coloursFound.toString());
+ }
+ else
+ {
+ Cache.applicationProperties.remove("USER_DEFINED_COLOURS");
+ }
+ }
+}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SequenceI;
-import jalview.io.AlignmentFileI;
+import jalview.io.AlignmentFileReaderI;
import jalview.io.AppletFormatAdapter;
import jalview.io.DataSourceType;
import jalview.io.FileFormatException;
AlignViewportI viewport;
- AlignmentFileI source = null;
+ AlignmentFileReaderI source = null;
public CutAndPasteTransfer()
{
if (!Jalview.isHeadlessMode())
{
JvOptionPane.showInternalMessageDialog(Desktop.desktop,
- AppletFormatAdapter.SUPPORTED_FORMATS,
+ AppletFormatAdapter.getSupportedFormats(),
MessageManager.getString("label.couldnt_read_data"),
JvOptionPane.WARNING_MESSAGE);
}
{
String title = MessageManager.formatMessage(
"label.input_cut_paste_params",
- new String[] { format.toString() });
+ new String[] { format.getName() });
FeatureSettingsModelI proxyColourScheme = source
.getFeatureColourScheme();
if (!Jalview.isHeadlessMode())
{
JvOptionPane.showInternalMessageDialog(Desktop.desktop,
- AppletFormatAdapter.SUPPORTED_FORMATS,
+ AppletFormatAdapter.getSupportedFormats(),
MessageManager.getString("label.couldnt_read_data"),
JvOptionPane.WARNING_MESSAGE);
}
pane12.add(nametf, BorderLayout.EAST);
panel.add(pane12, BorderLayout.NORTH);
pane12 = new JPanel(new BorderLayout());
- pane12.add(new JLabel(MessageManager.getString("label.url")),
+ pane12.add(new JLabel(MessageManager.getString("label.url:")),
BorderLayout.NORTH);
pane12.add(seqs, BorderLayout.SOUTH);
pane12.add(urltf, BorderLayout.EAST);
*/
package jalview.gui;
-import static jalview.util.UrlConstants.EMBLEBI_STRING;
import static jalview.util.UrlConstants.SEQUENCE_ID;
import jalview.api.AlignViewportI;
import jalview.io.FileFormat;
import jalview.io.FileFormatException;
import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
import jalview.io.FileLoader;
import jalview.io.IdentifyFile;
import jalview.io.JalviewFileChooser;
import jalview.jbgui.GSplitFrame;
import jalview.jbgui.GStructureViewer;
import jalview.structure.StructureSelectionManager;
+import jalview.urls.IdOrgSettings;
import jalview.util.ImageMaker;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import jalview.util.UrlConstants;
import jalview.viewmodel.AlignmentViewport;
import jalview.ws.params.ParamManager;
+import jalview.ws.utils.UrlDownloadClient;
import java.awt.BorderLayout;
import java.awt.Color;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
showNews.setVisible(false);
+ getIdentifiersOrgData();
+
checkURLLinks();
this.addWindowListener(new WindowAdapter()
});
}
+ public void getIdentifiersOrgData()
+ {
+ // Thread off the identifiers fetcher
+ addDialogThread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ Cache.log.debug("Downloading data from identifiers.org");
+ UrlDownloadClient client = new UrlDownloadClient();
+ try
+ {
+ client.download(IdOrgSettings.getUrl(),
+ IdOrgSettings.getDownloadLocation());
+ } catch (IOException e)
+ {
+ Cache.log.debug("Exception downloading identifiers.org data"
+ + e.getMessage());
+ }
+ }
+ });
+ }
+
@Override
protected void showNews_actionPerformed(ActionEvent e)
{
Cache.setProperty("LAST_DIRECTORY", chooser
.getSelectedFile().getParent());
- FileFormatI format = null;
- FileFormatI selectedFormat = chooser.getSelectedFormat();
- if (FileFormat.Jalview.equals(selectedFormat))
- {
- format = FileFormat.Jalview;
- }
- else
+ FileFormatI format = chooser.getSelectedFormat();
+
+ /*
+ * Call IdentifyFile to verify the file contains what its extension implies.
+ * Skip this step for dynamically added file formats, because
+ * IdentifyFile does not know how to recognise them.
+ */
+ if (FileFormats.getInstance().isIdentifiable(format))
{
try
{
format = new IdentifyFile().identify(choice, DataSourceType.FILE);
} catch (FileFormatException e)
{
- // format is null
+ // format = null; //??
}
}
@Override
public void saveState_actionPerformed(ActionEvent e)
{
- JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"), "jvp", "Jalview Project");
+ JalviewFileChooser chooser = new JalviewFileChooser("jvp",
+ "Jalview Project");
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager.getString("label.save_state"));
{
if (v_client != null)
{
- JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"), "vdj",// TODO: VAMSAS DOCUMENT EXTENSION is VDJ
+ // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
+ JalviewFileChooser chooser = new JalviewFileChooser("vdj",
"Vamsas Document");
chooser.setFileView(new JalviewFileView());
{
// check what the actual links are - if it's just the default don't
// bother with the warning
- Vector<String> links = Preferences.sequenceURLLinks;
+ List<String> links = Preferences.sequenceUrlLinks
+ .getLinksForMenu();
// only need to check links if there is one with a
// SEQUENCE_ID which is not the default EMBL_EBI link
while (li.hasNext())
{
String link = li.next();
- if (link.contains(SEQUENCE_ID) && !link.equals(EMBLEBI_STRING))
+ if (link.contains(SEQUENCE_ID)
+ && !link.equals(UrlConstants.DEFAULT_STRING))
{
check = true;
int barPos = link.indexOf("|");
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.schemes.FeatureColour;
-import jalview.schemes.UserColourScheme;
+import jalview.util.ColorUtils;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
FeatureColourI col = getFeatureStyle(name.getText());
if (col == null)
{
- col = new FeatureColour(UserColourScheme
+ col = new FeatureColour(ColorUtils
.createColourFromName(name.getText()));
}
oldcol = fcol = col;
void load()
{
- JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"), "fc",
+ JalviewFileChooser chooser = new JalviewFileChooser("fc",
"Sequence Feature Colours");
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager
void save()
{
- JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"), "fc",
+ JalviewFileChooser chooser = new JalviewFileChooser("fc",
"Sequence Feature Colours");
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager
import jalview.io.SequenceAnnotationReport;
import jalview.util.MessageManager;
import jalview.util.Platform;
-import jalview.util.UrlLink;
import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.List;
-import java.util.Vector;
-import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
return;
}
- Vector links = Preferences.sequenceURLLinks;
- if (links == null || links.size() < 1)
- {
- return;
- }
-
int seq = alignPanel.getSeqPanel().findSeq(e);
- String url = null;
- int i = 0;
String id = av.getAlignment().getSequenceAt(seq).getName();
- while (url == null && i < links.size())
- {
- // DEFAULT LINK IS FIRST IN THE LINK LIST
- // BUT IF ITS A REGEX AND DOES NOT MATCH THE NEXT ONE WILL BE TRIED
- url = links.elementAt(i++).toString();
- jalview.util.UrlLink urlLink = null;
- try
- {
- urlLink = new UrlLink(url);
- } catch (Exception foo)
- {
- jalview.bin.Cache.log.error("Exception for URLLink '" + url + "'",
- foo);
- url = null;
- continue;
- }
+ String url = Preferences.sequenceUrlLinks.getPrimaryUrl(id);
- if (urlLink.usesDBAccession())
- {
- // this URL requires an accession id, not the name of a sequence
- url = null;
- continue;
- }
-
- if (!urlLink.isValid())
- {
- jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
- url = null;
- continue;
- }
-
- String urls[] = urlLink.makeUrls(id, true);
- if (urls == null || urls[0] == null || urls[0].length() < 4)
- {
- url = null;
- continue;
- }
- // just take first URL made from regex
- url = urls[1];
- }
try
{
jalview.util.BrowserLauncher.openURL(url);
Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq2);
// build a new links menu based on the current links + any non-positional
// features
- Vector<String> nlinks = new Vector<String>(Preferences.sequenceURLLinks);
+ List<String> nlinks = Preferences.sequenceUrlLinks.getLinksForMenu();
SequenceFeature sfs[] = sq == null ? null : sq.getSequenceFeatures();
if (sfs != null)
{
{
for (int l = 0, lSize = sf.links.size(); l < lSize; l++)
{
- nlinks.addElement(sf.links.elementAt(l));
+ nlinks.add(sf.links.elementAt(l));
}
}
}
import jalview.gui.StructureViewer.ViewerType;
import jalview.io.DataSourceType;
import jalview.io.FileFormat;
+import jalview.renderer.ResidueShaderI;
import jalview.schemabinding.version2.AlcodMap;
import jalview.schemabinding.version2.AlcodonFrame;
import jalview.schemabinding.version2.Annotation;
// group has references so set its ID field
jGroup.setId(groupRefs.get(sg));
}
- if (sg.cs != null)
+ ColourSchemeI colourScheme = sg.getColourScheme();
+ if (colourScheme != null)
{
- if (sg.cs.conservationApplied())
+ ResidueShaderI groupColourScheme = sg
+ .getGroupColourScheme();
+ if (groupColourScheme.conservationApplied())
{
- jGroup.setConsThreshold(sg.cs.getConservationInc());
+ jGroup.setConsThreshold(groupColourScheme.getConservationInc());
- if (sg.cs instanceof jalview.schemes.UserColourScheme)
+ if (colourScheme instanceof jalview.schemes.UserColourScheme)
{
- jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
+ jGroup.setColour(setUserColourScheme(colourScheme,
+ userColours, jms));
}
else
{
- jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
+ jGroup.setColour(colourScheme.getSchemeName());
}
}
- else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
+ else if (colourScheme instanceof jalview.schemes.AnnotationColourGradient)
{
jGroup.setColour("AnnotationColourGradient");
jGroup.setAnnotationColours(constructAnnotationColours(
- (jalview.schemes.AnnotationColourGradient) sg.cs,
+ (jalview.schemes.AnnotationColourGradient) colourScheme,
userColours, jms));
}
- else if (sg.cs instanceof jalview.schemes.UserColourScheme)
+ else if (colourScheme instanceof jalview.schemes.UserColourScheme)
{
- jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
+ jGroup.setColour(setUserColourScheme(colourScheme,
+ userColours, jms));
}
else
{
- jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
+ jGroup.setColour(colourScheme.getSchemeName());
}
- jGroup.setPidThreshold(sg.cs.getThreshold());
+ jGroup.setPidThreshold(groupColourScheme.getThreshold());
}
jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
.getGlobalColourScheme()));
}
+ ResidueShaderI vcs = av.getResidueShading();
ColourSchemeI cs = av.getGlobalColourScheme();
if (cs != null)
{
- if (cs.conservationApplied())
+ if (vcs.conservationApplied())
{
- view.setConsThreshold(cs.getConservationInc());
+ view.setConsThreshold(vcs.getConservationInc());
if (cs instanceof jalview.schemes.UserColourScheme)
{
view.setBgColour(setUserColourScheme(cs, userColours, jms));
}
}
-
- if (cs instanceof ResidueColourScheme)
- {
- view.setPidThreshold(cs.getThreshold());
- }
+ view.setPidThreshold(vcs.getThreshold());
}
view.setConservationSelected(av.getConservationSelected());
}
else
{
- ac.setColourScheme(ColourSchemeProperty.getColourName(acg
- .getBaseColour()));
+ ac.setColourScheme(ColourSchemeProperty.getColourName(acg.getBaseColour()));
}
ac.setMaxColour(acg.getMaxColour().getRGB());
&& jGroup.getAnnotationColours() != null)
{
addAnnotSchemeGroup = true;
- cs = null;
}
else
{
- cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
- }
-
- if (cs != null)
- {
- cs.setThreshold(jGroup.getPidThreshold(), true);
+ cs = ColourSchemeProperty.getColourScheme(al, jGroup.getColour());
}
}
+ int pidThreshold = jGroup.getPidThreshold();
Vector<SequenceI> seqs = new Vector<SequenceI>();
SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
-
+ sg.getGroupColourScheme().setThreshold(pidThreshold, true);
+ sg.getGroupColourScheme().setConservationInc(jGroup.getConsThreshold());
sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
sg.textColour = new java.awt.Color(jGroup.getTextCol1());
if (addAnnotSchemeGroup)
{
// reconstruct the annotation colourscheme
- sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
- null, al, jms, false);
+ sg.setColourScheme(constructAnnotationColour(
+ jGroup.getAnnotationColours(), null, al, jms, false));
}
}
}
af.viewport.setShowAnnotation(view.getShowAnnotation());
af.viewport.setAbovePIDThreshold(view.getPidSelected());
+ af.viewport.setThreshold(view.getPidThreshold());
af.viewport.setColourText(view.getShowColourText());
af.viewport.setConservationSelected(view.getConservationSelected());
+ af.viewport.setIncrement(view.getConsThreshold());
af.viewport.setShowJVSuffix(view.getShowFullId());
af.viewport.setRightAlignIds(view.getRightAlignIds());
af.viewport.setFont(
}
else
{
- cs = ColourSchemeProperty.getColour(al, view.getBgColour());
- }
-
- if (cs != null)
- {
- cs.setThreshold(view.getPidThreshold(), true);
- cs.setConsensus(af.viewport.getSequenceConsensusHash());
+ cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour());
}
}
af.viewport.setGlobalColourScheme(cs);
+ af.viewport.getResidueShading().setThreshold(
+ view.getPidThreshold(), true);
+ af.viewport.getResidueShading().setConsensus(
+ af.viewport.getSequenceConsensusHash());
af.viewport.setColourAppliesToAllGroups(false);
if (view.getConservationSelected() && cs != null)
{
- cs.setConservationInc(view.getConsThreshold());
+ af.viewport.getResidueShading().setConservationInc(
+ view.getConsThreshold());
}
af.changeColour(cs);
propagateAnnColour = true;
for (jalview.datamodel.SequenceGroup sg : al.getGroups())
{
- if (sg.cs instanceof AnnotationColourGradient)
+ if (sg.getColourScheme() instanceof AnnotationColourGradient)
{
propagateAnnColour = false;
}
);
}
- if (viewAnnColour.getColourScheme().equals("None"))
+ if (viewAnnColour.getColourScheme().equals(
+ ResidueColourScheme.NONE))
{
cs = new AnnotationColourGradient(
annAlignment.getAlignmentAnnotation()[i],
{
cs = new AnnotationColourGradient(
annAlignment.getAlignmentAnnotation()[i],
- ColourSchemeProperty.getColour(al,
+ ColourSchemeProperty.getColourScheme(al,
viewAnnColour.getColourScheme()),
viewAnnColour.getAboveThreshold());
}
}
/*
- * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
+ * if (viewAnnColour.getColourScheme().equals(ResidueColourScheme.NONE)) { sg.cs =
* new AnnotationColourGradient(
* annAlignment.getAlignmentAnnotation()[i], new
* java.awt.Color(viewAnnColour. getMinColour()), new
* viewAnnColour.getAboveThreshold()); } else
*/
{
- sg.cs = new AnnotationColourGradient(
- annAlignment.getAlignmentAnnotation()[i], sg.cs,
- viewAnnColour.getAboveThreshold());
+ sg.setColourScheme(new AnnotationColourGradient(
+ annAlignment.getAlignmentAnnotation()[i], sg
+ .getColourScheme(), viewAnnColour
+ .getAboveThreshold()));
if (cs instanceof AnnotationColourGradient)
{
if (viewAnnColour.hasPerSequence())
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
-import javax.swing.JOptionPane;
-
/**
* DOCUMENT ME!
*
}
else
{
- cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
- }
-
- if (cs != null)
- {
- cs.setThreshold(groups[i].getPidThreshold(), true);
+ cs = ColourSchemeProperty.getColourScheme(al, groups[i].getColour());
}
-
}
+ int pidThreshold = groups[i].getPidThreshold();
Vector seqs = new Vector();
int[] ids = groups[i].getSeq();
seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
groups[i].getDisplayText(), groups[i].getColourText(),
groups[i].getStart(), groups[i].getEnd());
+ sg.getGroupColourScheme().setThreshold(pidThreshold, true);
sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
}
else
{
- cs = ColourSchemeProperty.getColour(al, view.getBgColour());
+ cs = ColourSchemeProperty.getColourScheme(al, view.getBgColour());
}
- if (cs != null)
- {
- cs.setThreshold(view.getPidThreshold(), true);
- cs.setConsensus(af.viewport.getSequenceConsensusHash());
- }
+ // if (cs != null)
+ // {
+ // cs.setThreshold(view.getPidThreshold(), true);
+ // cs.setConsensus(af.viewport.getSequenceConsensusHash());
+ // }
}
- af.viewport.setGlobalColourScheme(cs);
+ af.viewport.getResidueShading().setThreshold(
+ view.getPidThreshold(), true);
+ af.viewport.getResidueShading().setConsensus(
+ af.viewport.getSequenceConsensusHash());
af.viewport.setColourAppliesToAllGroups(false);
af.alignPanel.updateLayout();
af.changeColour(cs);
if (view.getConservationSelected() && cs != null)
{
- cs.setConservationInc(view.getConsThreshold());
+ af.viewport.getResidueShading().setConservationInc(
+ view.getConsThreshold());
}
af.viewport.setColourAppliesToAllGroups(true);
import jalview.io.DataSourceType;
import jalview.structure.StructureSelectionManager;
+import javax.swing.SwingUtilities;
+
public class JalviewChimeraBindingModel extends JalviewChimeraBinding
{
private ChimeraViewFrame cvf;
}
if (!isLoadingFromArchive())
{
- colourBySequence(ap.av.isShowSequenceFeatures(), ap);
+ colourBySequence(ap);
}
}
protected void sendAsynchronousCommand(final String command,
final String progressMsg)
{
- Thread thread = new Thread(new Runnable()
+ final long handle = progressMsg == null ? 0 : cvf
+ .startProgressBar(progressMsg);
+ SwingUtilities.invokeLater(new Runnable()
{
-
@Override
public void run()
{
- long stm = cvf.startProgressBar(progressMsg);
try
{
sendChimeraCommand(command, false);
} finally
{
- cvf.stopProgressBar(null, stm);
+ if (progressMsg != null)
+ {
+ cvf.stopProgressBar(null, handle);
+ }
}
}
});
- thread.start();
-
}
@Override
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JColorChooser;
import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
import javax.swing.JRadioButtonMenuItem;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
/**
* DOCUMENT ME!
*/
public PCAPanel(AlignmentPanel ap)
{
+ super();
this.av = ap.av;
this.ap = ap;
return;
}
+
+ addInternalFrameListener(new InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosed(InternalFrameEvent e)
+ {
+ close_actionPerformed();
+ }
+ });
+
pcaModel = new PCAModel(seqstrings, seqs, nucleotide);
PaintRefresher.Register(this, av.getSequenceSetId());
worker.start();
}
+ /**
+ * Ensure references to potentially very large objects (the PCA matrices) are
+ * nulled when the frame is closed
+ */
+ protected void close_actionPerformed()
+ {
+ pcaModel = null;
+ }
+
@Override
protected void scoreMatrix_menuSelected()
{
public void bgcolour_actionPerformed(ActionEvent e)
{
Color col = JColorChooser.showDialog(this,
- MessageManager.getString("label.select_backgroud_colour"),
+ MessageManager.getString("label.select_background_colour"),
rc.bgColour);
if (col != null)
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.io.FileFormat;
+import jalview.gui.ColourMenuHelper.ColourChangeListener;
import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
import jalview.io.FormatAdapter;
import jalview.io.SequenceAnnotationReport;
import jalview.schemes.AnnotationColourGradient;
import jalview.schemes.Blosum62ColourScheme;
-import jalview.schemes.BuriedColourScheme;
-import jalview.schemes.ClustalxColourScheme;
-import jalview.schemes.HelixColourScheme;
-import jalview.schemes.HydrophobicColourScheme;
-import jalview.schemes.NucleotideColourScheme;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemes;
import jalview.schemes.PIDColourScheme;
-import jalview.schemes.PurinePyrimidineColourScheme;
-import jalview.schemes.StrandColourScheme;
-import jalview.schemes.TaylorColourScheme;
-import jalview.schemes.TurnColourScheme;
-import jalview.schemes.UserColourScheme;
-import jalview.schemes.ZappoColourScheme;
+import jalview.schemes.ResidueColourScheme;
import jalview.util.GroupUrlLink;
import jalview.util.GroupUrlLink.UrlStringTooLongException;
import jalview.util.MessageManager;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Vector;
-import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JColorChooser;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
-import javax.swing.JRadioButtonMenuItem;
/**
* DOCUMENT ME!
* @author $author$
* @version $Revision: 1.118 $
*/
-public class PopupMenu extends JPopupMenu
+public class PopupMenu extends JPopupMenu implements ColourChangeListener
{
JMenu groupMenu = new JMenu();
JMenuItem groupName = new JMenuItem();
- protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem hydrophobicityColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();
-
protected JCheckBoxMenuItem abovePIDColour = new JCheckBoxMenuItem();
- protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem purinePyrimidineColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem RNAInteractionColour = new JRadioButtonMenuItem();
-
- JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem();
+ protected JMenuItem modifyPID = new JMenuItem();
protected JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();
+ protected JMenuItem modifyConservation = new JMenuItem();
+
AlignmentPanel ap;
JMenu sequenceMenu = new JMenu();
JMenuItem outline = new JMenuItem();
- JRadioButtonMenuItem nucleotideMenuItem = new JRadioButtonMenuItem();
-
JMenu colourMenu = new JMenu();
JCheckBoxMenuItem showBoxes = new JCheckBoxMenuItem();
this.ap = ap;
sequence = seq;
- ButtonGroup colours = new ButtonGroup();
- colours.add(noColourmenuItem);
- colours.add(clustalColour);
- colours.add(zappoColour);
- colours.add(taylorColour);
- colours.add(hydrophobicityColour);
- colours.add(helixColour);
- colours.add(strandColour);
- colours.add(turnColour);
- colours.add(buriedColour);
- colours.add(abovePIDColour);
- colours.add(userDefinedColour);
- colours.add(PIDColour);
- colours.add(BLOSUM62Colour);
- colours.add(purinePyrimidineColour);
- colours.add(RNAInteractionColour);
-
- for (String ff : FileFormat.getWritableFormats(true))
+ for (String ff : FileFormats.getInstance().getWritableFormats(true))
{
JMenuItem item = new JMenuItem(ff);
- item.addActionListener(new java.awt.event.ActionListener()
+ item.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
menuItem.setText(MessageManager.formatMessage(
"label.2d_rna_structure_line",
new Object[] { aa.label }));
- menuItem.addActionListener(new java.awt.event.ActionListener()
+ menuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
menuItem.setText(MessageManager.formatMessage(
"label.2d_rna_sequence_name",
new Object[] { seq.getName() }));
- menuItem.addActionListener(new java.awt.event.ActionListener()
+ menuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
menuItem = new JMenuItem(
MessageManager.getString("action.hide_sequences"));
- menuItem.addActionListener(new java.awt.event.ActionListener()
+ menuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
menuItem = new JMenuItem(MessageManager.formatMessage(
"label.represent_group_with",
new Object[] { seq.getName() }));
- menuItem.addActionListener(new java.awt.event.ActionListener()
+ menuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
add(menuItem);
}
-
}
SequenceGroup sg = ap.av.getSelectionGroup();
groupName.setText(MessageManager
.getString("label.edit_name_and_description_current_group"));
- if (sg.cs instanceof ZappoColourScheme)
- {
- zappoColour.setSelected(true);
- }
- else if (sg.cs instanceof TaylorColourScheme)
- {
- taylorColour.setSelected(true);
- }
- else if (sg.cs instanceof PIDColourScheme)
- {
- PIDColour.setSelected(true);
- }
- else if (sg.cs instanceof Blosum62ColourScheme)
- {
- BLOSUM62Colour.setSelected(true);
- }
- else if (sg.cs instanceof UserColourScheme)
- {
- userDefinedColour.setSelected(true);
- }
- else if (sg.cs instanceof HydrophobicColourScheme)
- {
- hydrophobicityColour.setSelected(true);
- }
- else if (sg.cs instanceof HelixColourScheme)
- {
- helixColour.setSelected(true);
- }
- else if (sg.cs instanceof StrandColourScheme)
- {
- strandColour.setSelected(true);
- }
- else if (sg.cs instanceof TurnColourScheme)
- {
- turnColour.setSelected(true);
- }
- else if (sg.cs instanceof BuriedColourScheme)
- {
- buriedColour.setSelected(true);
- }
- else if (sg.cs instanceof ClustalxColourScheme)
- {
- clustalColour.setSelected(true);
- }
- else if (sg.cs instanceof PurinePyrimidineColourScheme)
- {
- purinePyrimidineColour.setSelected(true);
- }
+ ColourMenuHelper.setColourSelected(colourMenu, sg.getColourScheme());
- /*
- * else if (sg.cs instanceof CovariationColourScheme) {
- * covariationColour.setSelected(true); }
- */
- else
- {
- noColourmenuItem.setSelected(true);
- }
+ conservationMenuItem.setEnabled(!sg.isNucleotide());
- if (sg.cs != null && sg.cs.conservationApplied())
+ if (sg.cs != null)
{
- conservationMenuItem.setSelected(true);
+ if (sg.cs.conservationApplied())
+ {
+ conservationMenuItem.setSelected(true);
+ }
+ if (sg.cs.getThreshold() > 0)
+ {
+ abovePIDColour.setSelected(true);
+ }
}
+ modifyConservation.setEnabled(conservationMenuItem.isSelected());
+ modifyPID.setEnabled(abovePIDColour.isSelected());
displayNonconserved.setSelected(sg.getShowNonconserved());
showText.setSelected(sg.getDisplayText());
showColourText.setSelected(sg.getColourText());
}
-
-
/**
* Add annotation types to 'Show annotations' and/or 'Hide annotations' menus.
* "All" is added first, followed by a separator. Then add any annotation
label = label.substring(1, label.length() - 1); // a, b, c
final JMenuItem item = new JMenuItem(label);
item.setToolTipText(calcId);
- item.addActionListener(new java.awt.event.ActionListener()
+ item.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
JMenuItem item = new JMenuItem(label);
item.setToolTipText(MessageManager.formatMessage(
"label.open_url_param", new Object[] { url }));
- item.addActionListener(new java.awt.event.ActionListener()
+ item.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
groupMenu.setText(MessageManager.getString("label.selection"));
groupName.setText(MessageManager.getString("label.name"));
- groupName.addActionListener(new java.awt.event.ActionListener()
+ groupName.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
sequenceMenu.setText(MessageManager.getString("label.sequence"));
sequenceName.setText(MessageManager
.getString("label.edit_name_description"));
- sequenceName.addActionListener(new java.awt.event.ActionListener()
+ sequenceName.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
chooseAnnotations.setText(MessageManager
.getString("action.choose_annotations"));
- chooseAnnotations.addActionListener(new java.awt.event.ActionListener()
+ chooseAnnotations.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
sequenceDetails.setText(MessageManager
.getString("label.sequence_details"));
- sequenceDetails.addActionListener(new java.awt.event.ActionListener()
+ sequenceDetails.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
sequenceSelDetails.setText(MessageManager
.getString("label.sequence_details"));
- sequenceSelDetails
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- sequenceSelectionDetails_actionPerformed();
- }
- });
- PIDColour.setFocusPainted(false);
+ sequenceSelDetails.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ sequenceSelectionDetails_actionPerformed();
+ }
+ });
+
unGroupMenuItem
.setText(MessageManager.getString("action.remove_group"));
- unGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
+ unGroupMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
});
createGroupMenuItem.setText(MessageManager
.getString("action.create_group"));
- createGroupMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- createGroupMenuItem_actionPerformed();
- }
- });
-
- outline.setText(MessageManager.getString("action.border_colour"));
- outline.addActionListener(new java.awt.event.ActionListener()
+ createGroupMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- outline_actionPerformed();
+ createGroupMenuItem_actionPerformed();
}
});
- nucleotideMenuItem
- .setText(MessageManager.getString("label.nucleotide"));
- nucleotideMenuItem.addActionListener(new ActionListener()
+
+ outline.setText(MessageManager.getString("action.border_colour"));
+ outline.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- nucleotideMenuItem_actionPerformed();
+ outline_actionPerformed();
}
});
- colourMenu.setText(MessageManager.getString("label.group_colour"));
showBoxes.setText(MessageManager.getString("action.boxes"));
showBoxes.setState(true);
showBoxes.addActionListener(new ActionListener()
}
});
displayNonconserved.setText(MessageManager
- .getString("label.show_non_conversed"));
+ .getString("label.show_non_conserved"));
displayNonconserved.setState(true);
displayNonconserved.addActionListener(new ActionListener()
{
sequenceFeature_actionPerformed();
}
});
- textColour.setText(MessageManager.getString("label.text_colour"));
- textColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- textColour_actionPerformed();
- }
- });
jMenu1.setText(MessageManager.getString("label.group"));
pdbStructureDialog.setText(MessageManager
.getString("label.show_pdbstruct_dialog"));
sequenceMenu.add(sequenceName);
sequenceMenu.add(sequenceDetails);
sequenceMenu.add(makeReferenceSeq);
- colourMenu.add(textColour);
- colourMenu.add(noColourmenuItem);
- colourMenu.add(clustalColour);
- colourMenu.add(BLOSUM62Colour);
- colourMenu.add(PIDColour);
- colourMenu.add(zappoColour);
- colourMenu.add(taylorColour);
- colourMenu.add(hydrophobicityColour);
- colourMenu.add(helixColour);
- colourMenu.add(strandColour);
- colourMenu.add(turnColour);
- colourMenu.add(buriedColour);
- colourMenu.add(nucleotideMenuItem);
- if (ap.getAlignment().isNucleotide())
- {
- // JBPNote - commented since the colourscheme isn't functional
- colourMenu.add(purinePyrimidineColour);
- }
- colourMenu.add(userDefinedColour);
-
- if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
- {
- java.util.Enumeration userColours = jalview.gui.UserDefinedColours
- .getUserColourSchemes().keys();
- while (userColours.hasMoreElements())
- {
- JMenuItem item = new JMenuItem(userColours.nextElement().toString());
- item.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- userDefinedColour_actionPerformed(evt);
- }
- });
- colourMenu.add(item);
- }
- }
+ initColourMenu();
+ buildColourMenu();
- colourMenu.addSeparator();
- colourMenu.add(abovePIDColour);
- colourMenu.add(conservationMenuItem);
editMenu.add(copy);
editMenu.add(cut);
editMenu.add(editSequence);
jMenu1.add(showColourText);
jMenu1.add(outline);
jMenu1.add(displayNonconserved);
- noColourmenuItem.setText(MessageManager.getString("label.none"));
- noColourmenuItem.addActionListener(new java.awt.event.ActionListener()
+ }
+
+ /**
+ * Constructs the entries for the colour menu
+ */
+ protected void initColourMenu()
+ {
+ colourMenu.setText(MessageManager.getString("label.group_colour"));
+ textColour.setText(MessageManager.getString("label.text_colour"));
+ textColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- noColourmenuItem_actionPerformed();
+ textColour_actionPerformed();
}
});
- clustalColour.setText(MessageManager
- .getString("label.clustalx_colours"));
- clustalColour.addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- clustalColour_actionPerformed();
- }
- });
- zappoColour.setText(MessageManager.getString("label.zappo"));
- zappoColour.addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- zappoColour_actionPerformed();
- }
- });
- taylorColour.setText(MessageManager.getString("label.taylor"));
- taylorColour.addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- taylorColour_actionPerformed();
- }
- });
- hydrophobicityColour.setText(MessageManager
- .getString("label.hydrophobicity"));
- hydrophobicityColour
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- hydrophobicityColour_actionPerformed();
- }
- });
- helixColour.setText(MessageManager.getString("label.helix_propensity"));
- helixColour.addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- helixColour_actionPerformed();
- }
- });
- strandColour.setText(MessageManager
- .getString("label.strand_propensity"));
- strandColour.addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- strandColour_actionPerformed();
- }
- });
- turnColour.setText(MessageManager.getString("label.turn_propensity"));
- turnColour.addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- turnColour_actionPerformed();
- }
- });
- buriedColour.setText(MessageManager.getString("label.buried_index"));
- buriedColour.addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- buriedColour_actionPerformed();
- }
- });
abovePIDColour.setText(MessageManager
- .getString("label.above_identity_percentage"));
- abovePIDColour.addActionListener(new java.awt.event.ActionListener()
+ .getString("label.above_identity_threshold"));
+ abovePIDColour.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- abovePIDColour_actionPerformed();
+ abovePIDColour_actionPerformed(abovePIDColour.isSelected());
}
});
- userDefinedColour.setText(MessageManager
- .getString("action.user_defined"));
- userDefinedColour.addActionListener(new java.awt.event.ActionListener()
+
+ modifyPID.setText(MessageManager
+ .getString("label.modify_identity_threshold"));
+ modifyPID.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- userDefinedColour_actionPerformed(e);
+ modifyPID_actionPerformed();
}
});
- PIDColour
- .setText(MessageManager.getString("label.percentage_identity"));
- PIDColour.addActionListener(new java.awt.event.ActionListener()
+
+ conservationMenuItem.setText(MessageManager
+ .getString("action.by_conservation"));
+ conservationMenuItem.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- PIDColour_actionPerformed();
+ conservationMenuItem_actionPerformed(conservationMenuItem
+ .isSelected());
}
});
- BLOSUM62Colour.setText(MessageManager.getString("label.blosum62"));
- BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()
+
+ modifyConservation.setText(MessageManager
+ .getString("label.modify_conservation_threshold"));
+ modifyConservation.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- BLOSUM62Colour_actionPerformed();
+ modifyConservation_actionPerformed();
}
});
- purinePyrimidineColour.setText(MessageManager
- .getString("label.purine_pyrimidine"));
- purinePyrimidineColour
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- purinePyrimidineColour_actionPerformed();
- }
- });
+ }
- /*
- * covariationColour.addActionListener(new java.awt.event.ActionListener() {
- * public void actionPerformed(ActionEvent e) {
- * covariationColour_actionPerformed(); } });
- */
+ /**
+ * Builds the group colour sub-menu, including any user-defined colours which
+ * were loaded at startup or during the Jalview session
+ */
+ protected void buildColourMenu()
+ {
+ SequenceGroup sg = ap.av.getSelectionGroup();
+ if (sg == null)
+ {
+ /*
+ * popup menu with no sequence group scope
+ */
+ return;
+ }
+ colourMenu.removeAll();
+ colourMenu.add(textColour);
+ colourMenu.addSeparator();
- conservationMenuItem.setText(MessageManager
- .getString("label.conservation"));
- conservationMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- conservationMenuItem_actionPerformed();
- }
- });
+ ColourMenuHelper.addMenuItems(colourMenu, this, sg, false);
+
+ colourMenu.addSeparator();
+ colourMenu.add(conservationMenuItem);
+ colourMenu.add(modifyConservation);
+ colourMenu.add(abovePIDColour);
+ colourMenu.add(modifyPID);
+ }
+
+ protected void modifyConservation_actionPerformed()
+ {
+ SequenceGroup sg = getGroup();
+ if (sg.cs != null)
+ {
+ SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
+ SliderPanel.showConservationSlider();
+ }
+ }
+
+ protected void modifyPID_actionPerformed()
+ {
+ SequenceGroup sg = getGroup();
+ if (sg.cs != null)
+ {
+ // int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup()
+ // .getName());
+ // sg.cs.setThreshold(threshold, ap.av.isIgnoreGapsConsensus());
+ SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup()
+ .getName());
+ SliderPanel.showPIDSlider();
+ }
}
/**
* Temporary store to hold distinct calcId / type pairs for the tooltip.
* Using TreeMap means calcIds are shown in alphabetical order.
*/
- Map<String, String> tipEntries = new TreeMap<String, String>();
+ SortedMap<String, String> tipEntries = new TreeMap<String, String>();
final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<SequenceI, List<AlignmentAnnotation>>();
AlignmentI al = this.ap.av.getAlignment();
AlignmentUtils.findAddableReferenceAnnotations(forSequences,
PaintRefresher.Refresh(this, ap.av.getSequenceSetId());
}
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void clustalColour_actionPerformed()
- {
- SequenceGroup sg = getGroup();
- sg.cs = new ClustalxColourScheme(sg, ap.av.getHiddenRepSequences());
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void zappoColour_actionPerformed()
- {
- getGroup().cs = new ZappoColourScheme();
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void taylorColour_actionPerformed()
- {
- getGroup().cs = new TaylorColourScheme();
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void hydrophobicityColour_actionPerformed()
- {
- getGroup().cs = new HydrophobicColourScheme();
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void helixColour_actionPerformed()
- {
- getGroup().cs = new HelixColourScheme();
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void strandColour_actionPerformed()
- {
- getGroup().cs = new StrandColourScheme();
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void turnColour_actionPerformed()
- {
- getGroup().cs = new TurnColourScheme();
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void buriedColour_actionPerformed()
- {
- getGroup().cs = new BuriedColourScheme();
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- public void nucleotideMenuItem_actionPerformed()
- {
- getGroup().cs = new NucleotideColourScheme();
- refresh();
- }
-
- protected void purinePyrimidineColour_actionPerformed()
- {
- getGroup().cs = new PurinePyrimidineColourScheme();
- refresh();
- }
-
/*
* protected void covariationColour_actionPerformed() { getGroup().cs = new
* CovariationColourScheme(sequence.getAnnotation()[0]); refresh(); }
/**
* DOCUMENT ME!
*
+ * @param selected
+ *
* @param e
* DOCUMENT ME!
*/
- protected void abovePIDColour_actionPerformed()
+ public void abovePIDColour_actionPerformed(boolean selected)
{
SequenceGroup sg = getGroup();
if (sg.cs == null)
return;
}
- if (abovePIDColour.isSelected())
+ if (selected)
{
sg.cs.setConsensus(AAFrequency.calculate(
sg.getSequences(ap.av.getHiddenRepSequences()),
sg.getStartRes(), sg.getEndRes() + 1));
- int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup()
+ int threshold = SliderPanel.setPIDSliderSource(ap,
+ sg.getGroupColourScheme(), getGroup()
.getName());
sg.cs.setThreshold(threshold, ap.av.isIgnoreGapsConsensus());
// remove PIDColouring
{
sg.cs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
+ SliderPanel.hidePIDSlider();
}
+ modifyPID.setEnabled(selected);
refresh();
}
/**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void userDefinedColour_actionPerformed(ActionEvent e)
- {
- SequenceGroup sg = getGroup();
-
- if (e.getSource().equals(userDefinedColour))
- {
- new UserDefinedColours(ap, sg);
- }
- else
- {
- UserColourScheme udc = (UserColourScheme) UserDefinedColours
- .getUserColourSchemes().get(e.getActionCommand());
-
- sg.cs = udc;
- }
- refresh();
- }
-
- /**
* Open a panel where the user can choose which types of sequence annotation
* to show or hide.
*
* @param e
* DOCUMENT ME!
*/
- protected void PIDColour_actionPerformed()
- {
- SequenceGroup sg = getGroup();
- sg.cs = new PIDColourScheme();
- sg.cs.setConsensus(AAFrequency.calculate(
- sg.getSequences(ap.av.getHiddenRepSequences()),
- sg.getStartRes(), sg.getEndRes() + 1));
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void BLOSUM62Colour_actionPerformed()
- {
- SequenceGroup sg = getGroup();
-
- sg.cs = new Blosum62ColourScheme();
-
- sg.cs.setConsensus(AAFrequency.calculate(
- sg.getSequences(ap.av.getHiddenRepSequences()),
- sg.getStartRes(), sg.getEndRes() + 1));
-
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void noColourmenuItem_actionPerformed()
- {
- getGroup().cs = null;
- refresh();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- protected void conservationMenuItem_actionPerformed()
+ public void conservationMenuItem_actionPerformed(boolean selected)
{
SequenceGroup sg = getGroup();
if (sg.cs == null)
return;
}
- if (conservationMenuItem.isSelected())
+ if (selected)
{
// JBPNote: Conservation name shouldn't be i18n translated
Conservation c = new Conservation("Group", sg.getSequences(ap.av
c.calculate();
c.verdict(false, ap.av.getConsPercGaps());
-
sg.cs.setConservation(c);
- SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
+ SliderPanel.setConservationSlider(ap, sg.getGroupColourScheme(),
+ sg.getName());
SliderPanel.showConservationSlider();
}
else
// remove ConservationColouring
{
sg.cs.setConservation(null);
+ SliderPanel.hideConservationSlider();
}
+ modifyConservation.setEnabled(selected);
refresh();
}
AnnotationColourGradient.NO_THRESHOLD);
acg.setPredefinedColours(true);
- sg.cs = acg;
+ sg.setColourScheme(acg);
refresh();
}
// or we simply trust the user wants
// wysiwig behaviour
- FileFormatI fileFormat = FileFormat.forName(e.getActionCommand());
+ FileFormatI fileFormat = FileFormats.getInstance().forName(e.getActionCommand());
cap.setText(new FormatAdapter(ap).formatSequences(fileFormat, ap, true));
}
}
}
+ /**
+ * Action on user selecting an item from the colour menu (that does not have
+ * its bespoke action handler)
+ *
+ * @return
+ */
+ @Override
+ public void changeColour_actionPerformed(String colourSchemeName)
+ {
+ SequenceGroup sg = getGroup();
+ if (ResidueColourScheme.USER_DEFINED.equals(colourSchemeName))
+ {
+ /*
+ * open a panel to load or configure a user-defined colour scheme
+ */
+ new UserDefinedColours(ap, sg);
+ }
+ else
+ {
+ /*
+ * switch to the chosen colour scheme (or null for None)
+ */
+ ColourSchemeI colourScheme = ColourSchemes.getInstance().getColourScheme(
+ colourSchemeName, sg, ap.av.getHiddenRepSequences());
+ sg.setColourScheme(colourScheme);
+ if (colourScheme instanceof Blosum62ColourScheme
+ || colourScheme instanceof PIDColourScheme)
+ {
+ sg.cs.setConsensus(AAFrequency.calculate(
+ sg.getSequences(ap.av.getHiddenRepSequences()),
+ sg.getStartRes(), sg.getEndRes() + 1));
+ }
+ }
+
+ refresh();
+ }
+
}
*/
package jalview.gui;
-import static jalview.util.UrlConstants.DB_ACCESSION;
-import static jalview.util.UrlConstants.EMBLEBI_STRING;
-import static jalview.util.UrlConstants.SEQUENCE_ID;
-import static jalview.util.UrlConstants.SRS_STRING;
-
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.bin.Cache;
import jalview.gui.Help.HelpId;
import jalview.io.JalviewFileView;
import jalview.jbgui.GPreferences;
import jalview.jbgui.GSequenceLink;
-import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemes;
+import jalview.schemes.ResidueColourScheme;
+import jalview.urls.UrlLinkTableModel;
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.desktop.DesktopUrlProviderFactory;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import jalview.util.UrlConstants;
import jalview.ws.sifts.SiftsSettings;
import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
-import java.util.StringTokenizer;
-import java.util.Vector;
import javax.help.HelpSetException;
import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
+import javax.swing.ListSelectionModel;
+import javax.swing.RowFilter;
+import javax.swing.RowSorter;
+import javax.swing.SortOrder;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
* Holds name and link separated with | character. Sequence ID must be
* $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
*/
- public static Vector<String> sequenceURLLinks;
+ public static UrlProviderI sequenceUrlLinks;
+
+ public static UrlLinkTableModel dataModel;
/**
* Holds name and link separated with | character. Sequence IDS and Sequences
public static List<String> groupURLLinks;
static
{
- String string = Cache.getDefault("SEQUENCE_LINKS", EMBLEBI_STRING);
- sequenceURLLinks = new Vector<String>();
-
- try
+ // get links selected to be in the menu (SEQUENCE_LINKS)
+ // and links entered by the user but not selected (STORED_LINKS)
+ String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
+ String notInMenuString = Cache.getDefault("STORED_LINKS", "");
+ String defaultUrl = Cache.getDefault("DEFAULT_URL",
+ UrlConstants.DEFAULT_LABEL);
+
+ // if both links lists are empty, add the DEFAULT_URL link
+ // otherwise we assume the default link is in one of the lists
+ if (inMenuString.isEmpty() && notInMenuString.isEmpty())
{
- StringTokenizer st = new StringTokenizer(string, "|");
- while (st.hasMoreElements())
- {
- String name = st.nextToken();
- String url = st.nextToken();
- // check for '|' within a regex
- int rxstart = url.indexOf("$" + DB_ACCESSION + "$");
- if (rxstart == -1)
- {
- rxstart = url.indexOf("$" + SEQUENCE_ID + "$");
- }
- while (rxstart == -1 && url.indexOf("/=$") == -1)
- {
- url = url + "|" + st.nextToken();
- }
- sequenceURLLinks.addElement(name + "|" + url);
- }
- } catch (Exception ex)
- {
- System.out.println(ex + "\nError parsing sequence links");
- }
- {
- // upgrade old SRS link
- int srsPos = sequenceURLLinks.indexOf(SRS_STRING);
- if (srsPos > -1)
- {
- sequenceURLLinks.setElementAt(EMBLEBI_STRING, srsPos);
- }
+ inMenuString = UrlConstants.DEFAULT_STRING;
}
+ UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
+ inMenuString, notInMenuString);
+ sequenceUrlLinks = factory.createUrlProvider();
+ dataModel = new UrlLinkTableModel(sequenceUrlLinks);
/**
* TODO: reformulate groupURL encoding so two or more can be stored in the
groupURLLinks = new ArrayList<String>();
}
- Vector<String> nameLinks, urlLinks;
-
JInternalFrame frame;
DasSourceBrowser dasSource;
/*
* Set Colours tab defaults
*/
- for (int i = ColourSchemeProperty.FIRST_COLOUR; i <= ColourSchemeProperty.LAST_COLOUR; i++)
+ protColour.addItem(ResidueColourScheme.NONE);
+ nucColour.addItem(ResidueColourScheme.NONE);
+ for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
{
- protColour.addItem(ColourSchemeProperty.getColourName(i));
- nucColour.addItem(ColourSchemeProperty.getColourName(i));
+ String name = cs.getSchemeName();
+ protColour.addItem(name);
+ nucColour.addItem(name);
}
- String oldProp = Cache.getDefault(DEFAULT_COLOUR, "None");
+ String oldProp = Cache.getDefault(DEFAULT_COLOUR,
+ ResidueColourScheme.NONE);
String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
protColour.setSelectedItem(newProp != null ? newProp : oldProp);
newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
/*
* Set Connections tab defaults
*/
- nameLinks = new Vector<String>();
- urlLinks = new Vector<String>();
- for (int i = 0; i < sequenceURLLinks.size(); i++)
+
+ // set up sorting
+ linkUrlTable.setModel(dataModel);
+ final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
+ linkUrlTable.getModel());
+ linkUrlTable.setRowSorter(sorter);
+ List<RowSorter.SortKey> sortKeys = new ArrayList<>();
+
+ UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
+ sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
+ SortOrder.DESCENDING));
+ sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
+ SortOrder.DESCENDING));
+ sortKeys.add(new RowSorter.SortKey(m.getNameColumn(),
+ SortOrder.ASCENDING));
+
+ sorter.setSortKeys(sortKeys);
+ sorter.sort();
+
+ // set up filtering
+ ActionListener onReset;
+ onReset = new ActionListener()
{
- String link = sequenceURLLinks.elementAt(i).toString();
- nameLinks.addElement(link.substring(0, link.indexOf("|")));
- urlLinks.addElement(link.substring(link.indexOf("|") + 1));
- }
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ filterTB.setText("");
+ sorter.setRowFilter(RowFilter.regexFilter(""));
+ }
+
+ };
+ doReset.addActionListener(onReset);
+
+ // filter to display only custom urls
+ final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
+ {
+ @Override
+ public boolean include(
+ Entry<? extends TableModel, ? extends Object> entry)
+ {
+ return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
+ }
+ };
+
+ final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
+ linkUrlTable.getModel());
+ customSorter.setRowFilter(customUrlFilter);
+
+ ActionListener onCustomOnly;
+ onCustomOnly = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ filterTB.setText("");
+ sorter.setRowFilter(customUrlFilter);
+ }
+ };
+ userOnly.addActionListener(onCustomOnly);
+
+ filterTB.getDocument().addDocumentListener(new DocumentListener()
+ {
+ String caseInsensitiveFlag = "(?i)";
- updateLinkData();
+ @Override
+ public void changedUpdate(DocumentEvent e)
+ {
+ sorter.setRowFilter(RowFilter.regexFilter(caseInsensitiveFlag
+ + filterTB.getText()));
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e)
+ {
+ sorter.setRowFilter(RowFilter.regexFilter(caseInsensitiveFlag
+ + filterTB.getText()));
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e)
+ {
+ sorter.setRowFilter(RowFilter.regexFilter(caseInsensitiveFlag
+ + filterTB.getText()));
+ }
+ });
+
+ // set up list selection functionality
+ linkUrlTable.getSelectionModel().addListSelectionListener(
+ new UrlListSelectionHandler());
+
+ // set up radio buttons
+ int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
+ .getPrimaryColumn();
+ String onClickName = linkUrlTable.getColumnName(onClickCol);
+ linkUrlTable.getColumn(onClickName).setCellRenderer(
+ new RadioButtonRenderer());
+ linkUrlTable.getColumn(onClickName)
+ .setCellEditor(new RadioButtonEditor());
+
+ // get boolean columns and resize those to min possible
+ for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
+ {
+ if (linkUrlTable.getModel().getColumnClass(column)
+ .equals(Boolean.class))
+ {
+ TableColumn tableColumn = linkUrlTable.getColumnModel().getColumn(
+ column);
+ int preferredWidth = tableColumn.getMinWidth();
+
+ TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
+ column);
+ Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
+ int cwidth = c.getPreferredSize().width
+ + linkUrlTable.getIntercellSpacing().width;
+ preferredWidth = Math.max(preferredWidth, cwidth);
+
+ tableColumn.setPreferredWidth(preferredWidth);
+ }
+ }
useProxy.setSelected(Cache.getDefault("USE_PROXY", false));
- proxyServerTB.setEnabled(useProxy.isSelected());
- proxyPortTB.setEnabled(useProxy.isSelected());
+ useProxy_actionPerformed(); // make sure useProxy is correctly initialised
proxyServerTB.setText(Cache.getDefault("PROXY_SERVER", ""));
proxyPortTB.setText(Cache.getDefault("PROXY_PORT", ""));
jalview.util.BrowserLauncher.resetBrowser();
- if (nameLinks.size() > 0)
+ // save user-defined and selected links
+ String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
+ if (menuLinks.isEmpty())
+ {
+ Cache.applicationProperties.remove("SEQUENCE_LINKS");
+ }
+ else
{
- StringBuffer links = new StringBuffer();
- sequenceURLLinks = new Vector<String>();
- for (int i = 0; i < nameLinks.size(); i++)
- {
- sequenceURLLinks.addElement(nameLinks.elementAt(i) + "|"
- + urlLinks.elementAt(i));
- links.append(sequenceURLLinks.elementAt(i).toString());
- links.append("|");
- }
- // remove last "|"
- links.setLength(links.length() - 1);
Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
- links.toString());
+ menuLinks.toString());
+ }
+
+ String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
+ if (nonMenuLinks.isEmpty())
+ {
+ Cache.applicationProperties.remove("STORED_LINKS");
}
else
{
- Cache.applicationProperties.remove("SEQUENCE_LINKS");
- sequenceURLLinks.clear();
+ Cache.applicationProperties.setProperty("STORED_LINKS",
+ nonMenuLinks.toString());
}
+ Cache.applicationProperties.setProperty("DEFAULT_URL",
+ sequenceUrlLinks.getPrimaryUrlId());
+
Cache.applicationProperties.setProperty("USE_PROXY",
Boolean.toString(useProxy.isSelected()));
if (format != null)
{
Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
- format.toString());
+ format.getName());
}
startupFileTextfield.setText(chooser.getSelectedFile()
.getAbsolutePath());
@Override
public void newLink_actionPerformed(ActionEvent e)
{
-
GSequenceLink link = new GSequenceLink();
boolean valid = false;
while (!valid)
{
if (link.checkValid())
{
- nameLinks.addElement(link.getName());
- urlLinks.addElement(link.getURL());
- updateLinkData();
- valid = true;
+ if (((UrlLinkTableModel) linkUrlTable.getModel())
+ .isUniqueName(link.getName()))
+ {
+ ((UrlLinkTableModel) linkUrlTable.getModel()).insertRow(
+ link.getName(), link.getURL());
+ valid = true;
+ }
+ else
+ {
+ link.notifyDuplicate();
+ continue;
+ }
}
}
else
{
GSequenceLink link = new GSequenceLink();
- int index = linkNameList.getSelectedIndex();
+ int index = linkUrlTable.getSelectedRow();
if (index == -1)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
- MessageManager.getString("label.no_link_selected"),
- MessageManager.getString("label.no_link_selected"),
- JvOptionPane.WARNING_MESSAGE);
+ // button no longer enabled if row is not selected
+ Cache.log.debug("Edit with no row selected in linkUrlTable");
return;
}
- link.setName(nameLinks.elementAt(index).toString());
- link.setURL(urlLinks.elementAt(index).toString());
+ int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
+ .getNameColumn();
+ int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
+ .getUrlColumn();
+ String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
+ link.setName(oldName);
+ link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
boolean valid = false;
while (!valid)
{
-
if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
- MessageManager.getString("label.new_sequence_url_link"),
+ MessageManager.getString("label.edit_sequence_url_link"),
JvOptionPane.OK_CANCEL_OPTION, -1, null) == JvOptionPane.OK_OPTION)
{
if (link.checkValid())
{
- nameLinks.setElementAt(link.getName(), index);
- urlLinks.setElementAt(link.getURL(), index);
- updateLinkData();
- valid = true;
+ if ((oldName.equals(link.getName()))
+ || (((UrlLinkTableModel) linkUrlTable.getModel())
+ .isUniqueName(link.getName())))
+ {
+ linkUrlTable.setValueAt(link.getName(), index, nameCol);
+ linkUrlTable.setValueAt(link.getURL(), index, urlCol);
+ valid = true;
+ }
+ else
+ {
+ link.notifyDuplicate();
+ continue;
+ }
}
}
-
else
{
break;
@Override
public void deleteLink_actionPerformed(ActionEvent e)
{
- int index = linkNameList.getSelectedIndex();
+ int index = linkUrlTable.getSelectedRow();
+ int modelIndex = -1;
if (index == -1)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
- MessageManager.getString("label.no_link_selected"),
- MessageManager.getString("label.no_link_selected"),
- JvOptionPane.WARNING_MESSAGE);
+ // button no longer enabled if row is not selected
+ Cache.log.debug("Delete with no row selected in linkUrlTable");
return;
}
- nameLinks.removeElementAt(index);
- urlLinks.removeElementAt(index);
- updateLinkData();
- }
+ else
+ {
+ modelIndex = linkUrlTable.convertRowIndexToModel(index);
+ }
- void updateLinkData()
- {
- linkNameList.setListData(nameLinks);
- linkURLList.setListData(urlLinks);
+ // make sure we use the model index to delete, and not the table index
+ ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
}
+
@Override
public void defaultBrowser_mouseClicked(MouseEvent e)
{
return name.hashCode() + code.hashCode();
}
}
+
+ private class UrlListSelectionHandler implements ListSelectionListener
+ {
+
+ @Override
+ public void valueChanged(ListSelectionEvent e)
+ {
+ ListSelectionModel lsm = (ListSelectionModel) e.getSource();
+
+ int index = lsm.getMinSelectionIndex();
+ if (index == -1)
+ {
+ // no selection, so disable delete/edit buttons
+ editLink.setEnabled(false);
+ deleteLink.setEnabled(false);
+ return;
+ }
+ int modelIndex = linkUrlTable.convertRowIndexToModel(index);
+
+ // enable/disable edit and delete link buttons
+ if (((UrlLinkTableModel) linkUrlTable.getModel())
+ .isRowDeletable(modelIndex))
+ {
+ deleteLink.setEnabled(true);
+ }
+ else
+ {
+ deleteLink.setEnabled(false);
+ }
+
+ if (((UrlLinkTableModel) linkUrlTable.getModel())
+ .isRowEditable(modelIndex))
+ {
+ editLink.setEnabled(true);
+ }
+ else
+ {
+ editLink.setEnabled(false);
+ }
+ }
+}
}
slider.addChangeListener(new ChangeListener()
{
+ @Override
public void stateChanged(ChangeEvent evt)
{
valueField.setText(slider.getValue() + "");
false);
frame.addInternalFrameListener(new InternalFrameAdapter()
{
+ @Override
public void internalFrameClosing(InternalFrameEvent evt)
{
ap.getIdPanel().getIdCanvas().setHighlighted(null);
*
* @return DOCUMENT ME!
*/
+ @Override
public void run()
{
JProgressBar progress = new JProgressBar();
* @param e
* DOCUMENT ME!
*/
+ @Override
public void applyButton_actionPerformed(ActionEvent e)
{
Vector del = new Vector();
* @param e
* DOCUMENT ME!
*/
+ @Override
public void undoButton_actionPerformed(ActionEvent e)
{
if (historyList == null || historyList.isEmpty())
}
}
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
- public void valueField_actionPerformed(ActionEvent e)
- {
- try
- {
- int i = Integer.parseInt(valueField.getText());
- slider.setValue(i);
- } catch (Exception ex)
- {
- valueField.setText(slider.getValue() + "");
- }
- }
-
}
}
/**
- * DOCUMENT ME!
+ * Action on dragging the mouse in the scale panel is to expand or shrink the
+ * selection group range (including any hidden columns that it spans)
*
* @param evt
- * DOCUMENT ME!
*/
@Override
public void mouseDragged(MouseEvent evt)
{
mouseDragging = true;
+ ColumnSelection cs = av.getColumnSelection();
int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
- if (res < 0)
- {
- res = 0;
- }
-
- if (av.hasHiddenColumns())
- {
- res = av.getColumnSelection().adjustForHiddenColumns(res);
- }
-
- if (res >= av.getAlignment().getWidth())
- {
- res = av.getAlignment().getWidth() - 1;
- }
-
- if (res < min)
- {
- min = res;
- }
-
- if (res > max)
- {
- max = res;
- }
+ res = Math.max(0, res);
+ res = cs.adjustForHiddenColumns(res);
+ res = Math.min(res, av.getAlignment().getWidth() - 1);
+ min = Math.min(res, min);
+ max = Math.max(res, max);
SequenceGroup sg = av.getSelectionGroup();
-
if (sg != null)
{
stretchingGroup = true;
-
- if (!av.getColumnSelection().contains(res))
- {
- av.getColumnSelection().addElement(res);
- }
-
- if (res > sg.getStartRes())
- {
- sg.setEndRes(res);
- }
- if (res < sg.getStartRes())
- {
- sg.setStartRes(res);
- }
-
- int col;
- for (int i = min; i <= max; i++)
- {
- col = i; // av.getColumnSelection().adjustForHiddenColumns(i);
-
- if ((col < sg.getStartRes()) || (col > sg.getEndRes()))
- {
- av.getColumnSelection().removeElement(col);
- }
- else
- {
- av.getColumnSelection().addElement(col);
- }
- }
-
+ cs.stretchGroup(res, sg, min, max);
ap.paintAlignment(false);
}
}
{
}
+ /**
+ * Creates a tooltip when the mouse is over a hidden columns marker
+ */
@Override
public void mouseMoved(MouseEvent evt)
{
ToolTipManager.sharedInstance().registerComponent(this);
this.setToolTipText(MessageManager
.getString("label.reveal_hidden_columns"));
- break;
+ repaint();
+ return;
}
}
}
- repaint();
}
/**
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.io.SequenceAnnotationReport;
+import jalview.renderer.ResidueShaderI;
import jalview.schemes.ResidueProperties;
import jalview.structure.SelectionListener;
import jalview.structure.SelectionSource;
import java.util.ArrayList;
import java.util.List;
-import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
stretchGroup = av.getSelectionGroup();
- if (stretchGroup == null)
+ if (stretchGroup == null || !stretchGroup.contains(sequence, res))
{
- stretchGroup = av.getAlignment().findGroup(sequence);
-
- if ((stretchGroup != null) && (res > stretchGroup.getStartRes())
- && (res < stretchGroup.getEndRes()))
+ stretchGroup = av.getAlignment().findGroup(sequence, res);
+ if (stretchGroup != null)
{
+ // only update the current selection if the popup menu has a group to
+ // focus on
av.setSelectionGroup(stretchGroup);
}
- else
- {
- stretchGroup = null;
- }
- }
- else if (!stretchGroup.getSequences(null).contains(sequence)
- || (stretchGroup.getStartRes() > res)
- || (stretchGroup.getEndRes() < res))
- {
- stretchGroup = null;
-
- SequenceGroup[] allGroups = av.getAlignment().findAllGroups(sequence);
-
- if (allGroups != null)
- {
- for (int i = 0; i < allGroups.length; i++)
- {
- if ((allGroups[i].getStartRes() <= res)
- && (allGroups[i].getEndRes() >= res))
- {
- stretchGroup = allGroups[i];
- break;
- }
- }
- }
-
- av.setSelectionGroup(stretchGroup);
}
if (evt.isPopupTrigger()) // Mac: mousePressed
if (av.getConservationSelected())
{
- SliderPanel.setConservationSlider(ap, av.getGlobalColourScheme(),
- "Background");
+ SliderPanel.setConservationSlider(ap, av.getResidueShading(),
+ ap.getViewName());
}
if (av.getAbovePIDThreshold())
{
- SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(),
- "Background");
+ SliderPanel.setPIDSliderSource(ap, av.getResidueShading(),
+ ap.getViewName());
}
+ // TODO: stretchGroup will always be not null. Is this a merge error ?
if ((stretchGroup != null) && (stretchGroup.getEndRes() == res))
{
// Edit end res position of selected group
stretchGroup.cs.alignmentChanged(stretchGroup,
av.getHiddenRepSequences());
+ ResidueShaderI groupColourScheme = stretchGroup.getGroupColourScheme();
+ String name = stretchGroup.getName();
if (stretchGroup.cs.conservationApplied())
{
- SliderPanel.setConservationSlider(ap, stretchGroup.cs,
- stretchGroup.getName());
+ SliderPanel.setConservationSlider(ap, groupColourScheme, name);
}
- else
+ if (stretchGroup.cs.getThreshold() > 0)
{
- SliderPanel.setPIDSliderSource(ap, stretchGroup.cs,
- stretchGroup.getName());
+ SliderPanel.setPIDSliderSource(ap, groupColourScheme, name);
}
}
PaintRefresher.Refresh(this, av.getSequenceSetId());
import jalview.api.FeatureRenderer;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.schemes.ColourSchemeI;
+import jalview.renderer.ResidueShaderI;
+import jalview.util.Comparison;
import java.awt.Color;
import java.awt.FontMetrics;
{
if (currentSequenceGroup.getDisplayBoxes())
{
- getBoxColour(currentSequenceGroup.cs, seq, i);
+ getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq, i);
}
}
else if (av.getShowBoxes())
{
- getBoxColour(av.getGlobalColourScheme(), seq, i);
+ getBoxColour(av.getResidueShading(), seq, i);
}
return resBoxColour;
/**
* DOCUMENT ME!
*
- * @param cs
+ * @param shader
* DOCUMENT ME!
* @param seq
* DOCUMENT ME!
* @param i
* DOCUMENT ME!
*/
- void getBoxColour(ColourSchemeI cs, SequenceI seq, int i)
+ void getBoxColour(ResidueShaderI shader, SequenceI seq, int i)
{
- if (cs != null)
+ if (shader != null)
{
- resBoxColour = cs.findColour(seq.getCharAt(i), i, seq);
+ resBoxColour = shader.findColour(seq.getCharAt(i),
+ i, seq);
}
- else if (forOverview
- && !jalview.util.Comparison.isGap(seq.getCharAt(i)))
+ else if (forOverview && !Comparison.isGap(seq.getCharAt(i)))
{
resBoxColour = Color.lightGray;
}
{
if (currentSequenceGroup.getDisplayBoxes())
{
- getBoxColour(currentSequenceGroup.cs, seq, i);
+ getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq,
+ i);
}
}
else if (av.getShowBoxes())
{
- getBoxColour(av.getGlobalColourScheme(), seq, i);
+ getBoxColour(av.getResidueShading(), seq, i);
}
-
}
if (resBoxColour != tempColour)
|| currentSequenceGroup.getColourText())
{
getboxColour = true;
- getBoxColour(currentSequenceGroup.cs, seq, i);
+ getBoxColour(currentSequenceGroup.getGroupColourScheme(), seq,
+ i);
if (currentSequenceGroup.getColourText())
{
if (av.getColourText())
{
getboxColour = true;
- getBoxColour(av.getGlobalColourScheme(), seq, i);
+ getBoxColour(av.getResidueShading(), seq, i);
if (av.getShowBoxes())
{
{
if (!getboxColour)
{
- getBoxColour(av.getGlobalColourScheme(), seq, i);
+ getBoxColour(av.getResidueShading(), seq, i);
}
if (resBoxColour.getRed() + resBoxColour.getBlue()
import jalview.datamodel.SequenceGroup;
import jalview.jbgui.GSliderPanel;
-import jalview.schemes.ColourSchemeI;
+import jalview.renderer.ResidueShaderI;
import jalview.util.MessageManager;
-import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
-import java.util.Iterator;
+import java.beans.PropertyVetoException;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
/**
* DOCUMENT ME!
*/
public class SliderPanel extends GSliderPanel
{
+ private static final String BACKGROUND = "Background";
+
static JInternalFrame conservationSlider;
static JInternalFrame PIDSlider;
boolean forConservation = true;
- ColourSchemeI cs;
+ ResidueShaderI cs;
+
+ /**
+ * Returns the currently displayed slider panel (or null if none).
+ *
+ * @return
+ */
+ public static SliderPanel getSliderPanel()
+ {
+ if (conservationSlider != null && conservationSlider.isVisible())
+ {
+ return (SliderPanel) conservationSlider.getContentPane();
+ }
+ if (PIDSlider != null && PIDSlider.isVisible())
+ {
+ return (SliderPanel) PIDSlider.getContentPane();
+ }
+ return null;
+ }
/**
* Creates a new SliderPanel object.
* DOCUMENT ME!
* @param forConserve
* DOCUMENT ME!
- * @param cs
+ * @param scheme
* DOCUMENT ME!
*/
public SliderPanel(final AlignmentPanel ap, int value,
- boolean forConserve, ColourSchemeI cs)
+ boolean forConserve, ResidueShaderI scheme)
{
this.ap = ap;
- this.cs = cs;
+ this.cs = scheme;
forConservation = forConserve;
undoButton.setVisible(false);
applyButton.setVisible(false);
slider.addChangeListener(new ChangeListener()
{
+ @Override
public void stateChanged(ChangeEvent evt)
{
valueField.setText(slider.getValue() + "");
slider.addMouseListener(new MouseAdapter()
{
+ @Override
public void mouseReleased(MouseEvent evt)
{
ap.paintAlignment(true);
}
/**
- * DOCUMENT ME!
+ * Method to 'set focus' of the Conservation slider panel
*
* @param ap
- * DOCUMENT ME!
- * @param cs
- * DOCUMENT ME!
+ * the panel to repaint on change of slider
+ * @param rs
+ * the colour scheme to update on change of slider
* @param source
- * DOCUMENT ME!
+ * a text description for the panel's title
*
- * @return DOCUMENT ME!
+ * @return
*/
public static int setConservationSlider(AlignmentPanel ap,
- ColourSchemeI cs, String source)
+ ResidueShaderI rs, String source)
{
- SliderPanel sp = null;
+ SliderPanel sliderPanel = null;
if (conservationSlider == null)
{
- sp = new SliderPanel(ap, cs.getConservationInc(), true, cs);
+ sliderPanel = new SliderPanel(ap, rs.getConservationInc(), true, rs);
conservationSlider = new JInternalFrame();
- conservationSlider.setContentPane(sp);
+ conservationSlider.setContentPane(sliderPanel);
conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);
}
else
{
- sp = (SliderPanel) conservationSlider.getContentPane();
- sp.cs = cs;
+ sliderPanel = (SliderPanel) conservationSlider.getContentPane();
+ sliderPanel.valueField.setText(String.valueOf(rs.getConservationInc()));
+ sliderPanel.cs = rs;
+ sliderPanel.ap = ap;
+ sliderPanel.slider.setValue(rs.getConservationInc());
}
- conservationSlider
- .setTitle(MessageManager.formatMessage(
- "label.conservation_colour_increment",
- new String[] { source }));
+ conservationSlider.setTitle(MessageManager.formatMessage(
+ "label.conservation_colour_increment",
+ new String[] { source == null ? BACKGROUND : source }));
if (ap.av.getAlignment().getGroups() != null)
{
- sp.setAllGroupsCheckEnabled(true);
+ sliderPanel.setAllGroupsCheckEnabled(true);
}
else
{
- sp.setAllGroupsCheckEnabled(false);
+ sliderPanel.setAllGroupsCheckEnabled(false);
}
- return sp.getValue();
+ return sliderPanel.getValue();
}
/**
- * DOCUMENT ME!
+ * Hides the PID slider panel if it is shown
*/
- public static void showConservationSlider()
+ public static void hidePIDSlider()
{
- try
+ if (PIDSlider != null)
{
- PIDSlider.setClosed(true);
- PIDSlider = null;
- } catch (Exception ex)
+ try
+ {
+ PIDSlider.setClosed(true);
+ PIDSlider = null;
+ } catch (PropertyVetoException ex)
+ {
+ }
+ }
+ }
+
+ /**
+ * Hides the conservation slider panel if it is shown
+ */
+ public static void hideConservationSlider()
+ {
+ if (conservationSlider != null)
{
+ try
+ {
+ conservationSlider.setClosed(true);
+ conservationSlider = null;
+ } catch (PropertyVetoException ex)
+ {
+ }
}
+ }
+
+ /**
+ * DOCUMENT ME!
+ */
+ public static void showConservationSlider()
+ {
+ hidePIDSlider();
if (!conservationSlider.isVisible())
{
Desktop.addInternalFrame(conservationSlider,
conservationSlider.getTitle(), 420, 90, false);
conservationSlider
- .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
+ .addInternalFrameListener(new InternalFrameAdapter()
{
- public void internalFrameClosed(
- javax.swing.event.InternalFrameEvent e)
+ @Override
+ public void internalFrameClosed(InternalFrameEvent e)
{
conservationSlider = null;
}
}
/**
- * DOCUMENT ME!
+ * Method to 'set focus' of the PID slider panel
*
* @param ap
- * DOCUMENT ME!
- * @param cs
- * DOCUMENT ME!
+ * the panel to repaint on change of slider
+ * @param rs
+ * the colour scheme to update on change of slider
* @param source
- * DOCUMENT ME!
+ * a text description for the panel's title
*
- * @return DOCUMENT ME!
+ * @return
*/
- public static int setPIDSliderSource(AlignmentPanel ap, ColourSchemeI cs,
- String source)
+ public static int setPIDSliderSource(AlignmentPanel ap,
+ ResidueShaderI rs, String source)
{
- SliderPanel pid = null;
+ int threshold = rs.getThreshold();
- int threshold = cs.getThreshold();
+ SliderPanel sliderPanel = null;
if (PIDSlider == null)
{
- pid = new SliderPanel(ap, threshold, false, cs);
+ sliderPanel = new SliderPanel(ap, threshold, false, rs);
PIDSlider = new JInternalFrame();
- PIDSlider.setContentPane(pid);
+ PIDSlider.setContentPane(sliderPanel);
PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
}
else
{
- pid = (SliderPanel) PIDSlider.getContentPane();
- pid.cs = cs;
+ sliderPanel = (SliderPanel) PIDSlider.getContentPane();
+ sliderPanel.cs = rs;
+ sliderPanel.ap = ap;
+ sliderPanel.valueField.setText(String.valueOf(rs.getThreshold()));
+ sliderPanel.slider.setValue(rs.getThreshold());
}
- PIDSlider
- .setTitle(MessageManager.formatMessage(
- "label.percentage_identity_threshold",
- new String[] { source }));
+ PIDSlider.setTitle(MessageManager.formatMessage(
+ "label.percentage_identity_threshold",
+ new String[] { source == null ? BACKGROUND : source }));
if (ap.av.getAlignment().getGroups() != null)
{
- pid.setAllGroupsCheckEnabled(true);
+ sliderPanel.setAllGroupsCheckEnabled(true);
}
else
{
- pid.setAllGroupsCheckEnabled(false);
+ sliderPanel.setAllGroupsCheckEnabled(false);
}
- return pid.getValue();
+ return sliderPanel.getValue();
}
/**
* DOCUMENT ME!
+ *
+ * @return
*/
- public static void showPIDSlider()
+ public static JInternalFrame showPIDSlider()
{
- try
- {
- conservationSlider.setClosed(true);
- conservationSlider = null;
- } catch (Exception ex)
- {
- }
+ hideConservationSlider();
if (!PIDSlider.isVisible())
{
Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), 420, 90,
false);
PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
- PIDSlider
- .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
- {
- public void internalFrameClosed(
- javax.swing.event.InternalFrameEvent e)
- {
- PIDSlider = null;
- }
- });
+ PIDSlider.addInternalFrameListener(new InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosed(InternalFrameEvent e)
+ {
+ PIDSlider = null;
+ }
+ });
PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
}
+ return PIDSlider;
}
/**
- * DOCUMENT ME!
+ * Updates the colour scheme with the current (identity threshold or
+ * conservation) percentage value. Also updates all groups if 'apply to all
+ * groups' is selected.
*
- * @param i
- * DOCUMENT ME!
+ * @param percent
*/
- public void valueChanged(int i)
+ public void valueChanged(int percent)
{
- if (cs == null)
+ if (!forConservation)
{
- return;
+ ap.av.setThreshold(percent);
}
-
- ColourSchemeI toChange = cs;
- Iterator<SequenceGroup> allGroups = null;
+ updateColourScheme(percent, cs);
if (allGroupsCheck.isSelected())
{
- allGroups = ap.av.getAlignment().getGroups().listIterator();
- }
-
- while (toChange != null)
- {
- if (forConservation)
- {
- toChange.setConservationInc(i);
- }
- else
- {
- toChange.setThreshold(i, ap.av.isIgnoreGapsConsensus());
- }
- if (allGroups != null && allGroups.hasNext())
- {
- while ((toChange = allGroups.next().cs) == null
- && allGroups.hasNext())
- {
- ;
- }
- }
- else
+ for (SequenceGroup sg : ap.av.getAlignment().getGroups())
{
- toChange = null;
+ updateColourScheme(percent, sg.getGroupColourScheme());
}
}
}
/**
+ * Updates the colour scheme (if not null) with the current (identity
+ * threshold or conservation) percentage value
+ *
+ * @param percent
+ * @param scheme
+ */
+ protected void updateColourScheme(int percent, ResidueShaderI scheme)
+ {
+ if (scheme == null)
+ {
+ return;
+ }
+ if (forConservation)
+ {
+ scheme.setConservationInc(percent);
+ }
+ else
+ {
+ scheme.setThreshold(percent, ap.av.isIgnoreGapsConsensus());
+ }
+ }
+
+ /**
* DOCUMENT ME!
*
* @param b
* @param e
* DOCUMENT ME!
*/
- public void valueField_actionPerformed(ActionEvent e)
+ @Override
+ public void valueField_actionPerformed()
{
try
{
return Integer.parseInt(valueField.getText());
}
+ @Override
public void slider_mouseReleased(MouseEvent e)
{
if (ap.overviewPanel != null)
}
}
+ public static int getConservationValue()
+ {
+ return getValue(conservationSlider);
+ }
+
+ static int getValue(JInternalFrame slider)
+ {
+ return slider == null ? 0 : ((SliderPanel) slider.getContentPane())
+ .getValue();
+ }
+
+ public static int getPIDValue()
+ {
+ return getValue(PIDSlider);
+ }
+
+ /**
+ * Answers true if the SliderPanel is for Conservation, false if it is for PID
+ * threshold
+ *
+ * @return
+ */
+ public boolean isForConservation()
+ {
+ return forConservation;
+ }
+
+ /**
+ * Answers the title for the slider panel; this may include 'Background' if
+ * for the alignment, or the group id if for a group
+ *
+ * @return
+ */
+ public String getTitle()
+ {
+ String title = null;
+ if (isForConservation())
+ {
+ if (conservationSlider != null)
+ {
+ title = conservationSlider.getTitle();
+ }
+ }
+ else if (PIDSlider != null)
+ {
+ title = PIDSlider.getTitle();
+ }
+ return title;
+ }
}
*/
package jalview.gui;
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.gui.StructureViewer.ViewerType;
import jalview.gui.ViewSelectionMenu.ViewSetProvider;
import jalview.io.DataSourceType;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
import jalview.jbgui.GStructureViewer;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemes;
import jalview.structures.models.AAStructureBindingModel;
import jalview.util.MessageManager;
+import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
+import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JMenu;
import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
/**
* Base class with common functionality for JMol, Chimera or other structure
public abstract class StructureViewerBase extends GStructureViewer
implements Runnable, ViewSetProvider
{
+ /*
+ * names for colour options (additional to Jalview colour schemes)
+ */
+ enum ViewerColour
+ {
+ BySequence, ByChain, ChargeCysteine, ByViewer
+ }
/**
* list of sequenceSet ids associated with the view
protected boolean allChainsSelected = false;
+ protected JMenu viewSelectionMenu;
+
+ /**
+ * Default constructor
+ */
+ public StructureViewerBase()
+ {
+ super();
+ }
/**
*
* @param ap2
}
}
// otherwise, start adding the structure.
- getBindingModel().addSequenceAndChain(new PDBEntry[] { pdbentry },
+ getBinding().addSequenceAndChain(new PDBEntry[] { pdbentry },
new SequenceI[][] { seqs }, new String[][] { chains });
addingStructures = true;
_started = false;
return option;
}
- protected abstract boolean hasPdbId(String pdbId);
+ protected boolean hasPdbId(String pdbId)
+ {
+ return getBinding().hasPdbId(pdbId);
+ }
protected abstract List<StructureViewerBase> getViewersFor(
AlignmentPanel alp);
// JBPNOTE: this looks like a binding routine, rather than a gui routine
for (StructureViewerBase viewer : getViewersFor(null))
{
- AAStructureBindingModel bindingModel = viewer.getBindingModel();
+ AAStructureBindingModel bindingModel = viewer.getBinding();
for (int pe = 0; pe < bindingModel.getPdbCount(); pe++)
{
if (bindingModel.getPdbEntry(pe).getFile().equals(pdbFilename))
abstract void showSelectedChains();
+ /**
+ * Action on selecting one of Jalview's registered colour schemes
+ */
+ @Override
+ public void changeColour_actionPerformed(String colourSchemeName)
+ {
+ AlignmentI al = getAlignmentPanel().av.getAlignment();
+ ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(
+ colourSchemeName, al, null);
+ getBinding().setJalviewColourScheme(cs);
+ }
+
+ /**
+ * Builds the colour menu
+ */
+ protected void buildColourMenu()
+ {
+ colourMenu.removeAll();
+ AlignmentI al = getAlignmentPanel().av.getAlignment();
+
+ /*
+ * add colour by sequence, by chain, by charge and cysteine
+ */
+ colourMenu.add(seqColour);
+ colourMenu.add(chainColour);
+ colourMenu.add(chargeColour);
+ chargeColour.setEnabled(!al.isNucleotide());
+
+ /*
+ * add all 'simple' (per-residue) colour schemes registered to Jalview
+ */
+ ButtonGroup itemGroup = ColourMenuHelper.addMenuItems(colourMenu, this,
+ al, true);
+
+ /*
+ * add 'colour by viewer' (menu item text is set in subclasses)
+ */
+ viewerColour.setSelected(false);
+ viewerColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent)
+ {
+ viewerColour_actionPerformed(actionEvent);
+ }
+ });
+ colourMenu.add(viewerColour);
+
+ /*
+ * add 'set background colour'
+ */
+ JMenuItem backGround = new JMenuItem();
+ backGround
+ .setText(MessageManager.getString("action.background_colour"));
+ backGround.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent)
+ {
+ background_actionPerformed(actionEvent);
+ }
+ });
+ colourMenu.add(backGround);
+
+ /*
+ * add colour buttons to a group so their selection is
+ * mutually exclusive (background colour is a separate option)
+ */
+ itemGroup.add(seqColour);
+ itemGroup.add(chainColour);
+ itemGroup.add(chargeColour);
+ itemGroup.add(viewerColour);
+ }
+
+ /**
+ * Construct menu items
+ */
+ protected void initMenus()
+ {
+ AAStructureBindingModel binding = getBinding();
+
+ seqColour = new JRadioButtonMenuItem();
+ seqColour.setText(MessageManager.getString("action.by_sequence"));
+ seqColour.setName(ViewerColour.BySequence.name());
+ seqColour.setSelected(binding.isColourBySequence());
+ seqColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent)
+ {
+ seqColour_actionPerformed(actionEvent);
+ }
+ });
+
+ chainColour = new JRadioButtonMenuItem();
+ chainColour.setText(MessageManager.getString("action.by_chain"));
+ chainColour.setName(ViewerColour.ByChain.name());
+ chainColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent)
+ {
+ chainColour_actionPerformed(actionEvent);
+ }
+ });
+
+ chargeColour = new JRadioButtonMenuItem();
+ chargeColour.setText(MessageManager.getString("label.charge_cysteine"));
+ chargeColour.setName(ViewerColour.ChargeCysteine.name());
+ chargeColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent)
+ {
+ chargeColour_actionPerformed(actionEvent);
+ }
+ });
+
+ viewerColour = new JRadioButtonMenuItem();
+ // text is set in overrides of this method
+ viewerColour.setName(ViewerColour.ByViewer.name());
+ viewerColour.setSelected(!binding.isColourBySequence());
+
+ if (_colourwith == null)
+ {
+ _colourwith = new Vector<AlignmentPanel>();
+ }
+ if (_alignwith == null)
+ {
+ _alignwith = new Vector<AlignmentPanel>();
+ }
+
+ ViewSelectionMenu seqColourBy = new ViewSelectionMenu(
+ MessageManager.getString("label.colour_by"), this, _colourwith,
+ new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent e)
+ {
+ if (!seqColour.isSelected())
+ {
+ seqColour.doClick();
+ }
+ else
+ {
+ // update the Chimera display now.
+ seqColour_actionPerformed(null);
+ }
+ }
+ });
+ viewMenu.add(seqColourBy);
+
+ final ItemListener handler = new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent e)
+ {
+ alignStructs.setEnabled(!_alignwith.isEmpty());
+ alignStructs.setToolTipText(MessageManager.formatMessage(
+ "label.align_structures_using_linked_alignment_views",
+ _alignwith.size()));
+ }
+ };
+ viewSelectionMenu = new ViewSelectionMenu(
+ MessageManager.getString("label.superpose_with"), this,
+ _alignwith, handler);
+ handler.itemStateChanged(null);
+ viewerActionMenu.add(viewSelectionMenu, 0);
+ viewerActionMenu.addMenuListener(new MenuListener()
+ {
+ @Override
+ public void menuSelected(MenuEvent e)
+ {
+ handler.itemStateChanged(null);
+ }
+
+ @Override
+ public void menuDeselected(MenuEvent e)
+ {
+ }
+
+ @Override
+ public void menuCanceled(MenuEvent e)
+ {
+ }
+ });
+
+ buildColourMenu();
+ }
+
+ @Override
+ public void setJalviewColourScheme(ColourSchemeI cs) {
+ getBinding().setJalviewColourScheme(cs);
+ }
+
+ /**
+ * Sends commands to the structure viewer to superimpose structures based on
+ * currently associated alignments. May optionally return an error message for
+ * the operation.
+ */
+ @Override
+ protected String alignStructs_actionPerformed(
+ ActionEvent actionEvent)
+ {
+ return alignStructs_withAllAlignPanels();
+ }
+
+ protected String alignStructs_withAllAlignPanels()
+ {
+ if (getAlignmentPanel() == null)
+ {
+ return null;
+ }
+
+ if (_alignwith.size() == 0)
+ {
+ _alignwith.add(getAlignmentPanel());
+ }
+
+ String reply = null;
+ try
+ {
+ AlignmentI[] als = new Alignment[_alignwith.size()];
+ ColumnSelection[] alc = new ColumnSelection[_alignwith.size()];
+ int[] alm = new int[_alignwith.size()];
+ int a = 0;
+
+ for (AlignmentPanel ap : _alignwith)
+ {
+ als[a] = ap.av.getAlignment();
+ alm[a] = -1;
+ alc[a++] = ap.av.getColumnSelection();
+ }
+ reply = getBinding().superposeStructures(als, alm, alc);
+ if (reply != null)
+ {
+ String text = MessageManager.formatMessage(
+ "error.superposition_failed", reply);
+ statusBar.setText(text);
+ }
+ } catch (Exception e)
+ {
+ StringBuffer sp = new StringBuffer();
+ for (AlignmentPanel ap : _alignwith)
+ {
+ sp.append("'" + ap.alignFrame.getTitle() + "' ");
+ }
+ Cache.log.info("Couldn't align structures with the " + sp.toString()
+ + "associated alignment panels.", e);
+ }
+ return reply;
+ }
+
+ @Override
+ public void background_actionPerformed(ActionEvent actionEvent)
+ {
+ Color col = JColorChooser.showDialog(this,
+ MessageManager.getString("label.select_background_colour"),
+ null);
+ if (col != null)
+ {
+ getBinding().setBackgroundColour(col);
+ }
+ }
+ @Override
+ public void viewerColour_actionPerformed(ActionEvent actionEvent)
+ {
+ if (viewerColour.isSelected())
+ {
+ // disable automatic sequence colouring.
+ getBinding().setColourBySequence(false);
+ }
+ }
+ @Override
+ public void chainColour_actionPerformed(ActionEvent actionEvent)
+ {
+ chainColour.setSelected(true);
+ getBinding().colourByChain();
+ }
+ @Override
+ public void chargeColour_actionPerformed(ActionEvent actionEvent)
+ {
+ chargeColour.setSelected(true);
+ getBinding().colourByCharge();
+ }
+ @Override
+ public void seqColour_actionPerformed(ActionEvent actionEvent)
+ {
+ AAStructureBindingModel binding = getBinding();
+ binding.setColourBySequence(seqColour.isSelected());
+ if (_colourwith == null)
+ {
+ _colourwith = new Vector<AlignmentPanel>();
+ }
+ if (binding.isColourBySequence())
+ {
+ if (!binding.isLoadingFromArchive())
+ {
+ if (_colourwith.size() == 0 && getAlignmentPanel() != null)
+ {
+ // Make the currently displayed alignment panel the associated view
+ _colourwith.add(getAlignmentPanel().alignFrame.alignPanel);
+ }
+ }
+ // Set the colour using the current view for the associated alignframe
+ for (AlignmentPanel ap : _colourwith)
+ {
+ binding.colourBySequence(ap);
+ }
+ }
+ }
+ @Override
+ public void pdbFile_actionPerformed(ActionEvent actionEvent)
+ {
+ JalviewFileChooser chooser = new JalviewFileChooser(
+ Cache.getProperty("LAST_DIRECTORY"));
+
+ chooser.setFileView(new JalviewFileView());
+ chooser.setDialogTitle(MessageManager.getString("label.save_pdb_file"));
+ chooser.setToolTipText(MessageManager.getString("action.save"));
+
+ int value = chooser.showSaveDialog(this);
+
+ if (value == JalviewFileChooser.APPROVE_OPTION)
+ {
+ BufferedReader in = null;
+ try
+ {
+ // TODO: cope with multiple PDB files in view
+ in = new BufferedReader(
+ new FileReader(getBinding().getPdbFile()[0]));
+ File outFile = chooser.getSelectedFile();
+
+ PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
+ String data;
+ while ((data = in.readLine()) != null)
+ {
+ if (!(data.indexOf("<PRE>") > -1 || data.indexOf("</PRE>") > -1))
+ {
+ out.println(data);
+ }
+ }
+ out.close();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ } finally
+ {
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ } catch (IOException e)
+ {
+ // ignore
+ }
+ }
+ }
+ }
+ }
+ @Override
+ public void viewMapping_actionPerformed(ActionEvent actionEvent)
+ {
+ CutAndPasteTransfer cap = new CutAndPasteTransfer();
+ try
+ {
+ cap.appendText(getBinding().printMappings());
+ } catch (OutOfMemoryError e)
+ {
+ new OOMWarning(
+ "composing sequence-structure alignments for display in text box.",
+ e);
+ cap.dispose();
+ return;
+ }
+ Desktop.addInternalFrame(cap,
+ MessageManager.getString("label.pdb_sequence_mapping"), 550,
+ 600);
+ }
+
+ protected abstract String getViewerName();
+
+ /**
+ * Configures the title and menu items of the viewer panel.
+ */
+ public void updateTitleAndMenus()
+ {
+ AAStructureBindingModel binding = getBinding();
+ if (binding.hasFileLoadingError())
+ {
+ repaint();
+ return;
+ }
+ setChainMenuItems(binding.getChainNames());
+
+ this.setTitle(binding.getViewerTitle(getViewerName(), true));
+
+ /*
+ * enable 'Superpose with' if more than one mapped structure
+ */
+ viewSelectionMenu.setEnabled(false);
+ if (getBinding().getPdbFile().length > 1
+ && getBinding().getSequence().length > 1)
+ {
+ viewSelectionMenu.setEnabled(true);
+ }
+
+ /*
+ * Show action menu if it has any enabled items
+ */
+ viewerActionMenu.setVisible(false);
+ for (int i = 0; i < viewerActionMenu.getItemCount(); i++)
+ {
+ if (viewerActionMenu.getItem(i).isEnabled())
+ {
+ viewerActionMenu.setVisible(true);
+ break;
+ }
+ }
+
+ if (!binding.isLoadingFromArchive())
+ {
+ seqColour_actionPerformed(null);
+ }
+ }
}
}
else
{
- cs = ColourSchemeProperty.getColour(sg, ColourSchemeProperty
- .getColourName(av.getGlobalColourScheme()));
+ cs = ColourSchemeProperty.getColourScheme(sg,
+ ColourSchemeProperty.getColourName(av
+ .getGlobalColourScheme()));
}
// cs is null if shading is an annotationColourGradient
- if (cs != null)
- {
- cs.setThreshold(av.getGlobalColourScheme().getThreshold(),
- av.isIgnoreGapsConsensus());
- }
+ // if (cs != null)
+ // {
+ // cs.setThreshold(av.getViewportColourScheme().getThreshold(),
+ // av.isIgnoreGapsConsensus());
+ // }
}
- sg.cs = cs;
+ sg.setColourScheme(cs);
+ sg.getGroupColourScheme().setThreshold(
+ av.getResidueShading().getThreshold(),
+ av.isIgnoreGapsConsensus());
// sg.recalcConservation();
sg.setName("JTreeGroup:" + sg.hashCode());
sg.setIdColour(col);
for (int a = 0; a < aps.length; a++)
{
if (aps[a].av.getGlobalColourScheme() != null
- && aps[a].av.getGlobalColourScheme().conservationApplied())
+ && aps[a].av.getResidueShading()
+ .conservationApplied())
{
Conservation c = new Conservation("Group", sg.getSequences(null),
sg.getStartRes(), sg.getEndRes());
try
{
JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"),
ImageMaker.EPS_EXTENSION, ImageMaker.EPS_EXTENSION);
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager
try
{
JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"),
ImageMaker.PNG_EXTENSION, ImageMaker.PNG_DESCRIPTION);
chooser.setFileView(new jalview.io.JalviewFileView());
import jalview.io.JalviewFileChooser;
import jalview.io.JalviewFileView;
import jalview.jbgui.GUserDefinedColours;
+import jalview.schemabinding.version2.Colour;
+import jalview.schemabinding.version2.JalviewUserColours;
import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemes;
import jalview.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
import jalview.util.ColorUtils;
+import jalview.util.Format;
import jalview.util.MessageManager;
import java.awt.Color;
import java.awt.Font;
+import java.awt.Insets;
import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
+import java.util.List;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
public class UserDefinedColours extends GUserDefinedColours implements
ChangeListener
{
+ private static final Font VERDANA_BOLD_10 = new Font("Verdana",
+ Font.BOLD, 10);
+
+ public static final String USER_DEFINED_COLOURS = "USER_DEFINED_COLOURS";
+
+ private static final String LAST_DIRECTORY = "LAST_DIRECTORY";
+
private static final int MY_FRAME_HEIGHT = 420;
private static final int MY_FRAME_WIDTH = 810;
SequenceGroup seqGroup;
- ArrayList<JButton> selectedButtons;
+ List<JButton> selectedButtons;
ColourSchemeI oldColourScheme;
JInternalFrame frame;
- JalviewStructureDisplayI jmol;
+ JalviewStructureDisplayI structureViewer;
- ArrayList<JButton> upperCaseButtons;
+ List<JButton> upperCaseButtons;
- ArrayList<JButton> lowerCaseButtons;
+ List<JButton> lowerCaseButtons;
/**
* Creates a new UserDefinedColours object.
*
* @param ap
- * DOCUMENT ME!
* @param sg
- * DOCUMENT ME!
*/
public UserDefinedColours(AlignmentPanel ap, SequenceGroup sg)
{
- super();
+ this();
lcaseColour.setEnabled(false);
if (seqGroup != null)
{
- oldColourScheme = seqGroup.cs;
+ oldColourScheme = seqGroup.getColourScheme();
}
else
{
if (oldColourScheme instanceof UserColourScheme)
{
- schemeName.setText(((UserColourScheme) oldColourScheme).getName());
+ schemeName.setText(oldColourScheme.getSchemeName());
if (((UserColourScheme) oldColourScheme).getLowerCaseColours() != null)
{
caseSensitive.setSelected(true);
showFrame();
}
- public UserDefinedColours(JalviewStructureDisplayI jmol,
+ public UserDefinedColours(JalviewStructureDisplayI viewer,
ColourSchemeI oldcs)
{
- super();
- this.jmol = jmol;
+ this();
+ this.structureViewer = viewer;
colorChooser.getSelectionModel().addChangeListener(this);
if (oldColourScheme instanceof UserColourScheme)
{
- schemeName.setText(((UserColourScheme) oldColourScheme).getName());
+ schemeName.setText(((UserColourScheme) oldColourScheme)
+ .getSchemeName());
}
resetButtonPanel(false);
}
+ public UserDefinedColours()
+ {
+ super();
+ selectedButtons = new ArrayList<JButton>();
+ }
+
void showFrame()
{
colorChooser.getSelectionModel().addChangeListener(this);
}
}
- void resetButtonPanel(boolean caseSensitive)
+ /**
+ * Rebuilds the panel with coloured buttons for residues. If not case
+ * sensitive colours, show 3-letter amino acid code as button text. If case
+ * sensitive, just show the single letter code, in order to make space for the
+ * additional buttons.
+ *
+ * @param isCaseSensitive
+ */
+ void resetButtonPanel(boolean isCaseSensitive)
{
buttonPanel.removeAll();
upperCaseButtons = new ArrayList<JButton>();
}
- JButton button;
- String label;
for (int i = 0; i < 20; i++)
{
- if (caseSensitive)
- {
- label = ResidueProperties.aa[i];
- }
- else
- {
- label = ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i])
- .toString();
- }
-
- button = makeButton(label, ResidueProperties.aa[i], upperCaseButtons,
- i);
-
+ String label = isCaseSensitive ? ResidueProperties.aa[i]
+ : ResidueProperties.aa2Triplet.get(ResidueProperties.aa[i])
+ .toString();
+ JButton button = makeButton(label, ResidueProperties.aa[i],
+ upperCaseButtons, i);
buttonPanel.add(button);
}
buttonPanel.add(makeButton("X", "X", upperCaseButtons, 22));
buttonPanel.add(makeButton("Gap", "-", upperCaseButtons, 23));
- if (!caseSensitive)
+ if (!isCaseSensitive)
{
gridLayout.setRows(6);
gridLayout.setColumns(4);
{
int row = i / cols + 1;
int index = (row * cols) + i;
- button = makeButton(ResidueProperties.aa[i].toLowerCase(),
+ JButton button = makeButton(ResidueProperties.aa[i].toLowerCase(),
ResidueProperties.aa[i].toLowerCase(), lowerCaseButtons, i);
buttonPanel.add(button, index);
}
}
- if (caseSensitive)
+ if (isCaseSensitive)
{
buttonPanel.add(makeButton("b", "b", lowerCaseButtons, 20));
buttonPanel.add(makeButton("z", "z", lowerCaseButtons, 21));
// codes
if (this.frame != null)
{
- int newWidth = caseSensitive ? MY_FRAME_WIDTH_CASE_SENSITIVE
+ int newWidth = isCaseSensitive ? MY_FRAME_WIDTH_CASE_SENSITIVE
: MY_FRAME_WIDTH;
this.frame.setSize(newWidth, this.frame.getHeight());
}
}
/**
- * DOCUMENT ME!
+ * ChangeListener handler for when a colour is picked in the colour chooser.
+ * The action is to apply the colour to all selected buttons as their
+ * background colour. Foreground colour (text) is set to a lighter shade in
+ * order to highlight which buttons are selected. If 'Lower Case Colour' is
+ * active, then the colour is applied to all lower case buttons (as well as
+ * the Lower Case Colour button itself).
*
* @param evt
- * DOCUMENT ME!
*/
@Override
public void stateChanged(ChangeEvent evt)
{
- if (selectedButtons != null)
+ JButton button = null;
+ final Color newColour = colorChooser.getColor();
+ for (int i = 0; i < selectedButtons.size(); i++)
{
- JButton button = null;
- final Color newColour = colorChooser.getColor();
- for (int i = 0; i < selectedButtons.size(); i++)
+ button = selectedButtons.get(i);
+ button.setBackground(newColour);
+ button.setForeground(ColorUtils.brighterThan(newColour));
+ }
+ if (lcaseColour.isSelected())
+ {
+ for (int i = 0; i < lowerCaseButtons.size(); i++)
{
- button = selectedButtons.get(i);
+ button = lowerCaseButtons.get(i);
button.setBackground(newColour);
- button.setForeground(ColorUtils.brighterThan(newColour));
- }
- if (button == lcaseColour)
- {
- for (int i = 0; i < lowerCaseButtons.size(); i++)
- {
- button = lowerCaseButtons.get(i);
- button.setBackground(newColour);
- button.setForeground(ColorUtils.brighterThan(button
- .getBackground()));
- }
+ button.setForeground(ColorUtils.brighterThan(button.getBackground()));
}
}
}
*/
public void colourButtonPressed(MouseEvent e)
{
- if (selectedButtons == null)
- {
- selectedButtons = new ArrayList<JButton>();
- }
-
JButton pressed = (JButton) e.getSource();
if (e.isShiftDown())
}
/**
- * DOCUMENT ME!
+ * A helper method to update or make a colour button, whose background colour
+ * is the associated colour, and text colour a darker shade of the same. If
+ * the button is already in the list, then its text and margins are updated,
+ * if not then it is created and added. This method supports toggling between
+ * case-sensitive and case-insensitive button panels. The case-sensitive
+ * version has abbreviated button text in order to fit in more buttons.
*
* @param label
- * DOCUMENT ME!
- * @param aa
- * DOCUMENT ME!
+ * @param residue
+ * @param the
+ * list of buttons
+ * @param buttonIndex
+ * the button's position in the list
*/
- JButton makeButton(String label, String aa,
- ArrayList<JButton> caseSensitiveButtons, int buttonIndex)
+ JButton makeButton(String label, String residue, List<JButton> buttons,
+ int buttonIndex)
{
final JButton button;
Color col;
- if (buttonIndex < caseSensitiveButtons.size())
+ if (buttonIndex < buttons.size())
{
- button = caseSensitiveButtons.get(buttonIndex);
+ button = buttons.get(buttonIndex);
col = button.getBackground();
}
else
{
button = new JButton();
- button.addMouseListener(new java.awt.event.MouseAdapter()
+ button.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
}
});
- caseSensitiveButtons.add(button);
+ buttons.add(button);
+ /*
+ * make initial button colour that of the current colour scheme,
+ * if it is a simple per-residue colouring, else white
+ */
col = Color.white;
- if (oldColourScheme != null)
+ if (oldColourScheme != null && oldColourScheme.isSimple())
{
- try
- {
- col = oldColourScheme.findColour(aa.charAt(0), -1, null);
- } catch (Exception ex)
- {
- }
+ col = oldColourScheme.findColour(residue.charAt(0), 0, null, null,
+ 0f);
}
}
if (caseSensitive.isSelected())
{
- button.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ button.setMargin(new Insets(2, 2, 2, 2));
}
else
{
- button.setMargin(new java.awt.Insets(2, 14, 2, 14));
+ button.setMargin(new Insets(2, 14, 2, 14));
}
button.setOpaque(true); // required for the next line to have effect
button.setBackground(col);
button.setText(label);
button.setForeground(ColorUtils.darkerThan(col));
- button.setFont(new java.awt.Font("Verdana", Font.BOLD, 10));
+ button.setFont(VERDANA_BOLD_10);
return button;
}
/**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
+ * On 'OK', check that at least one colour has been assigned to a residue (and
+ * if not issue a warning), and apply the chosen colour scheme and close the
+ * panel.
*/
@Override
- protected void okButton_actionPerformed(ActionEvent e)
+ protected void okButton_actionPerformed()
{
if (isNoSelectionMade())
{
}
else
{
- applyButton_actionPerformed(null);
+ applyButton_actionPerformed();
try
{
}
/**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
+ * Applies the current colour scheme to the alignment, sequence group or
+ * structure view.
*/
@Override
- protected void applyButton_actionPerformed(ActionEvent e)
+ protected void applyButton_actionPerformed()
{
if (isNoSelectionMade())
{
}
UserColourScheme ucs = getSchemeFromButtons();
- ucs.setName(schemeName.getText());
if (seqGroup != null)
{
- seqGroup.cs = ucs;
+ seqGroup.setColourScheme(ucs);
ap.paintAlignment(true);
}
else if (ap != null)
{
ap.alignFrame.changeColour(ucs);
}
- else if (jmol != null)
+ else if (structureViewer != null)
{
- jmol.setJalviewColourScheme(ucs);
+ structureViewer.setJalviewColourScheme(ucs);
}
}
}
UserColourScheme ucs = new UserColourScheme(newColours);
+ ucs.setName(schemeName.getText());
if (caseSensitive.isSelected())
{
ucs.setLowerCaseColours(newColours);
}
- if (ap != null)
- {
- ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
- }
+ // if (ap != null)
+ // {
+ // ucs.setThreshold(0, ap.av.isIgnoreGapsConsensus());
+ // }
return ucs;
}
upperCaseButtons = new ArrayList<JButton>();
lowerCaseButtons = new ArrayList<JButton>();
- JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"), "jc",
+ JalviewFileChooser chooser = new JalviewFileChooser("jc",
"Jalview User Colours");
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager
int value = chooser.showOpenDialog(this);
- if (value == JalviewFileChooser.APPROVE_OPTION)
+ if (value != JalviewFileChooser.APPROVE_OPTION)
{
- File choice = chooser.getSelectedFile();
- jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
- String defaultColours = jalview.bin.Cache.getDefault(
- "USER_DEFINED_COLOURS", choice.getPath());
- if (defaultColours.indexOf(choice.getPath()) == -1)
- {
- defaultColours = defaultColours.concat("|")
- .concat(choice.getPath());
- }
-
- jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);
-
- UserColourScheme ucs = loadColours(choice.getAbsolutePath());
- Color[] colors = ucs.getColours();
- schemeName.setText(ucs.getName());
-
- if (ucs.getLowerCaseColours() != null)
- {
- caseSensitive.setSelected(true);
- lcaseColour.setEnabled(true);
- resetButtonPanel(true);
- for (int i = 0; i < lowerCaseButtons.size(); i++)
- {
- JButton button = lowerCaseButtons.get(i);
- button.setBackground(ucs.getLowerCaseColours()[i]);
- }
+ return;
+ }
+ File choice = chooser.getSelectedFile();
+ Cache.setProperty(LAST_DIRECTORY, choice.getParent());
- }
- else
- {
- caseSensitive.setSelected(false);
- lcaseColour.setEnabled(false);
- resetButtonPanel(false);
- }
+ UserColourScheme ucs = ColourSchemes.loadColourScheme(choice
+ .getAbsolutePath());
+ Color[] colors = ucs.getColours();
+ schemeName.setText(ucs.getSchemeName());
- for (int i = 0; i < upperCaseButtons.size(); i++)
+ if (ucs.getLowerCaseColours() != null)
+ {
+ caseSensitive.setSelected(true);
+ lcaseColour.setEnabled(true);
+ resetButtonPanel(true);
+ for (int i = 0; i < lowerCaseButtons.size(); i++)
{
- JButton button = upperCaseButtons.get(i);
- button.setBackground(colors[i]);
+ JButton button = lowerCaseButtons.get(i);
+ button.setBackground(ucs.getLowerCaseColours()[i]);
}
+ }
+ else
+ {
+ caseSensitive.setSelected(false);
+ lcaseColour.setEnabled(false);
+ resetButtonPanel(false);
+ }
+ for (int i = 0; i < upperCaseButtons.size(); i++)
+ {
+ JButton button = upperCaseButtons.get(i);
+ button.setBackground(colors[i]);
}
+
+ addNewColourScheme(choice.getPath());
}
/**
- * DOCUMENT ME!
+ * Loads the user-defined colour scheme from the first file listed in property
+ * "USER_DEFINED_COLOURS". If this fails, returns an all-white colour scheme.
*
- * @return DOCUMENT ME!
+ * @return
*/
public static UserColourScheme loadDefaultColours()
{
UserColourScheme ret = null;
- String colours = jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS");
+ String colours = Cache.getProperty(USER_DEFINED_COLOURS);
if (colours != null)
{
if (colours.indexOf("|") > -1)
{
colours = colours.substring(0, colours.indexOf("|"));
}
-
- ret = loadColours(colours);
+ ret = ColourSchemes.loadColourScheme(colours);
}
if (ret == null)
{
- Color[] newColours = new Color[24];
- for (int i = 0; i < 24; i++)
- {
- newColours[i] = Color.white;
- }
- ret = new UserColourScheme(newColours);
+ ret = new UserColourScheme("white");
}
return ret;
/**
* DOCUMENT ME!
*
- * @param file
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- static UserColourScheme loadColours(String file)
- {
- UserColourScheme ucs = null;
- Color[] newColours = null;
- try
- {
- InputStreamReader in = new InputStreamReader(
- new FileInputStream(file), "UTF-8");
-
- jalview.schemabinding.version2.JalviewUserColours jucs = new jalview.schemabinding.version2.JalviewUserColours();
-
- org.exolab.castor.xml.Unmarshaller unmar = new org.exolab.castor.xml.Unmarshaller(
- jucs);
- jucs = (jalview.schemabinding.version2.JalviewUserColours) unmar
- .unmarshal(in);
-
- newColours = new Color[24];
-
- Color[] lowerCase = null;
- boolean caseSensitive = false;
-
- String name;
- int index;
- for (int i = 0; i < jucs.getColourCount(); i++)
- {
- name = jucs.getColour(i).getName();
- if (ResidueProperties.aa3Hash.containsKey(name))
- {
- index = ResidueProperties.aa3Hash.get(name).intValue();
- }
- else
- {
- index = ResidueProperties.aaIndex[name.charAt(0)];
- }
- if (index == -1)
- {
- continue;
- }
-
- if (name.toLowerCase().equals(name))
- {
- if (lowerCase == null)
- {
- lowerCase = new Color[23];
- }
- caseSensitive = true;
- lowerCase[index] = new Color(Integer.parseInt(jucs.getColour(i)
- .getRGB(), 16));
- }
- else
- {
- newColours[index] = new Color(Integer.parseInt(jucs.getColour(i)
- .getRGB(), 16));
- }
- }
-
- if (newColours != null)
- {
- ucs = new UserColourScheme(newColours);
- ucs.setName(jucs.getSchemeName());
- if (caseSensitive)
- {
- ucs.setLowerCaseColours(lowerCase);
- }
- }
-
- } catch (Exception ex)
- {
- // Could be Archive Jalview format
- try
- {
- InputStreamReader in = new InputStreamReader(new FileInputStream(
- file), "UTF-8");
-
- jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();
-
- jucs = jucs.unmarshal(in);
-
- newColours = new Color[jucs.getColourCount()];
-
- for (int i = 0; i < 24; i++)
- {
- newColours[i] = new Color(Integer.parseInt(jucs.getColour(i)
- .getRGB(), 16));
- }
- if (newColours != null)
- {
- ucs = new UserColourScheme(newColours);
- ucs.setName(jucs.getSchemeName());
- }
- } catch (Exception ex2)
- {
- ex2.printStackTrace();
- }
-
- if (newColours == null)
- {
- System.out.println("Error loading User ColourFile\n" + ex);
- }
- }
-
- return ucs;
- }
-
- /**
- * DOCUMENT ME!
- *
* @param e
* DOCUMENT ME!
*/
@Override
protected void savebutton_actionPerformed(ActionEvent e)
{
- if (schemeName.getText().trim().length() < 1)
+ String name = schemeName.getText().trim();
+ if (name.length() < 1)
{
JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
.getString("label.user_colour_scheme_must_have_name"),
return;
}
- if (userColourSchemes != null
- && userColourSchemes.containsKey(schemeName.getText()))
+ if (ColourSchemes.getInstance().nameExists(name))
{
int reply = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
MessageManager.formatMessage(
"label.colour_scheme_exists_overwrite", new Object[] {
- schemeName.getText(), schemeName.getText() }),
+ name, name }),
MessageManager.getString("label.duplicate_scheme_name"),
JvOptionPane.YES_NO_OPTION);
if (reply != JvOptionPane.YES_OPTION)
{
return;
}
-
- userColourSchemes.remove(schemeName.getText());
+ ColourSchemes.getInstance().removeColourScheme(name);
}
- JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"), "jc",
+ JalviewFileChooser chooser = new JalviewFileChooser("jc",
"Jalview User Colours");
- chooser.setFileView(new JalviewFileView());
+ JalviewFileView fileView = new JalviewFileView();
+ chooser.setFileView(fileView);
chooser.setDialogTitle(MessageManager
.getString("label.save_colour_scheme"));
chooser.setToolTipText(MessageManager.getString("action.save"));
if (value == JalviewFileChooser.APPROVE_OPTION)
{
- String choice = chooser.getSelectedFile().getPath();
- String defaultColours = jalview.bin.Cache.getDefault(
- "USER_DEFINED_COLOURS", choice);
- if (defaultColours.indexOf(choice) == -1)
- {
- if (defaultColours.length() > 0)
- {
- defaultColours = defaultColours.concat("|");
- }
- defaultColours = defaultColours.concat(choice);
- }
-
- userColourSchemes.put(schemeName.getText(), getSchemeFromButtons());
-
- ap.alignFrame.updateUserColourMenu();
-
- jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS", defaultColours);
-
- jalview.schemabinding.version2.JalviewUserColours ucs = new jalview.schemabinding.version2.JalviewUserColours();
-
- ucs.setSchemeName(schemeName.getText());
- try
- {
- PrintWriter out = new PrintWriter(new OutputStreamWriter(
- new FileOutputStream(choice), "UTF-8"));
-
- for (int i = 0; i < buttonPanel.getComponentCount(); i++)
- {
- JButton button = (JButton) buttonPanel.getComponent(i);
- jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
- col.setName(button.getText());
- col.setRGB(jalview.util.Format.getHexString(button
- .getBackground()));
- ucs.addColour(col);
- }
-
- ucs.marshal(out);
- out.close();
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
+ File file = chooser.getSelectedFile();
+ addNewColourScheme(file.getPath());
+ saveToFile(file);
}
}
/**
- * DOCUMENT ME!
+ * Adds the current colour scheme to the Jalview properties file so it is
+ * loaded on next startup, and updates the Colour menu in the parent
+ * AlignFrame (if there is one). Note this action does not including applying
+ * the colour scheme.
*
- * @param e
- * DOCUMENT ME!
+ * @param filePath
*/
- @Override
- protected void cancelButton_actionPerformed(ActionEvent e)
+ protected void addNewColourScheme(String filePath)
{
- if (ap != null)
+ /*
+ * update the delimited list of user defined colour files in
+ * Jalview property USER_DEFINED_COLOURS
+ */
+ String defaultColours = Cache
+ .getDefault(USER_DEFINED_COLOURS, filePath);
+ if (defaultColours.indexOf(filePath) == -1)
{
- if (seqGroup != null)
- {
- seqGroup.cs = oldColourScheme;
- }
- else if (ap != null)
+ if (defaultColours.length() > 0)
{
- ap.av.setGlobalColourScheme(oldColourScheme);
+ defaultColours = defaultColours.concat("|");
}
- ap.paintAlignment(true);
+ defaultColours = defaultColours.concat(filePath);
}
+ Cache.setProperty(USER_DEFINED_COLOURS, defaultColours);
- if (jmol != null)
- {
- jmol.setJalviewColourScheme(oldColourScheme);
- }
+ /*
+ * construct and register the colour scheme
+ */
+ UserColourScheme ucs = getSchemeFromButtons();
+ ColourSchemes.getInstance().registerColourScheme(ucs);
- try
- {
- frame.setClosed(true);
- } catch (Exception ex)
+ /*
+ * update the Colour menu items
+ */
+ if (ap != null)
{
+ ap.alignFrame.buildColourMenu();
}
}
- static Hashtable userColourSchemes;
-
- public static Hashtable getUserColourSchemes()
- {
- return userColourSchemes;
- }
-
- public static void initUserColourSchemes(String files)
+ /**
+ * Saves the colour scheme to file in XML format
+ *
+ * @param path
+ */
+ protected void saveToFile(File toFile)
{
- userColourSchemes = new Hashtable();
-
- if (files == null || files.length() == 0)
+ /*
+ * build a Java model of colour scheme as XML, and
+ * marshal to file
+ */
+ JalviewUserColours ucs = new JalviewUserColours();
+ ucs.setSchemeName(schemeName.getText());
+ try
{
- return;
- }
+ PrintWriter out = new PrintWriter(new OutputStreamWriter(
+ new FileOutputStream(toFile), "UTF-8"));
- // In case colours can't be loaded, we'll remove them
- // from the default list here.
- StringBuffer coloursFound = new StringBuffer();
- StringTokenizer st = new StringTokenizer(files, "|");
- while (st.hasMoreElements())
- {
- String file = st.nextToken();
- try
- {
- UserColourScheme ucs = loadColours(file);
- if (ucs != null)
- {
- if (coloursFound.length() > 0)
- {
- coloursFound.append("|");
- }
- coloursFound.append(file);
- userColourSchemes.put(ucs.getName(), ucs);
- }
- } catch (Exception ex)
+ for (int i = 0; i < buttonPanel.getComponentCount(); i++)
{
- System.out.println("Error loading User ColourFile\n" + ex);
+ JButton button = (JButton) buttonPanel.getComponent(i);
+ Colour col = new Colour();
+ col.setName(button.getText());
+ col.setRGB(Format.getHexString(button.getBackground()));
+ ucs.addColour(col);
}
- }
- if (!files.equals(coloursFound.toString()))
+ ucs.marshal(out);
+ out.close();
+ } catch (Exception ex)
{
- if (coloursFound.toString().length() > 1)
- {
- jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",
- coloursFound.toString());
- }
- else
- {
- jalview.bin.Cache.applicationProperties
- .remove("USER_DEFINED_COLOURS");
- }
+ ex.printStackTrace();
}
}
- public static void removeColourFromDefaults(String target)
+ /**
+ * On cancel, restores the colour scheme before the dialogue was opened
+ *
+ * @param e
+ */
+ @Override
+ protected void cancelButton_actionPerformed(ActionEvent e)
{
- // The only way to find colours by name is to load them in
- // In case colours can't be loaded, we'll remove them
- // from the default list here.
-
- userColourSchemes = new Hashtable();
-
- StringBuffer coloursFound = new StringBuffer();
- StringTokenizer st = new StringTokenizer(
- jalview.bin.Cache.getProperty("USER_DEFINED_COLOURS"), "|");
-
- while (st.hasMoreElements())
+ if (ap != null)
{
- String file = st.nextToken();
- try
+ if (seqGroup != null)
{
- UserColourScheme ucs = loadColours(file);
- if (ucs != null && !ucs.getName().equals(target))
- {
- if (coloursFound.length() > 0)
- {
- coloursFound.append("|");
- }
- coloursFound.append(file);
- userColourSchemes.put(ucs.getName(), ucs);
- }
- } catch (Exception ex)
+ seqGroup.setColourScheme(oldColourScheme);
+ }
+ else
{
- System.out.println("Error loading User ColourFile\n" + ex);
+ ap.alignFrame.changeColour(oldColourScheme);
}
+ ap.paintAlignment(true);
}
- if (coloursFound.toString().length() > 1)
+ if (structureViewer != null)
{
- jalview.bin.Cache.setProperty("USER_DEFINED_COLOURS",
- coloursFound.toString());
+ structureViewer.setJalviewColourScheme(oldColourScheme);
}
- else
+
+ try
+ {
+ frame.setClosed(true);
+ } catch (Exception ex)
{
- jalview.bin.Cache.applicationProperties
- .remove("USER_DEFINED_COLOURS");
}
-
}
@Override
public void caseSensitive_actionPerformed(ActionEvent e)
{
- resetButtonPanel(caseSensitive.isSelected());
- lcaseColour.setEnabled(caseSensitive.isSelected());
- }
-
- @Override
- public void lcaseColour_actionPerformed(ActionEvent e)
- {
- if (selectedButtons == null)
- {
- selectedButtons = new ArrayList<JButton>();
- }
- else
- {
- selectedButtons.clear();
- }
- selectedButtons.add(lcaseColour);
+ boolean selected = caseSensitive.isSelected();
+ resetButtonPanel(selected);
+ lcaseColour.setEnabled(selected);
}
}
}
if (filename == null)
{
- JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"), "wsparams",
+ JalviewFileChooser chooser = new JalviewFileChooser("wsparams",
"Web Service Parameter File");
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager
JTextField urltf = new JTextField(url, 40);
JPanel panel = new JPanel(new BorderLayout());
JPanel pane12 = new JPanel(new BorderLayout());
- pane12.add(new JLabel(MessageManager.getString("label.url")),
+ pane12.add(new JLabel(MessageManager.getString("label.url:")),
BorderLayout.CENTER);
pane12.add(urltf, BorderLayout.EAST);
panel.add(pane12, BorderLayout.NORTH);
new Thread(new Runnable()
{
+ @Override
public void run()
{
// force a refresh.
new Thread(new Runnable()
{
+ @Override
public void run()
{
progressBar.setVisible(true);
new Thread(new Runnable()
{
+ @Override
public void run()
{
long ct = System.currentTimeMillis();
new Thread(new Runnable()
{
+ @Override
public void run()
{
updateWsMenuConfig(false);
* @author $author$
* @version $Revision$
*/
-public abstract class AlignFile extends FileParse implements AlignmentFileI
+public abstract class AlignFile extends FileParse implements
+ AlignmentFileReaderI, AlignmentFileWriterI
{
int noSeqs = 0;
}
}
+ protected void addSequence(SequenceI seq)
+ {
+ seqs.add(seq);
+ }
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
-public interface AlignmentFileI
+public interface AlignmentFileReaderI
{
SequenceI[] getSeqsAsArray();
void addGroups(AlignmentI al);
- void setNewlineString(String newline);
-
- void setExportSettings(AlignExportSettingI exportSettings);
-
- void configureForView(AlignmentViewPanel viewpanel);
-
void setSeqs(SequenceI[] sequencesArray);
- String print(SequenceI[] seqs, boolean jvsuffix);
-
boolean hasWarningMessage();
String getWarningMessage();
--- /dev/null
+package jalview.io;
+
+import jalview.api.AlignExportSettingI;
+import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureSettingsModelI;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+
+public interface AlignmentFileWriterI
+{
+
+ void setNewlineString(String newline);
+
+ void setExportSettings(AlignExportSettingI exportSettings);
+
+ void configureForView(AlignmentViewPanel viewpanel);
+
+ String print(SequenceI[] seqs, boolean jvsuffix);
+
+ boolean hasWarningMessage();
+
+ String getWarningMessage();
+
+}
import jalview.gui.Desktop;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.UserColourScheme;
import jalview.structure.StructureSelectionManager;
+import jalview.util.ColorUtils;
+import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
if (sg.cs != null)
{
text.append("colour=");
- text.append(ColourSchemeProperty.getColourName(sg.cs));
+ text.append(sg.cs.toString());
text.append("\t");
if (sg.cs.getThreshold() != 0)
{
Annotation parseAnnotation(String string, int graphStyle)
{
- boolean hasSymbols = (graphStyle == AlignmentAnnotation.NO_GRAPH); // don't
- // do the
- // glyph
- // test
- // if we
- // don't
- // want
- // secondary
- // structure
+ // don't do the glyph test if we don't want secondary structure
+ boolean hasSymbols = (graphStyle == AlignmentAnnotation.NO_GRAPH);
String desc = null, displayChar = null;
char ss = ' '; // secondaryStructure
float value = 0;
boolean parsedValue = false, dcset = false;
// find colour here
- java.awt.Color colour = null;
+ Color colour = null;
int i = string.indexOf("[");
int j = string.indexOf("]");
if (i > -1 && j > -1)
{
- UserColourScheme ucs = new UserColourScheme();
-
- colour = ucs.getColourFromString(string.substring(i + 1, j));
+ colour = ColorUtils.parseColourString(string.substring(i + 1,
+ j));
if (i > 0 && string.charAt(i - 1) == ',')
{
// clip the preceding comma as well
void colourAnnotations(AlignmentI al, String label, String colour)
{
- UserColourScheme ucs = new UserColourScheme(colour);
+ Color awtColour = ColorUtils.parseColourString(colour);
Annotation[] annotations;
for (int i = 0; i < al.getAlignmentAnnotation().length; i++)
{
{
if (annotations[j] != null)
{
- annotations[j].colour = ucs.findColour('A');
+ annotations[j].colour = awtColour;
}
}
}
SequenceGroup groupRef)
{
String group = st.nextToken();
- AlignmentAnnotation annotation = null, alannot[] = al
- .getAlignmentAnnotation();
- float value = new Float(st.nextToken()).floatValue();
+ AlignmentAnnotation[] alannot = al.getAlignmentAnnotation();
+ String nextToken = st.nextToken();
+ float value = 0f;
+ try
+ {
+ value = Float.valueOf(nextToken);
+ } catch (NumberFormatException e)
+ {
+ System.err.println("line " + nlinesread + ": Threshold '" + nextToken
+ + "' invalid, setting to zero");
+ }
String label = st.hasMoreTokens() ? st.nextToken() : null;
- java.awt.Color colour = null;
+ Color colour = null;
if (st.hasMoreTokens())
{
- UserColourScheme ucs = new UserColourScheme(st.nextToken());
- colour = ucs.findColour('A');
+ colour = ColorUtils.parseColourString(st.nextToken());
}
if (alannot != null)
{
}
}
}
- if (annotation == null)
- {
- return;
- }
}
void addGroup(AlignmentI al, StringTokenizer st)
if (sg != null)
{
String keyValue, key, value;
- ColourSchemeI def = sg.cs;
- sg.cs = null;
+ ColourSchemeI def = sg.getColourScheme();
while (st.hasMoreTokens())
{
keyValue = st.nextToken();
}
else if (key.equalsIgnoreCase("colour"))
{
- sg.cs = ColourSchemeProperty.getColour(al, value);
+ sg.cs.setColourScheme(ColourSchemeProperty
+ .getColourScheme(al, value));
}
else if (key.equalsIgnoreCase("pidThreshold"))
{
}
else if (key.equalsIgnoreCase("outlineColour"))
{
- sg.setOutlineColour(new UserColourScheme(value).findColour('A'));
+ sg.setOutlineColour(ColorUtils.parseColourString(value));
}
else if (key.equalsIgnoreCase("displayBoxes"))
{
}
else if (key.equalsIgnoreCase("textCol1"))
{
- sg.textColour = new UserColourScheme(value).findColour('A');
+ sg.textColour = ColorUtils.parseColourString(value);
}
else if (key.equalsIgnoreCase("textCol2"))
{
- sg.textColour2 = new UserColourScheme(value).findColour('A');
+ sg.textColour2 = ColorUtils.parseColourString(value);
}
else if (key.equalsIgnoreCase("textColThreshold"))
{
}
else if (key.equalsIgnoreCase("idColour"))
{
- // consider warning if colour doesn't resolve to a real colour
- sg.setIdColour((def = new UserColourScheme(value))
- .findColour('A'));
+ Color idColour = ColorUtils.parseColourString(value);
+ sg.setIdColour(idColour == null ? Color.black : idColour);
}
else if (key.equalsIgnoreCase("hide"))
{
}
sg.recalcConservation();
}
- if (sg.cs == null)
+ if (sg.getColourScheme() == null)
{
- sg.cs = def;
+ sg.setColourScheme(def);
}
}
}
*/
boolean serviceSecondaryStruct = false;
- private AlignmentFileI alignFile = null;
+ private AlignmentFileReaderI alignFile = null;
String inFile;
public static String INVALID_CHARACTERS = "Contains invalid characters";
- public static String SUPPORTED_FORMATS = "Formats currently supported are\n"
- + prettyPrint(FileFormat.getReadableFormats());
-
+ /**
+ * Returns an error message with a list of supported readable file formats
+ *
+ * @return
+ */
+ public static String getSupportedFormats()
+ {
+ return "Formats currently supported are\n"
+ + prettyPrint(FileFormats.getInstance().getReadableFormats());
+ }
public AppletFormatAdapter()
{
}
}
else
{
- // todo is MCview parsing obsolete yet?
+ // todo is MCview parsing obsolete yet? JAL-2120
StructureImportSettings.setShowSeqFeatures(true);
alignFile = new MCview.PDBfile(annotFromStructure,
localSecondaryStruct, serviceSecondaryStruct, inFile,
}
else
{
- alignFile = fileFormat.getAlignmentFile(inFile, sourceType);
+ // alignFile = fileFormat.getAlignmentFile(inFile, sourceType);
+ alignFile = fileFormat.getReader(new FileParse(inFile,
+ sourceType));
}
return buildAlignmentFromFile();
} catch (Exception e)
throw new IOException(e.getMessage());
}
}
- throw new FileFormatException(SUPPORTED_FORMATS);
+ throw new FileFormatException(getSupportedFormats());
}
/**
}
else
{
- alignFile = format.getAlignmentFile(source);
+ alignFile = format.getReader(source);
}
return buildAlignmentFromFile();
}
// If we get to this stage, the format was not supported
- throw new FileFormatException(SUPPORTED_FORMATS);
+ throw new FileFormatException(getSupportedFormats());
}
}
{
try
{
- AlignmentFileI afile = format.getAlignmentFile(alignment);
+ AlignmentFileWriterI afile = format.getWriter(alignment);
afile.setNewlineString(newline);
afile.setExportSettings(exportSettings);
return afileresp;
} catch (Exception e)
{
- System.err.println("Failed to write alignment as a '" + format
+ System.err.println("Failed to write alignment as a '"
+ + format.getName()
+ "' file\n");
e.printStackTrace();
}
return null;
}
- public AlignmentFileI getAlignFile()
+ public AlignmentFileReaderI getAlignFile()
{
return alignFile;
}
import jalview.io.gff.GffHelperFactory;
import jalview.io.gff.GffHelperI;
import jalview.schemes.FeatureColour;
-import jalview.schemes.UserColourScheme;
+import jalview.util.ColorUtils;
import jalview.util.MapList;
import jalview.util.ParseHtmlBodyAndLinks;
import jalview.util.StringUtils;
+import java.awt.Color;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
* Perhaps an old style groups file with no colours -
* synthesize a colour from the feature type
*/
- UserColourScheme ucs = new UserColourScheme(ft);
- featureColours.put(ft, new FeatureColour(ucs.findColour('A')));
+ Color colour = ColorUtils.createColourFromName(ft);
+ featureColours.put(ft, new FeatureColour(colour));
}
SequenceFeature sf = new SequenceFeature(ft, desc, "", startPos,
endPos, featureGroup);
import jalview.structure.StructureImportSettings;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
public enum FileFormat implements FileFormatI
{
Fasta("Fasta", "fa, fasta, mfa, fastq", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new FastaFile(inFile, sourceType);
- }
-
- @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new FastaFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new FastaFile();
}
Pfam("PFAM", "pfam", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new PfamFile(inFile, sourceType);
- }
-
- @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new PfamFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new PfamFile();
}
Stockholm("Stockholm", "sto,stk", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new StockholmFile(inFile, sourceType);
- }
- @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new StockholmFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new StockholmFile(al);
}
PIR("PIR", "pir", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new PIRFile(inFile, sourceType);
- }
- @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new PIRFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new PIRFile();
}
BLC("BLC", "BLC", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new BLCFile(inFile, sourceType);
- } @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new BLCFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new BLCFile();
}
AMSA("AMSA", "amsa", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new AMSAFile(inFile, sourceType);
- }
-
- @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new AMSAFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new AMSAFile(al);
}
Html("HTML", "html", true, false)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new HtmlFile(inFile, sourceType);
- } @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new HtmlFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new HtmlFile();
}
Rnaml("RNAML", "xml,rnaml", true, false)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new RnamlFile(inFile, sourceType);
- } @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new RnamlFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new RnamlFile();
}
},
- Json("JSON","json", true, true)
+ Json("JSON", "json", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new JSONFile(inFile, sourceType);
- } @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new JSONFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new JSONFile();
}
Pileup("PileUp", "pileup", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new PileUpfile(inFile, sourceType);
- } @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new PileUpfile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new PileUpfile();
}
MSF("MSF", "msf", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new MSFfile(inFile, sourceType);
- } @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new MSFfile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new MSFfile();
}
Clustal("Clustal", "aln", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new ClustalFile(inFile, sourceType);
- } @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new ClustalFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new ClustalFile();
}
Phylip("PHYLIP", "phy", true, true)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new PhylipFile(inFile, sourceType);
- }
-
- @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new PhylipFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new PhylipFile();
}
Jnet("JnetFile", "", false, false)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- JPredFile af = new JPredFile(inFile, sourceType);
- af.removeNonSequences();
- return af;
- }
-
- @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
JPredFile af = new JPredFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return null; // todo is this called?
}
Features("GFF or Jalview features", "gff2,gff3", true, false)
{
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new FeaturesFile(true, inFile, sourceType);
- }
-
- @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new FeaturesFile(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new FeaturesFile();
}
},
PDB("PDB", "pdb,ent", true, false)
{
-
- @Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- // TODO obtain config value from preference settings.
- // Set value to 'true' to test PDB processing with Jmol: JAL-1213
- boolean isParseWithJMOL = StructureImportSettings
- .getDefaultStructureFileFormat() != PDBEntry.Type.PDB;
- if (isParseWithJMOL)
- {
- return new JmolParser(inFile, sourceType);
- }
- else
- {
- StructureImportSettings.setShowSeqFeatures(true);
- return new MCview.PDBfile(
- StructureImportSettings.isVisibleChainAnnotation(),
- StructureImportSettings.isProcessSecondaryStructure(),
- StructureImportSettings.isExternalSecondaryStructure(),
- inFile,
- sourceType);
- }
- }
-
@Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
boolean isParseWithJMOL = StructureImportSettings
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new JmolParser(); // todo or null?
}
},
MMCif("mmCIF", "cif", true, false)
{
-
- @Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return new JmolParser(inFile, sourceType);
- }
-
@Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return new JmolParser(source);
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return new JmolParser(); // todo or null?
}
},
Jalview("Jalview", "jar,jvp", true, true)
{
-
@Override
- public AlignmentFileI getAlignmentFile(String inFile,
- DataSourceType sourceType) throws IOException
- {
- return null;
- }
-
- @Override
- public AlignmentFileI getAlignmentFile(FileParse source)
+ public AlignmentFileReaderI getReader(FileParse source)
throws IOException
{
return null;
}
@Override
- public AlignmentFileI getAlignmentFile(AlignmentI al)
+ public AlignmentFileWriterI getWriter(AlignmentI al)
{
return null;
}
{
return false;
}
- };
- /**
- * A lookup map of enums by upper-cased name
- */
- private static Map<String, FileFormat> names;
- static
- {
- names = new HashMap<String, FileFormat>();
- for (FileFormat format : FileFormat.values())
+ @Override
+ public boolean isIdentifiable()
{
- names.put(format.toString().toUpperCase(), format);
+ return false;
}
- }
+ };
private boolean writable;
private String name;
- /**
- * Answers a list of writeable file formats (as string, corresponding to the
- * toString() and forName() methods)
- *
- * @return
- */
- public static List<String> getWritableFormats(boolean textOnly)
- {
- List<String> l = new ArrayList<String>();
- for (FileFormatI ff : values())
- {
- if (ff.isWritable() && (!textOnly || ff.isTextFormat()))
- {
- l.add(ff.toString());
- }
- }
- return l;
- }
-
- /**
- * Answers a list of readable file formats (as string, corresponding to the
- * toString() and forName() methods)
- *
- * @return
- */
- public static List<String> getReadableFormats()
- {
- List<String> l = new ArrayList<String>();
- for (FileFormatI ff : values())
- {
- if (ff.isReadable())
- {
- l.add(ff.toString());
- }
- }
- return l;
- }
-
@Override
public boolean isComplexAlignFile()
{
return false;
}
- /**
- * Returns the file format with the given name, or null if format is null or
- * invalid. Unlike valueOf(), this is not case-sensitive, to be kind to
- * writers of javascript.
- *
- * @param format
- * @return
- */
- public static FileFormatI forName(String format)
- {
- // or could store format.getShortDescription().toUpperCase()
- // in order to decouple 'given name' from enum name
- return format == null ? null : names.get(format.toUpperCase());
- }
-
@Override
public boolean isReadable()
{
return extensions;
}
+ /**
+ * Answers the display name of the file format (as for example shown in menu
+ * options). This name should not be locale (language) dependent.
+ */
@Override
- public String toString()
+ public String getName()
{
return name;
}
@Override
- public AlignmentFileI getAlignmentFile()
- {
- return getAlignmentFile((AlignmentI) null);
- }
-
- @Override
public boolean isTextFormat()
{
return true;
{
return false;
}
+
+ /**
+ * By default, answers true, indicating the format is one that can be
+ * identified by IdentifyFile. Formats that cannot be identified should
+ * override this method to return false.
+ */
+ public boolean isIdentifiable()
+ {
+ return true;
+ }
}
public interface FileFormatI
{
+ AlignmentFileReaderI getReader(FileParse source) throws IOException;
- AlignmentFileI getAlignmentFile(String inFile, DataSourceType sourceType)
- throws IOException;
-
- // TODO can we get rid of one of these methods?
- AlignmentFileI getAlignmentFile(FileParse source) throws IOException;
-
- AlignmentFileI getAlignmentFile(AlignmentI al);
-
- AlignmentFileI getAlignmentFile();
+ AlignmentFileWriterI getWriter(AlignmentI al);
boolean isComplexAlignFile();
/**
+ * Answers the display name of the file format (as for example shown in menu
+ * options). This name should not be locale (language) dependent.
+ */
+ String getName();
+
+ /**
* Returns a comma-separated list of file extensions associated with the
* format
*
/**
* Answers true if the format is one that Jalview can read. This implies that
- * the format provides implementations for getAlignmentFile(FileParse) and
- * getAlignmentFile(String, DataSourceType) which parse the data source for
- * sequence data.
+ * the format provides an implementation for getReader which can parse a data
+ * source for sequence data. Readable formats are included in the options in
+ * the open file dialogue.
*
* @return
*/
/**
* Answers true if the format is one that Jalview can write. This implies that
- * the object returned by getAlignmentFile provides an implementation of the
- * print() method.
+ * the object returned by getWriter provides an implementation of the print()
+ * method. Writable formats are included in the options in the Save As file
+ * dialogue, and the 'output to Textbox' option (if text format).
*
* @return
*/
boolean isTextFormat();
/**
- * Answers true if the file format is one that provides a 3D structure
+ * Answers true if the file format is one that provides 3D structure data
*
* @return
*/
--- /dev/null
+package jalview.io;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A singleton registry of alignment file formats known to Jalview. On startup,
+ * the 'built-in' formats are added (from the FileFormat enum). Additional
+ * formats can be registered (or formats deregistered) programmatically, for
+ * example with a Groovy script.
+ *
+ * @author gmcarstairs
+ *
+ */
+public class FileFormats
+{
+ private static FileFormats instance = new FileFormats();
+
+ /*
+ * A lookup map of file formats by upper-cased name
+ */
+ private static Map<String, FileFormatI> formats;
+
+ /*
+ * Formats in this set are capable of being identified by IdentifyFile
+ */
+ private static Set<FileFormatI> identifiable;
+
+ public static FileFormats getInstance()
+ {
+ return instance;
+ }
+
+ /**
+ * Private constructor registers Jalview's built-in file formats
+ */
+ private FileFormats()
+ {
+ reset();
+ }
+
+ /**
+ * Reset to just the built-in file formats packaged with Jalview. These are
+ * added (and will be shown in menus) in the order of their declaration in the
+ * FileFormat enum.
+ */
+ public synchronized void reset()
+ {
+ formats = new LinkedHashMap<String, FileFormatI>();
+ identifiable = new HashSet<FileFormatI>();
+ for (FileFormat format : FileFormat.values())
+ {
+ registerFileFormat(format, format.isIdentifiable());
+ }
+ }
+
+ /**
+ * Answers true if the format is one that can be identified by IdentifyFile.
+ * Answers false for a null value.
+ */
+ public boolean isIdentifiable(FileFormatI f)
+ {
+ return identifiable.contains(f);
+ }
+
+ /**
+ * Registers a file format for case-insensitive lookup by name
+ *
+ * @param format
+ */
+ public void registerFileFormat(FileFormatI format)
+ {
+ boolean isIdentifiable = format instanceof FileFormat
+ && ((FileFormat) format).isIdentifiable();
+ registerFileFormat(format, isIdentifiable);
+ }
+
+ protected void registerFileFormat(FileFormatI format,
+ boolean isIdentifiable)
+ {
+ String name = format.getName().toUpperCase();
+ if (formats.containsKey(name))
+ {
+ System.err.println("Overwriting file format: " + format.getName());
+ }
+ formats.put(name, format);
+ if (isIdentifiable)
+ {
+ identifiable.add(format);
+ }
+ }
+
+ /**
+ * Deregisters a file format so it is no longer shown in menus
+ *
+ * @param name
+ */
+ public void deregisterFileFormat(String name)
+ {
+ FileFormatI ff = formats.remove(name.toUpperCase());
+ identifiable.remove(ff);
+ }
+
+ /**
+ * Answers a list of writeable file formats (as strings, corresponding to the
+ * getName() and forName() methods)
+ *
+ * @param textOnly
+ * if true, only text (not binary) formats are included
+ * @return
+ */
+ public List<String> getWritableFormats(boolean textOnly)
+ {
+ List<String> l = new ArrayList<String>();
+ for (FileFormatI ff : formats.values())
+ {
+ if (ff.isWritable() && (!textOnly || ff.isTextFormat()))
+ {
+ l.add(ff.getName());
+ }
+ }
+ return l;
+ }
+
+ /**
+ * Answers a list of readable file formats (as strings, corresponding to the
+ * getName() and forName() methods)
+ *
+ * @return
+ */
+ public List<String> getReadableFormats()
+ {
+ List<String> l = new ArrayList<String>();
+ for (FileFormatI ff : formats.values())
+ {
+ if (ff.isReadable())
+ {
+ l.add(ff.getName());
+ }
+ }
+ return l;
+ }
+
+ /**
+ * Returns the file format with the given name, or null if format is null or
+ * invalid. This is not case-sensitive.
+ *
+ * @param format
+ * @return
+ */
+ public FileFormatI forName(String format)
+ {
+ return format == null ? null : formats.get(format.toUpperCase());
+ }
+
+ /**
+ * Returns an iterable collection of registered file formats (in the order in
+ * which they were registered)
+ *
+ * @return
+ */
+ public Iterable<FileFormatI> getFormats()
+ {
+ return formats.values();
+ }
+}
FileFormatI format;
- AlignmentFileI source = null; // alternative specification of where data comes
+ AlignmentFileReaderI source = null; // alternative specification of where data
+ // comes
// from
* @param format
* @return alignFrame constructed from file contents
*/
- public AlignFrame LoadFileWaitTillLoaded(AlignmentFileI source,
+ public AlignFrame LoadFileWaitTillLoaded(AlignmentFileReaderI source,
FileFormatI format)
{
this.source = source;
if (protocol == DataSourceType.FILE)
{
- Cache.setProperty("DEFAULT_FILE_FORMAT", format.toString());
+ Cache.setProperty("DEFAULT_FILE_FORMAT", format.getName());
}
}
Desktop.desktop,
MessageManager.getString("label.couldnt_read_data")
+ " in " + file + "\n"
- + AppletFormatAdapter.SUPPORTED_FORMATS,
+ + AppletFormatAdapter.getSupportedFormats(),
MessageManager.getString("label.couldnt_read_data"),
JvOptionPane.WARNING_MESSAGE);
}
}
else
{
- String error = AppletFormatAdapter.SUPPORTED_FORMATS;
- try
+ String error = AppletFormatAdapter.getSupportedFormats();
+ try
+ {
+ if (source != null)
{
- if (source != null)
- {
- // read from the provided source
+ // read from the provided source
al = new FormatAdapter().readFromFile(source, format);
- }
- else
- {
-
- // open a new source and read from it
- FormatAdapter fa = new FormatAdapter();
- al = fa.readFile(file, protocol, format);
- source = fa.getAlignFile(); // keep reference for later if
- // necessary.
- }
- } catch (java.io.IOException ex)
+ }
+ else
{
- error = ex.getMessage();
+
+ // open a new source and read from it
+ FormatAdapter fa = new FormatAdapter();
+ al = fa.readFile(file, protocol, format);
+ source = fa.getAlignFile(); // keep reference for later if
+ // necessary.
}
+ } catch (java.io.IOException ex)
+ {
+ error = ex.getMessage();
+ }
if ((al != null) && (al.getHeight() > 0) && al.hasValidSequence())
{
*/
public String formatSequences(FileFormatI format, SequenceI[] seqs)
{
- //
- // try
- // {
boolean withSuffix = getCacheSuffixDefault(format);
- return format.getAlignmentFile().print(seqs, withSuffix);
- // null;
- //
- // if (format.equalsIgnoreCase("FASTA"))
- // {
- // afile = new FastaFile();
- // afile.addJVSuffix(jalview.bin.Cache.getDefault("FASTA_JVSUFFIX",
- // true));
- // }
- // else if (format.equalsIgnoreCase("MSF"))
- // {
- // afile = new MSFfile();
- // afile.addJVSuffix(jalview.bin.Cache
- // .getDefault("MSF_JVSUFFIX", true));
- // }
- // else if (format.equalsIgnoreCase("PileUp"))
- // {
- // afile = new PileUpfile();
- // afile.addJVSuffix(jalview.bin.Cache.getDefault("PILEUP_JVSUFFIX",
- // true));
- // }
- // else if (format.equalsIgnoreCase("CLUSTAL"))
- // {
- // afile = new ClustalFile();
- // afile.addJVSuffix(jalview.bin.Cache.getDefault("CLUSTAL_JVSUFFIX",
- // true));
- // }
- // else if (format.equalsIgnoreCase("BLC"))
- // {
- // afile = new BLCFile();
- // afile.addJVSuffix(jalview.bin.Cache
- // .getDefault("BLC_JVSUFFIX", true));
- // }
- // else if (format.equalsIgnoreCase("PIR"))
- // {
- // afile = new PIRFile();
- // afile.addJVSuffix(jalview.bin.Cache
- // .getDefault("PIR_JVSUFFIX", true));
- // }
- // else if (format.equalsIgnoreCase("PFAM"))
- // {
- // afile = new PfamFile();
- // afile.addJVSuffix(jalview.bin.Cache.getDefault("PFAM_JVSUFFIX",
- // true));
- // }
- // /*
- // * amsa is not supported by this function - it requires an alignment
- // * rather than a sequence vector else if
- // (format.equalsIgnoreCase("AMSA"))
- // * { afile = new AMSAFile(); afile.addJVSuffix(
- // * jalview.bin.Cache.getDefault("AMSA_JVSUFFIX", true)); }
- // */
-
-// afile.setSeqs(seqs);
-// String afileresp = afile.print();
-// if (afile.hasWarningMessage())
-// {
-// System.err.println("Warning raised when writing as " + format
-// + " : " + afile.getWarningMessage());
-// }
-// return afileresp;
-// } catch (Exception e)
-// {
-// System.err.println("Failed to write alignment as a '" + format
-// + "' file\n");
-// e.printStackTrace();
-// }
-//
-// return null;
+ return format.getWriter(null).print(seqs, withSuffix);
}
public boolean getCacheSuffixDefault(FileFormatI format)
{
- return Cache.getDefault(format.toString() + "_JVSUFFIX", true);
+ return Cache.getDefault(format.getName() + "_JVSUFFIX", true);
}
public String formatSequences(FileFormatI format, AlignmentI alignment,
selectedOnly);
}
- public AlignmentI readFromFile(AlignmentFileI source, FileFormatI format)
- throws IOException
+ public AlignmentI readFromFile(AlignmentFileReaderI source,
+ FileFormatI format) throws IOException
{
FileParse fp = new FileParse(source.getInFile(),
source.getDataSourceType());
package jalview.io;
import jalview.api.AlignExportSettingI;
-import jalview.bin.Cache;
import jalview.datamodel.AlignmentExportData;
import jalview.exceptions.NoFileSelectedException;
import jalview.gui.AlignmentPanel;
pSessionId);
}
- JalviewFileChooser jvFileChooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"), "html", "HTML files");
+ JalviewFileChooser jvFileChooser = new JalviewFileChooser("html",
+ "HTML files");
jvFileChooser.setFileView(new JalviewFileView());
jvFileChooser.setDialogTitle(MessageManager
// preserves original behaviour prior to version 2.3
}
- public FileFormatI identify(AlignmentFileI file, boolean closeSource)
+ public FileFormatI identify(AlignmentFileReaderI file, boolean closeSource)
throws IOException
{
FileParse fp = new FileParse(file.getInFile(), file.getDataSourceType());
import jalview.json.binding.biojson.v1.SequenceFeaturesPojo;
import jalview.json.binding.biojson.v1.SequenceGrpPojo;
import jalview.json.binding.biojson.v1.SequencePojo;
-import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.UserColourScheme;
+import jalview.schemes.JalviewColourScheme;
+import jalview.schemes.ResidueColourScheme;
+import jalview.util.ColorUtils;
import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
import java.awt.Color;
{
// These color schemes require annotation, disable them if annotations
// are not exported
- if (globalColourScheme.equalsIgnoreCase("RNA Helices")
- || globalColourScheme.equalsIgnoreCase("T-COFFEE SCORES"))
+ if (globalColourScheme
+ .equalsIgnoreCase(JalviewColourScheme.RNAHelices.toString())
+ || globalColourScheme
+ .equalsIgnoreCase(JalviewColourScheme.TCoffee
+ .toString()))
{
- jsonAlignmentPojo.setGlobalColorScheme("None");
+ jsonAlignmentPojo.setGlobalColorScheme(ResidueColourScheme.NONE);
}
}
{
SequenceGrpPojo seqGrpPojo = new SequenceGrpPojo();
seqGrpPojo.setGroupName(seqGrp.getName());
- seqGrpPojo.setColourScheme(ColourSchemeProperty
- .getColourName(seqGrp.cs));
+ seqGrpPojo.setColourScheme(seqGrp.getColourScheme()
+ .getSchemeName());
seqGrpPojo.setColourText(seqGrp.getColourText());
seqGrpPojo.setDescription(seqGrp.getDescription());
seqGrpPojo.setDisplayBoxes(seqGrp.getDisplayBoxes());
}
SequenceGroup seqGrp = new SequenceGroup(grpSeqs, grpName, null,
displayBoxes, displayText, colourText, startRes, endRes);
- seqGrp.cs = ColourSchemeMapper.getJalviewColourScheme(colourScheme,
- seqGrp);
+ seqGrp.setColourScheme(ColourSchemeMapper.getJalviewColourScheme(
+ colourScheme, seqGrp));
seqGrp.setShowNonconserved(showNonconserved);
seqGrp.setDescription(description);
this.seqGroups.add(seqGrp);
annotations[count] = new Annotation(displayChar, desc, ss, val);
if (annot.get("colour") != null)
{
- Color color = UserColourScheme.getColourFromString(annot.get(
+ Color color = ColorUtils.parseColourString(annot.get(
"colour").toString());
annotations[count].colour = color;
}
}
}
}
- globalColourScheme = ColourSchemeProperty.getColourName(viewport
- .getGlobalColourScheme());
+ globalColourScheme = viewport.getGlobalColourScheme().getSchemeName();
setDisplayedFeatures(viewport.getFeaturesDisplayed());
showSeqFeatures = viewport.isShowSequenceFeatures();
//////////////////////////////////////////////////////////////////
package jalview.io;
+import jalview.bin.Cache;
import jalview.gui.JvOptionPane;
import jalview.util.MessageManager;
import jalview.util.Platform;
{
List<String> extensions = new ArrayList<String>();
List<String> descs = new ArrayList<String>();
- for (FileFormatI format : FileFormat.values())
+ for (FileFormatI format : FileFormats.getInstance().getFormats())
{
if (format.isReadable())
{
extensions.add(format.getExtensions());
- descs.add(format.toString());
+ descs.add(format.getName());
}
}
return new JalviewFileChooser(directory,
// with a lambda expression parameter for isReadable/isWritable
List<String> extensions = new ArrayList<String>();
List<String> descs = new ArrayList<String>();
- for (FileFormatI format : FileFormat.values())
+ for (FileFormatI format : FileFormats.getInstance().getFormats())
{
if (format.isWritable())
{
extensions.add(format.getExtensions());
- descs.add(format.toString());
+ descs.add(format.getName());
}
}
return new JalviewFileChooser(directory,
/**
* Constructor for a single choice of file extension and description
*
- * @param dir
* @param extension
* @param desc
*/
- public JalviewFileChooser(String dir, String extension, String desc)
+ public JalviewFileChooser(String extension, String desc)
{
- // TODO inline dir as Cache.getProperty("LAST_DIRECTORY") ? if applet
- // builds ok
- this(dir, new String[] { extension }, new String[] { desc }, desc,
- true);
+ this(Cache.getProperty("LAST_DIRECTORY"), new String[] { extension },
+ new String[] { desc }, desc, true);
}
JalviewFileChooser(String dir, String[] extensions, String[] descs,
format = format.substring(0, parenPos).trim();
try
{
- return FileFormat.valueOf(format);
+ return FileFormats.getInstance().forName(format);
} catch (IllegalArgumentException e)
{
System.err.println("Unexpected format: " + format);
private void loadExtensions()
{
extensions = new HashMap<String, String>();
- for (FileFormatI ff : FileFormat.values())
+ for (FileFormatI ff : FileFormats.getInstance().getFormats())
{
- String desc = ff.toString() + " file";
+ String desc = ff.getName() + " file";
String exts = ff.getExtensions();
for (String ext : exts.split(","))
{
import java.awt.Color;
+import MCview.PDBChain;
+
public class PDBFeatureSettings extends FeatureSettingsAdapter
{
// TODO find one central place to define feature names
private static final String FEATURE_INSERTION = "INSERTION";
- private static final String FEATURE_RES_NUM = "RESNUM";
+ private static final String FEATURE_RES_NUM = PDBChain.RESNUM_FEATURE;
@Override
public boolean isFeatureDisplayed(String type)
import java.util.regex.Pattern;
/**
- * A file parse for T-Coffee score ascii format. This file contains the
- * alignment consensus for each resude in any sequence.
+ * A file parser for T-Coffee score ascii format. This file contains the
+ * alignment consensus for each residue in any sequence.
* <p>
- * This file is procuded by <code>t_coffee</code> providing the option
+ * This file is produced by <code>t_coffee</code> providing the option
* <code>-output=score_ascii </code> to the program command line
*
* An example file is the following
*/
public class TCoffeeScoreFile extends AlignFile
{
- public TCoffeeScoreFile(String inFile, DataSourceType fileSourceType)
- throws IOException
- {
- super(inFile, fileSourceType);
- }
+ /**
+ * TCOFFEE score colourscheme
+ */
+ static final Color[] colors = { new Color(102, 102, 255), // 0: lilac #6666FF
+ new Color(0, 255, 0), // 1: green #00FF00
+ new Color(102, 255, 0), // 2: lime green #66FF00
+ new Color(204, 255, 0), // 3: greeny yellow #CCFF00
+ new Color(255, 255, 0), // 4: yellow #FFFF00
+ new Color(255, 204, 0), // 5: orange #FFCC00
+ new Color(255, 153, 0), // 6: deep orange #FF9900
+ new Color(255, 102, 0), // 7: ochre #FF6600
+ new Color(255, 51, 0), // 8: red #FF3300
+ new Color(255, 34, 0) // 9: redder #FF2000
+ };
- public TCoffeeScoreFile(FileParse source) throws IOException
- {
- super(source);
- }
+ public final static String TCOFFEE_SCORE = "TCoffeeScore";
+
+ static Pattern SCORES_WITH_RESIDUE_NUMS = Pattern
+ .compile("^\\d+\\s([^\\s]+)\\s+\\d+$");
/** The {@link Header} structure holder */
Header header;
Integer fWidth;
+ public TCoffeeScoreFile(String inFile, DataSourceType fileSourceType)
+ throws IOException
+ {
+ super(inFile, fileSourceType);
+
+ }
+
+ public TCoffeeScoreFile(FileParse source) throws IOException
+ {
+ super(source);
+ }
+
/**
* Parse the provided reader for the T-Coffee scores file format
*
}
}
- static Pattern SCORES_WITH_RESIDUE_NUMS = Pattern
- .compile("^\\d+\\s([^\\s]+)\\s+\\d+$");
-
/**
* Read a scores block ihe provided stream.
*
}
/**
- * TCOFFEE score colourscheme
- */
- static final Color[] colors = { new Color(102, 102, 255), // #6666FF
- new Color(0, 255, 0), // #00FF00
- new Color(102, 255, 0), // #66FF00
- new Color(204, 255, 0), // #CCFF00
- new Color(255, 255, 0), // #FFFF00
- new Color(255, 204, 0), // #FFCC00
- new Color(255, 153, 0), // #FF9900
- new Color(255, 102, 0), // #FF6600
- new Color(255, 51, 0), // #FF3300
- new Color(255, 34, 0) // #FF2000
- };
-
- public final static String TCOFFEE_SCORE = "TCoffeeScore";
-
- /**
* generate annotation for this TCoffee score set on the given alignment
*
* @param al
ArrayList<String> pdbfn = new ArrayList<String>();
StructureMappingcommandSet[] colcommands = JmolCommands
.getColourBySequenceCommand(ssm, modelSet, sequence, sr, fr,
- ((AlignmentViewPanel) source).getAlignment());
+ ((AlignmentViewPanel) source).getAlignViewport());
if (colcommands == null)
{
return;
return _listenerfn;
}
+ @Override
public void finalize() throws Throwable
{
jvlite = null;
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.api.SplitContainerI;
import jalview.bin.Cache;
-import jalview.gui.JvOptionPane;
import jalview.gui.JvSwingUtils;
import jalview.gui.Preferences;
-import jalview.io.FileFormat;
-import jalview.schemes.ColourSchemeProperty;
+import jalview.io.FileFormats;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.BorderLayout;
import java.awt.Color;
protected JMenuItem closeMenuItem = new JMenuItem();
- protected JMenu colourMenu = new JMenu();
-
protected JMenu webService = new JMenu();
protected JMenuItem webServiceNoServices;
- public JCheckBoxMenuItem viewBoxesMenuItem = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem viewBoxesMenuItem = new JCheckBoxMenuItem();
- public JCheckBoxMenuItem viewTextMenuItem = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem viewTextMenuItem = new JCheckBoxMenuItem();
protected JMenu sortByAnnotScore = new JMenu();
protected JMenu outputTextboxMenu = new JMenu();
- protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem hydrophobicityColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem nucleotideColour = new JRadioButtonMenuItem();
+ protected JCheckBoxMenuItem annotationPanelMenuItem = new JCheckBoxMenuItem();
- protected JRadioButtonMenuItem purinePyrimidineColour = new JRadioButtonMenuItem();
+ protected JCheckBoxMenuItem colourTextMenuItem = new JCheckBoxMenuItem();
- protected JRadioButtonMenuItem RNAInteractionColour = new JRadioButtonMenuItem();
-
- // protected JRadioButtonMenuItem covariationColour = new
- // JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem tcoffeeColour = new JRadioButtonMenuItem();
-
- public JCheckBoxMenuItem annotationPanelMenuItem = new JCheckBoxMenuItem();
-
- public JCheckBoxMenuItem colourTextMenuItem = new JCheckBoxMenuItem();
-
- public JCheckBoxMenuItem showNonconservedMenuItem = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem showNonconservedMenuItem = new JCheckBoxMenuItem();
protected JMenuItem undoMenuItem = new JMenuItem();
protected JMenuItem redoMenuItem = new JMenuItem();
- public JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();
-
- JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem();
-
- public JCheckBoxMenuItem wrapMenuItem = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem wrapMenuItem = new JCheckBoxMenuItem();
- public JCheckBoxMenuItem renderGapsMenuItem = new JCheckBoxMenuItem();
-
- public JCheckBoxMenuItem abovePIDThreshold = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem renderGapsMenuItem = new JCheckBoxMenuItem();
public JCheckBoxMenuItem showSeqFeatures = new JCheckBoxMenuItem();
JMenu pasteMenu = new JMenu();
- public JCheckBoxMenuItem applyToAllGroups = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem seqLimits = new JCheckBoxMenuItem();
+
+ protected JCheckBoxMenuItem scaleAbove = new JCheckBoxMenuItem();
+
+ protected JCheckBoxMenuItem scaleLeft = new JCheckBoxMenuItem();
+
+ protected JCheckBoxMenuItem scaleRight = new JCheckBoxMenuItem();
+
+ protected JCheckBoxMenuItem applyToAllGroups;
+
+ protected JMenu colourMenu = new JMenu();
+
+ protected JRadioButtonMenuItem textColour;
- public JCheckBoxMenuItem seqLimits = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem conservationMenuItem;
- public JCheckBoxMenuItem scaleAbove = new JCheckBoxMenuItem();
+ protected JMenuItem modifyConservation;
- public JCheckBoxMenuItem scaleLeft = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem abovePIDThreshold;
- public JCheckBoxMenuItem scaleRight = new JCheckBoxMenuItem();
+ protected JMenuItem modifyPID;
- protected JMenuItem modifyConservation = new JMenuItem();
+ protected JMenuItem annotationColour;
protected JMenu sortByTreeMenu = new JMenu();
protected JCheckBoxMenuItem showDbRefsMenuitem = new JCheckBoxMenuItem();
- protected ButtonGroup colours = new ButtonGroup();
-
protected JMenuItem showTranslation = new JMenuItem();
protected JMenuItem showReverse = new JMenuItem();
protected JMenuItem runGroovy = new JMenuItem();
- protected JMenuItem rnahelicesColour = new JMenuItem();
-
protected JCheckBoxMenuItem autoCalculate = new JCheckBoxMenuItem();
protected JCheckBoxMenuItem sortByTree = new JCheckBoxMenuItem();
setJMenuBar(alignFrameMenuBar);
// dynamically fill save as menu with available formats
- for (String ff : FileFormat.getWritableFormats(true))
+ for (String ff : FileFormats.getInstance().getWritableFormats(true))
{
JMenuItem item = new JMenuItem(ff);
System.err.println(e.toString());
}
- if (!jalview.util.Platform.isAMac())
+ if (!Platform.isAMac())
{
closeMenuItem.setMnemonic('C');
outputTextboxMenu.setMnemonic('T');
pasteMenu.setMnemonic('P');
reload.setMnemonic('R');
}
-
- if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
- {
- java.util.Enumeration userColours = jalview.gui.UserDefinedColours
- .getUserColourSchemes().keys();
-
- while (userColours.hasMoreElements())
- {
- final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(
- userColours.nextElement().toString());
- radioItem.setName("USER_DEFINED");
- radioItem.addMouseListener(new MouseAdapter()
- {
- @Override
- public void mousePressed(MouseEvent evt)
- {
- if (evt.isPopupTrigger()) // Mac
- {
- offerRemoval(radioItem);
- }
- }
-
- @Override
- public void mouseReleased(MouseEvent evt)
- {
- if (evt.isPopupTrigger()) // Windows
- {
- offerRemoval(radioItem);
- }
- }
-
- /**
- * @param radioItem
- */
- void offerRemoval(final JRadioButtonMenuItem radioItem)
- {
- radioItem.removeActionListener(radioItem.getActionListeners()[0]);
-
- int option = JvOptionPane.showInternalConfirmDialog(
- jalview.gui.Desktop.desktop, MessageManager
- .getString("label.remove_from_default_list"),
- MessageManager
- .getString("label.remove_user_defined_colour"),
- JvOptionPane.YES_NO_OPTION);
- if (option == JvOptionPane.YES_OPTION)
- {
- jalview.gui.UserDefinedColours
- .removeColourFromDefaults(radioItem.getText());
- colourMenu.remove(radioItem);
- }
- else
- {
- radioItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- userDefinedColour_actionPerformed(evt);
- }
- });
- }
- }
- });
- radioItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- userDefinedColour_actionPerformed(evt);
- }
- });
- colourMenu.insert(radioItem, 15);
- colours.add(radioItem);
- }
- }
- colours.add(noColourmenuItem);
- colours.add(clustalColour);
- colours.add(zappoColour);
- colours.add(taylorColour);
- colours.add(hydrophobicityColour);
- colours.add(helixColour);
- colours.add(strandColour);
- colours.add(turnColour);
- colours.add(buriedColour);
- colours.add(userDefinedColour);
- colours.add(PIDColour);
- colours.add(BLOSUM62Colour);
- colours.add(nucleotideColour);
- colours.add(purinePyrimidineColour);
- // colours.add(covariationColour);
- colours.add(tcoffeeColour);
- colours.add(RNAInteractionColour);
- setColourSelected(jalview.bin.Cache.getDefault(
- Preferences.DEFAULT_COLOUR, "None"));
- }
-
- public void setColourSelected(String defaultColour)
- {
-
- if (defaultColour != null)
- {
- int index = ColourSchemeProperty
- .getColourIndexFromName(defaultColour);
-
- switch (index)
- {
- case ColourSchemeProperty.CLUSTAL:
- clustalColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.BLOSUM:
- BLOSUM62Colour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.PID:
- PIDColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.ZAPPO:
- zappoColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.TAYLOR:
- taylorColour.setSelected(true);
- break;
-
- case ColourSchemeProperty.HYDROPHOBIC:
- hydrophobicityColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.HELIX:
- helixColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.STRAND:
- strandColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.TURN:
- turnColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.BURIED:
- buriedColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.NUCLEOTIDE:
- nucleotideColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.TCOFFEE:
- tcoffeeColour.setSelected(true);
- break;
-
- case ColourSchemeProperty.PURINEPYRIMIDINE:
- purinePyrimidineColour.setSelected(true);
-
- break;
-
- case ColourSchemeProperty.RNAINTERACTION:
- RNAInteractionColour.setSelected(true);
-
- break;
- /*
- * case ColourSchemeProperty.COVARIATION:
- * covariationColour.setSelected(true);
- *
- * break;
- */
- case ColourSchemeProperty.USER_DEFINED:
- userDefinedColour.setSelected(true);
-
- break;
- case ColourSchemeProperty.NONE:
- default:
- noColourmenuItem.setSelected(true);
- break;
-
- }
- }
-
}
private void jbInit() throws Exception
{
+ initColourMenu();
+
JMenuItem saveAs = new JMenuItem(
MessageManager.getString("action.save_as"));
ActionListener al = new ActionListener()
saveAs_actionPerformed(e);
}
};
+
+ // FIXME getDefaultToolkit throws an exception in Headless mode
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit
.getDefaultToolkit().getMenuShortcutKeyMask()
| KeyEvent.SHIFT_MASK, false);
}
});
showNonconservedMenuItem.setText(MessageManager
- .getString("label.show_non_conversed"));
+ .getString("label.show_non_conserved"));
showNonconservedMenuItem.setState(false);
showNonconservedMenuItem.addActionListener(new ActionListener()
{
statusBar.setText(MessageManager.getString("label.status_bar"));
outputTextboxMenu.setText(MessageManager
.getString("label.out_to_textbox"));
- clustalColour.setText(MessageManager.getString("label.clustalx"));
- clustalColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- clustalColour_actionPerformed(e);
- }
- });
- zappoColour.setText(MessageManager.getString("label.zappo"));
- zappoColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- zappoColour_actionPerformed(e);
- }
- });
- taylorColour.setText(MessageManager.getString("label.taylor"));
- taylorColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- taylorColour_actionPerformed(e);
- }
- });
- hydrophobicityColour.setText(MessageManager
- .getString("label.hydrophobicity"));
- hydrophobicityColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- hydrophobicityColour_actionPerformed(e);
- }
- });
- helixColour.setText(MessageManager.getString("label.helix_propensity"));
- helixColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- helixColour_actionPerformed(e);
- }
- });
- strandColour.setText(MessageManager
- .getString("label.strand_propensity"));
- strandColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- strandColour_actionPerformed(e);
- }
- });
- turnColour.setText(MessageManager.getString("label.turn_propensity"));
- turnColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- turnColour_actionPerformed(e);
- }
- });
- buriedColour.setText(MessageManager.getString("label.buried_index"));
- buriedColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- buriedColour_actionPerformed(e);
- }
- });
- userDefinedColour.setText(MessageManager
- .getString("action.user_defined"));
- userDefinedColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- userDefinedColour_actionPerformed(e);
- }
- });
- PIDColour
- .setText(MessageManager.getString("label.percentage_identity"));
- PIDColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- PIDColour_actionPerformed(e);
- }
- });
- BLOSUM62Colour
- .setText(MessageManager.getString("label.blosum62_score"));
- BLOSUM62Colour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- BLOSUM62Colour_actionPerformed(e);
- }
- });
- nucleotideColour.setText(MessageManager.getString("label.nucleotide"));
- nucleotideColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- nucleotideColour_actionPerformed(e);
- }
- });
-
- purinePyrimidineColour.setText(MessageManager
- .getString("label.purine_pyrimidine"));
- purinePyrimidineColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- purinePyrimidineColour_actionPerformed(e);
- }
- });
- RNAInteractionColour.setText("RNA Interaction type");
- RNAInteractionColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- RNAInteractionColour_actionPerformed(e);
- }
- });
- /*
- * covariationColour.setText("Covariation");
- * covariationColour.addActionListener(new ActionListener() { public void
- * actionPerformed(ActionEvent e) { covariationColour_actionPerformed(e); }
- * });
- */
JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem(
- MessageManager.getString("label.average_distance_bloslum62"));
+ MessageManager.getString("label.average_distance_blosum62"));
avDistanceTreeBlosumMenuItem.addActionListener(new ActionListener()
{
@Override
sortAnnotations_actionPerformed();
}
});
- colourTextMenuItem.setText(MessageManager
+ colourTextMenuItem = new JCheckBoxMenuItem(
+ MessageManager
.getString("label.colour_text"));
colourTextMenuItem.addActionListener(new ActionListener()
{
};
addMenuActionAndAccelerator(keyStroke, redoMenuItem, al);
- conservationMenuItem.setText(MessageManager
- .getString("action.by_conservation"));
- conservationMenuItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- conservationMenuItem_actionPerformed(e);
- }
- });
- noColourmenuItem.setText(MessageManager.getString("label.none"));
- noColourmenuItem.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- noColourmenuItem_actionPerformed(e);
- }
- });
wrapMenuItem.setText(MessageManager.getString("label.wrap"));
wrapMenuItem.addActionListener(new ActionListener()
{
};
addMenuActionAndAccelerator(keyStroke, findMenuItem, al);
- abovePIDThreshold.setText(MessageManager
- .getString("label.above_identity_threshold"));
- abovePIDThreshold.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- abovePIDThreshold_actionPerformed(e);
- }
- });
showSeqFeatures.setText(MessageManager
.getString("label.show_sequence_features"));
showSeqFeatures.addActionListener(new ActionListener()
}
});
- nucleotideColour.setText(MessageManager.getString("label.nucleotide"));
- nucleotideColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- nucleotideColour_actionPerformed(e);
- }
- });
-
- tcoffeeColour.setText(MessageManager.getString("label.tcoffee_scores"));
- tcoffeeColour.setEnabled(false);
- tcoffeeColour.addActionListener(new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent e)
- {
- tcoffeeColorScheme_actionPerformed(e);
- }
- });
-
JMenuItem deleteGroups = new JMenuItem(
MessageManager.getString("action.undefine_groups"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_U, Toolkit
};
addMenuActionAndAccelerator(keyStroke, deleteGroups, al);
+ JMenuItem annotationColumn = new JMenuItem(
+ MessageManager.getString("action.select_by_annotation"));
+ annotationColumn.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ annotationColumn_actionPerformed(e);
+ }
+ });
+
JMenuItem createGroup = new JMenuItem(
MessageManager.getString("action.create_groups"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit
};
addMenuActionAndAccelerator(keyStroke, pasteThis, al);
- applyToAllGroups.setText(MessageManager
- .getString("label.apply_colour_to_all_groups"));
- applyToAllGroups.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- applyToAllGroups_actionPerformed(e);
- }
- });
JMenuItem createPNG = new JMenuItem("PNG");
createPNG.addActionListener(new ActionListener()
{
});
- JMenuItem modifyPID = new JMenuItem(
- MessageManager.getString("label.modify_identity_threshold"));
- modifyPID.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- modifyPID_actionPerformed(e);
- }
- });
- modifyConservation.setText(MessageManager
- .getString("label.modify_conservation_threshold"));
- modifyConservation.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- modifyConservation_actionPerformed(e);
- }
- });
sortByTreeMenu
.setText(MessageManager.getString("action.by_tree_order"));
sort.setText(MessageManager.getString("action.sort"));
}
});
- JMenuItem annotationColour = new JMenuItem(
- MessageManager.getString("action.by_annotation"));
- annotationColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- annotationColour_actionPerformed(e);
- }
- });
-
- JMenuItem annotationColumn = new JMenuItem(
- MessageManager.getString("action.select_by_annotation"));
- annotationColumn.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- annotationColumn_actionPerformed(e);
- }
- });
-
- rnahelicesColour.setText(MessageManager
- .getString("action.by_rna_helixes"));
- rnahelicesColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- rnahelicesColour_actionPerformed(e);
- }
- });
-
JMenuItem associatedData = new JMenuItem(
MessageManager.getString("label.load_features_annotations"));
associatedData.addActionListener(new ActionListener()
tabbedPane.setToolTipText("<html><i>"
+ MessageManager.getString("label.rename_tab_eXpand_reGroup")
+ "</i></html>");
- JMenuItem textColour = new JMenuItem(
- MessageManager.getString("action.set_text_colour"));
- textColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- textColour_actionPerformed(e);
- }
- });
+
formatMenu.setText(MessageManager.getString("action.format"));
JMenu selectMenu = new JMenu(MessageManager.getString("action.select"));
idRightAlign.setText(MessageManager
autoAnnMenu.add(showGroupConsensus);
annotationsMenu.add(autoAnnMenu);
- colourMenu.add(applyToAllGroups);
- colourMenu.add(textColour);
- colourMenu.addSeparator();
- colourMenu.add(noColourmenuItem);
- colourMenu.add(clustalColour);
- colourMenu.add(BLOSUM62Colour);
- colourMenu.add(PIDColour);
- colourMenu.add(zappoColour);
- colourMenu.add(taylorColour);
- colourMenu.add(hydrophobicityColour);
- colourMenu.add(helixColour);
- colourMenu.add(strandColour);
- colourMenu.add(turnColour);
- colourMenu.add(buriedColour);
- colourMenu.add(nucleotideColour);
- colourMenu.add(purinePyrimidineColour);
- // colourMenu.add(RNAInteractionColour);
- // colourMenu.add(covariationColour);
- colourMenu.add(tcoffeeColour);
- colourMenu.add(userDefinedColour);
- colourMenu.addSeparator();
- colourMenu.add(conservationMenuItem);
- colourMenu.add(modifyConservation);
- colourMenu.add(abovePIDThreshold);
- colourMenu.add(modifyPID);
- colourMenu.add(annotationColour);
- colourMenu.add(rnahelicesColour);
sort.add(sortIDMenuItem);
sort.add(sortLengthMenuItem);
// selectMenu.add(listenToViewSelections);
}
+ /**
+ * Constructs the entries on the Colour menu (but does not add them to the
+ * menu).
+ */
+ protected void initColourMenu()
+ {
+ applyToAllGroups = new JCheckBoxMenuItem(
+ MessageManager.getString("label.apply_colour_to_all_groups"));
+ applyToAllGroups.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ applyToAllGroups_actionPerformed(applyToAllGroups.isSelected());
+ }
+ });
+
+ textColour = new JRadioButtonMenuItem(
+ MessageManager.getString("action.set_text_colour"));
+ textColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ textColour_actionPerformed();
+ }
+ });
+
+ conservationMenuItem = new JCheckBoxMenuItem(
+ MessageManager.getString("action.by_conservation"));
+ conservationMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ conservationMenuItem_actionPerformed(conservationMenuItem
+ .isSelected());
+ }
+ });
+
+ abovePIDThreshold = new JCheckBoxMenuItem(
+ MessageManager.getString("label.above_identity_threshold"));
+ abovePIDThreshold.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ abovePIDThreshold_actionPerformed(abovePIDThreshold.isSelected());
+ }
+ });
+ modifyPID = new JMenuItem(
+ MessageManager.getString("label.modify_identity_threshold"));
+ modifyPID.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ modifyPID_actionPerformed();
+ }
+ });
+ modifyConservation = new JMenuItem(
+ MessageManager
+ .getString("label.modify_conservation_threshold"));
+ modifyConservation.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ modifyConservation_actionPerformed();
+ }
+ });
+
+ annotationColour = new JMenuItem(
+ MessageManager.getString("action.by_annotation"));
+ annotationColour.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ annotationColour_actionPerformed();
+ }
+ });
+ }
+
protected void selectHighlightedColumns_actionPerformed(
ActionEvent actionEvent)
{
{
}
- protected void clustalColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void zappoColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void taylorColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void hydrophobicityColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void helixColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void strandColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void turnColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void buriedColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void userDefinedColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void PIDColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void BLOSUM62Colour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void purinePyrimidineColour_actionPerformed(ActionEvent e)
- {
- }
-
- protected void RNAInteractionColour_actionPerformed(ActionEvent e)
- {
- }
-
- /*
- * protected void covariationColour_actionPerformed(ActionEvent e) { }
- */
-
- protected void noColourmenuItem_actionPerformed(ActionEvent e)
- {
- }
-
- protected void conservationMenuItem_actionPerformed(ActionEvent e)
+ protected void conservationMenuItem_actionPerformed(boolean selected)
{
}
{
}
- protected void abovePIDThreshold_actionPerformed(ActionEvent e)
+ protected void abovePIDThreshold_actionPerformed(boolean selected)
{
}
{
}
- protected void nucleotideColour_actionPerformed(ActionEvent e)
- {
- }
-
protected void deleteGroups_actionPerformed(ActionEvent e)
{
}
{
}
- protected void applyToAllGroups_actionPerformed(ActionEvent e)
+ protected void applyToAllGroups_actionPerformed(boolean selected)
{
}
}
- /**
- * Template method to handle the 'Color T-Coffee scores' menu event.
- * <p>
- * Subclasses override this method to provide a custom action.
- *
- * @param event
- * The raised event
- */
- protected void tcoffeeColorScheme_actionPerformed(ActionEvent event)
- {
-
- }
-
protected void jpred_actionPerformed(ActionEvent e)
{
}
{
}
- protected void modifyPID_actionPerformed(ActionEvent e)
+ protected void modifyPID_actionPerformed()
{
}
- protected void modifyConservation_actionPerformed(ActionEvent e)
+ protected void modifyConservation_actionPerformed()
{
}
}
- public void annotationColour_actionPerformed(ActionEvent e)
+ public void annotationColour_actionPerformed()
{
-
}
public void annotationColumn_actionPerformed(ActionEvent e)
{
-
- }
-
- public void rnahelicesColour_actionPerformed(ActionEvent e)
- {
-
}
public void associatedData_actionPerformed(ActionEvent e)
}
- public void textColour_actionPerformed(ActionEvent e)
+ public void textColour_actionPerformed()
{
}
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
-import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
+import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
/**
* Base class for the Preferences panel.
/*
* Connections tab components
*/
- protected JList linkURLList = new JList();
+ protected JTable linkUrlTable = new JTable();
+
+ protected JButton editLink = new JButton();
+
+ protected JButton deleteLink = new JButton();
+
+ protected JTextField filterTB = new JTextField();
+
+ protected JButton doReset = new JButton();
+
+ protected JButton userOnly = new JButton();
+
+ protected JLabel portLabel = new JLabel();
+
+ protected JLabel serverLabel = new JLabel();
protected JTextField proxyServerTB = new JTextField();
protected JTextField defaultBrowser = new JTextField();
- protected JList linkNameList = new JList();
-
protected JCheckBox useProxy = new JCheckBox();
protected JCheckBox usagestats = new JCheckBox();
tabbedPane.add(initConnectionsTab(),
MessageManager.getString("label.connections"));
+ tabbedPane.add(initLinksTab(),
+ MessageManager.getString("label.urllinks"));
+
tabbedPane.add(initOutputTab(),
MessageManager.getString("label.output"));
{
JPanel connectTab = new JPanel();
connectTab.setLayout(new GridBagLayout());
- JLabel serverLabel = new JLabel();
- serverLabel.setText(MessageManager.getString("label.address"));
- serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- serverLabel.setFont(LABEL_FONT);
- proxyServerTB.setFont(LABEL_FONT);
- proxyPortTB.setFont(LABEL_FONT);
- JLabel portLabel = new JLabel();
- portLabel.setFont(LABEL_FONT);
- portLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- portLabel.setText(MessageManager.getString("label.port"));
+
+ // Label for browser text box
JLabel browserLabel = new JLabel();
- browserLabel.setFont(new java.awt.Font("SansSerif", 0, 11));
+ browserLabel.setFont(LABEL_FONT);
browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);
browserLabel.setText(MessageManager
.getString("label.default_browser_unix"));
defaultBrowser.setFont(LABEL_FONT);
defaultBrowser.setText("");
- usagestats.setText(MessageManager
- .getString("label.send_usage_statistics"));
- usagestats.setFont(LABEL_FONT);
- usagestats.setHorizontalAlignment(SwingConstants.RIGHT);
- usagestats.setHorizontalTextPosition(SwingConstants.LEADING);
- questionnaire.setText(MessageManager
- .getString("label.check_for_questionnaires"));
- questionnaire.setFont(LABEL_FONT);
- questionnaire.setHorizontalAlignment(SwingConstants.RIGHT);
- questionnaire.setHorizontalTextPosition(SwingConstants.LEADING);
- versioncheck.setText(MessageManager
- .getString("label.check_for_latest_version"));
- versioncheck.setFont(LABEL_FONT);
- versioncheck.setHorizontalAlignment(SwingConstants.RIGHT);
- versioncheck.setHorizontalTextPosition(SwingConstants.LEADING);
+
+ defaultBrowser.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() > 1)
+ {
+ defaultBrowser_mouseClicked(e);
+ }
+ }
+ });
+
+ JPanel proxyPanel = initConnTabProxyPanel();
+ initConnTabCheckboxes();
+
+ // Add default Browser text box
+ connectTab.add(browserLabel, new GridBagConstraints(0, 0, 1, 1, 0.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
+ new Insets(10, 0, 5, 5), 5, 1));
+ defaultBrowser.setFont(LABEL_FONT);
+ defaultBrowser.setText("");
+
+ connectTab.add(defaultBrowser, new GridBagConstraints(1, 0, 1, 1, 1.0,
+ 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
+ new Insets(10, 0, 5, 10), 30, 1));
+
+ // Add proxy server panel
+ connectTab.add(proxyPanel, new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0,
+ GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
+ new Insets(10, 0, 5, 12), 4, 10));
+
+ // Add usage stats, version check and questionnaire checkboxes
+ connectTab.add(usagestats, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 5, 5), 70, 1));
+ connectTab.add(questionnaire, new GridBagConstraints(1, 2, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 5, 10), 70, 1));
+ connectTab.add(versioncheck, new GridBagConstraints(0, 3, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 5, 5), 70, 1));
+
+ // Add padding so the panel doesn't look ridiculous
+ JPanel spacePanel = new JPanel();
+ connectTab.add(spacePanel, new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0,
+ GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0,
+ 0, 0, 5), 70, 1));
+
+ return connectTab;
+ }
+
+ /**
+ * Initialises the Links tabbed panel.
+ *
+ * @return
+ */
+ private JPanel initLinksTab()
+ {
+ JPanel linkTab = new JPanel();
+ linkTab.setLayout(new GridBagLayout());
+
+ // Set up table for Url links
+ linkUrlTable.setFillsViewportHeight(true);
+ linkUrlTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+ linkUrlTable.setAutoCreateRowSorter(true);
+ linkUrlTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+ // adjust row height so radio buttons actually fit
+ // don't do this in the renderer, it causes the awt thread to activate
+ // constantly
+ JRadioButton temp = new JRadioButton();
+ linkUrlTable.setRowHeight(temp.getMinimumSize().height);
+
+ // Table in scrollpane so that the table is given a scrollbar
+ JScrollPane linkScrollPane = new JScrollPane(linkUrlTable);
+ linkScrollPane.setBorder(null);
+
+ // Panel for links functionality
+ JPanel linkPanel = new JPanel(new GridBagLayout());
+ linkPanel.setBorder(new TitledBorder(MessageManager
+ .getString("label.url_linkfrom_sequence_id")));
+
+ // Put the Url links panel together
+
+ // Buttons go at top right, resizing only resizes the blank space vertically
+ JPanel buttonPanel = initLinkTabUrlButtons();
+ GridBagConstraints linkConstraints1 = new GridBagConstraints();
+ linkConstraints1.insets = new Insets(0, 0, 5, 0);
+ linkConstraints1.gridx = 0;
+ linkConstraints1.gridy = 0;
+ linkConstraints1.weightx = 1.0;
+ linkConstraints1.fill = GridBagConstraints.HORIZONTAL;
+ linkTab.add(buttonPanel, linkConstraints1);
+
+ // Links table goes at top left, resizing resizes the table
+ GridBagConstraints linkConstraints2 = new GridBagConstraints();
+ linkConstraints2.insets = new Insets(0, 0, 5, 5);
+ linkConstraints2.gridx = 0;
+ linkConstraints2.gridy = 1;
+ linkConstraints2.weightx = 1.0;
+ linkConstraints2.weighty = 1.0;
+ linkConstraints2.fill = GridBagConstraints.BOTH;
+ linkTab.add(linkScrollPane, linkConstraints2);
+
+ // Filter box and buttons goes at bottom left, resizing resizes the text box
+ JPanel filterPanel = initLinkTabFilterPanel();
+ GridBagConstraints linkConstraints3 = new GridBagConstraints();
+ linkConstraints3.insets = new Insets(0, 0, 0, 5);
+ linkConstraints3.gridx = 0;
+ linkConstraints3.gridy = 2;
+ linkConstraints3.weightx = 1.0;
+ linkConstraints3.fill = GridBagConstraints.HORIZONTAL;
+ linkTab.add(filterPanel, linkConstraints3);
+
+ return linkTab;
+ }
+
+ private JPanel initLinkTabFilterPanel()
+ {
+ // Filter textbox and reset button
+ JLabel filterLabel = new JLabel(
+ MessageManager.getString("label.filter"));
+ filterLabel.setFont(LABEL_FONT);
+ filterLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ filterLabel.setHorizontalTextPosition(SwingConstants.LEADING);
+
+ filterTB.setFont(LABEL_FONT);
+ filterTB.setText("");
+
+ doReset.setText(MessageManager.getString("action.showall"));
+ userOnly.setText(MessageManager.getString("action.customfilter"));
+
+ // Panel for filter functionality
+ JPanel filterPanel = new JPanel(new GridBagLayout());
+ filterPanel.setBorder(new TitledBorder("Filter"));
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.NONE;
+ gbc.anchor = GridBagConstraints.WEST;
+
+ filterPanel.add(filterLabel, gbc);
+
+ GridBagConstraints gbc1 = new GridBagConstraints();
+ gbc1.gridx = 1;
+ gbc1.gridwidth = 2;
+ gbc1.fill = GridBagConstraints.HORIZONTAL;
+ gbc1.anchor = GridBagConstraints.WEST;
+ gbc1.weightx = 1.0;
+ filterPanel.add(filterTB, gbc1);
+
+ GridBagConstraints gbc2 = new GridBagConstraints();
+ gbc2.gridx = 3;
+ gbc2.fill = GridBagConstraints.NONE;
+ gbc2.anchor = GridBagConstraints.WEST;
+ filterPanel.add(doReset, gbc2);
+
+ GridBagConstraints gbc3 = new GridBagConstraints();
+ gbc3.gridx = 4;
+ gbc3.fill = GridBagConstraints.NONE;
+ gbc3.anchor = GridBagConstraints.WEST;
+ filterPanel.add(userOnly, gbc3);
+
+ return filterPanel;
+ }
+
+ private JPanel initLinkTabUrlButtons()
+ {
+ // Buttons for new / edit / delete Url links
JButton newLink = new JButton();
newLink.setText(MessageManager.getString("action.new"));
+
+ editLink.setText(MessageManager.getString("action.edit"));
+
+ deleteLink.setText(MessageManager.getString("action.delete"));
+
+ // no current selection, so initially disable delete/edit buttons
+ editLink.setEnabled(false);
+ deleteLink.setEnabled(false);
+
newLink.addActionListener(new java.awt.event.ActionListener()
{
@Override
newLink_actionPerformed(e);
}
});
- JButton editLink = new JButton();
+
editLink.setText(MessageManager.getString("action.edit"));
editLink.addActionListener(new java.awt.event.ActionListener()
{
editLink_actionPerformed(e);
}
});
- JButton deleteLink = new JButton();
+
deleteLink.setText(MessageManager.getString("action.delete"));
deleteLink.addActionListener(new java.awt.event.ActionListener()
{
}
});
- linkURLList.addListSelectionListener(new ListSelectionListener()
- {
- @Override
- public void valueChanged(ListSelectionEvent e)
- {
- int index = linkURLList.getSelectedIndex();
- linkNameList.setSelectedIndex(index);
- }
- });
+ JPanel buttonPanel = new JPanel(new GridBagLayout());
+ buttonPanel.setBorder(new TitledBorder("Edit links"));
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.NONE;
+ buttonPanel.add(newLink, gbc);
+
+ GridBagConstraints gbc1 = new GridBagConstraints();
+ gbc1.gridx = 1;
+ gbc1.gridy = 0;
+ gbc1.fill = GridBagConstraints.NONE;
+ buttonPanel.add(editLink, gbc1);
+
+ GridBagConstraints gbc2 = new GridBagConstraints();
+ gbc2.gridx = 2;
+ gbc2.gridy = 0;
+ gbc2.fill = GridBagConstraints.NONE;
+ buttonPanel.add(deleteLink, gbc2);
+
+ GridBagConstraints gbc3 = new GridBagConstraints();
+ gbc3.gridx = 3;
+ gbc3.gridy = 0;
+ gbc3.fill = GridBagConstraints.HORIZONTAL;
+ gbc3.weightx = 1.0;
+ JPanel spacePanel = new JPanel();
+ spacePanel.setBorder(null);
+ buttonPanel.add(spacePanel, gbc3);
+
+ return buttonPanel;
+ }
- linkNameList.addListSelectionListener(new ListSelectionListener()
- {
- @Override
- public void valueChanged(ListSelectionEvent e)
- {
- int index = linkNameList.getSelectedIndex();
- linkURLList.setSelectedIndex(index);
- }
- });
+ /**
+ * Initialises the proxy server panel in the Connections tab
+ *
+ * @return the proxy server panel
+ */
+ private JPanel initConnTabProxyPanel()
+ {
+ // Label for server text box
+ serverLabel.setText(MessageManager.getString("label.address"));
+ serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ serverLabel.setFont(LABEL_FONT);
- JScrollPane linkScrollPane = new JScrollPane();
- linkScrollPane.setBorder(null);
- JPanel linkPanel = new JPanel();
- linkPanel.setBorder(new TitledBorder(MessageManager
- .getString("label.url_linkfrom_sequence_id")));
- linkPanel.setLayout(new BorderLayout());
- GridLayout gridLayout1 = new GridLayout();
- JPanel editLinkButtons = new JPanel();
- editLinkButtons.setLayout(gridLayout1);
- gridLayout1.setRows(3);
- linkNameList.setFont(LABEL_FONT);
- linkNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- BorderLayout borderLayout3 = new BorderLayout();
- JPanel linkPanel2 = new JPanel();
- linkPanel2.setLayout(borderLayout3);
- linkURLList.setFont(LABEL_FONT);
- linkURLList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // Proxy server and port text boxes
+ proxyServerTB.setFont(LABEL_FONT);
+ proxyPortTB.setFont(LABEL_FONT);
- defaultBrowser.addMouseListener(new MouseAdapter()
- {
- @Override
- public void mouseClicked(MouseEvent e)
- {
- if (e.getClickCount() > 1)
- {
- defaultBrowser_mouseClicked(e);
- }
- }
- });
+ // Label for Port text box
+ portLabel.setFont(LABEL_FONT);
+ portLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ portLabel.setText(MessageManager.getString("label.port"));
+
+ // Use proxy server checkbox
useProxy.setFont(LABEL_FONT);
useProxy.setHorizontalAlignment(SwingConstants.RIGHT);
useProxy.setHorizontalTextPosition(SwingConstants.LEADING);
useProxy_actionPerformed();
}
});
- linkPanel.add(editLinkButtons, BorderLayout.EAST);
- editLinkButtons.add(newLink, null);
- editLinkButtons.add(editLink, null);
- editLinkButtons.add(deleteLink, null);
- linkPanel.add(linkScrollPane, BorderLayout.CENTER);
- linkScrollPane.getViewport().add(linkPanel2, null);
- linkPanel2.add(linkURLList, BorderLayout.CENTER);
- linkPanel2.add(linkNameList, BorderLayout.WEST);
- JPanel jPanel1 = new JPanel();
+
+ // Make proxy server panel
+ JPanel proxyPanel = new JPanel();
TitledBorder titledBorder1 = new TitledBorder(
MessageManager.getString("label.proxy_server"));
- jPanel1.setBorder(titledBorder1);
- jPanel1.setLayout(new GridBagLayout());
- jPanel1.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
- 2, 4, 0), 5, 0));
- jPanel1.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
- 0, 4, 0), 11, 6));
- connectTab.add(linkPanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0,
- GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
- 16, 0, 0, 12), 359, -17));
- connectTab.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0,
- GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
- 21, 0, 35, 12), 4, 6));
- connectTab.add(browserLabel, new GridBagConstraints(0, 1, 1, 1, 0.0,
+ proxyPanel.setBorder(titledBorder1);
+ proxyPanel.setLayout(new GridBagLayout());
+ proxyPanel.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0,
0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
- new Insets(16, 0, 0, 0), 5, 1));
- jPanel1.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
+ new Insets(0, 2, 2, 0), 5, 0));
+ proxyPanel.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
+ 0, 2, 0), 11, 0));
+ proxyPanel.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
2, 5, 185), 2, -4));
- jPanel1.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 54, 1));
- jPanel1.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 0), 263, 1));
- connectTab.add(defaultBrowser, new GridBagConstraints(1, 1, 1, 1, 1.0,
- 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(15, 0, 0, 15), 307, 1));
- connectTab.add(usagestats, new GridBagConstraints(0, 4, 1, 1, 1.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 70, 1));
- connectTab.add(questionnaire, new GridBagConstraints(1, 4, 1, 1, 1.0,
+ proxyPanel.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0,
0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 70, 1));
- connectTab.add(versioncheck, new GridBagConstraints(0, 5, 1, 1, 1.0,
+ new Insets(0, 2, 2, 2), 54, 1));
+ proxyPanel.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0,
0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 70, 1));
- return connectTab;
+ new Insets(0, 2, 2, 0), 263, 1));
+
+ return proxyPanel;
+ }
+
+ /**
+ * Initialises the checkboxes in the Connections tab
+ */
+ private void initConnTabCheckboxes()
+ {
+ // Usage stats checkbox label
+ usagestats.setText(MessageManager
+ .getString("label.send_usage_statistics"));
+ usagestats.setFont(LABEL_FONT);
+ usagestats.setHorizontalAlignment(SwingConstants.RIGHT);
+ usagestats.setHorizontalTextPosition(SwingConstants.LEADING);
+
+ // Questionnaire checkbox label
+ questionnaire.setText(MessageManager
+ .getString("label.check_for_questionnaires"));
+ questionnaire.setFont(LABEL_FONT);
+ questionnaire.setHorizontalAlignment(SwingConstants.RIGHT);
+ questionnaire.setHorizontalTextPosition(SwingConstants.LEADING);
+
+ // Check for latest version checkbox label
+ versioncheck.setText(MessageManager
+ .getString("label.check_for_latest_version"));
+ versioncheck.setFont(LABEL_FONT);
+ versioncheck.setHorizontalAlignment(SwingConstants.RIGHT);
+ versioncheck.setHorizontalTextPosition(SwingConstants.LEADING);
}
/**
public void useProxy_actionPerformed()
{
- proxyServerTB.setEnabled(useProxy.isSelected());
- proxyPortTB.setEnabled(useProxy.isSelected());
+ boolean enabled = useProxy.isSelected();
+ portLabel.setEnabled(enabled);
+ serverLabel.setEnabled(enabled);
+ proxyServerTB.setEnabled(enabled);
+ proxyPortTB.setEnabled(enabled);
+ }
+
+ /**
+ * Customer renderer for JTable: supports column of radio buttons
+ */
+ public class RadioButtonRenderer extends JRadioButton implements
+ TableCellRenderer
+ {
+ public RadioButtonRenderer()
+ {
+ setHorizontalAlignment(CENTER);
+ setToolTipText(MessageManager.getString("label.urltooltip"));
+ }
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table,
+ Object value, boolean isSelected, boolean hasFocus, int row,
+ int column)
+ {
+ setSelected((boolean) value);
+
+ // set colours to match rest of table
+ if (isSelected)
+ {
+ setBackground(table.getSelectionBackground());
+ setForeground(table.getSelectionForeground());
+ }
+ else
+ {
+ setBackground(table.getBackground());
+ setForeground(table.getForeground());
+ }
+ return this;
+ }
}
+ /**
+ * Customer cell editor for JTable: supports column of radio buttons in
+ * conjunction with renderer
+ */
+ public class RadioButtonEditor extends AbstractCellEditor implements
+ TableCellEditor
+ {
+ private JRadioButton button = new JRadioButton();
+
+ public RadioButtonEditor()
+ {
+ button.setHorizontalAlignment(SwingConstants.CENTER);
+ this.button.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ fireEditingStopped();
+ }
+ });
+ }
+
+ @Override
+ public Component getTableCellEditorComponent(JTable table,
+ Object value, boolean isSelected, int row, int column)
+ {
+ button.setSelected((boolean) value);
+ return button;
+ }
+
+ @Override
+ public Object getCellEditorValue()
+ {
+ return button.isSelected();
+ }
+
+ }
}
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
-import java.awt.Panel;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.BorderFactory;
+import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
-public class GSequenceLink extends Panel
+public class GSequenceLink extends JPanel
{
+
+ JTextField nameTB = new JTextField();
+
+ JTextField urlTB = new JTextField();
+
+ JButton insertSeq = new JButton();
+
+ JButton insertDBAcc = new JButton();
+
+ JLabel insert = new JLabel();
+
+ JLabel jLabel1 = new JLabel();
+
+ JLabel jLabel2 = new JLabel();
+
+ JLabel jLabel3 = new JLabel();
+
+ JLabel jLabel4 = new JLabel();
+
+ JLabel jLabel5 = new JLabel();
+
+ JLabel jLabel6 = new JLabel();
+
+ JPanel jPanel1 = new JPanel();
+
+ GridBagLayout gridBagLayout1 = new GridBagLayout();
+
public GSequenceLink()
{
try
urlTB_keyTyped(e);
}
});
+
+ insertSeq.setLocation(77, 75);
+ insertSeq.setSize(141, 24);
+ insertSeq.setText(MessageManager.getString("action.seq_id"));
+ insertSeq.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ insertSeq_action(e);
+ }
+ });
+
+ insertDBAcc.setLocation(210, 75);
+ insertDBAcc.setSize(141, 24);
+ insertDBAcc.setText(MessageManager.getString("action.db_acc"));
+ insertDBAcc.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ insertDBAcc_action(e);
+ }
+ });
+
+ insert.setText(MessageManager.getString("label.insert"));
+ insert.setFont(JvSwingUtils.getLabelFont());
+ insert.setHorizontalAlignment(SwingConstants.RIGHT);
+ insert.setBounds(17, 78, 58, 16);
+
jLabel1.setFont(JvSwingUtils.getLabelFont());
jLabel1.setHorizontalAlignment(SwingConstants.TRAILING);
jLabel1.setText(MessageManager.getString("label.link_name"));
jLabel1.setBounds(new Rectangle(4, 10, 71, 24));
jLabel2.setFont(JvSwingUtils.getLabelFont());
jLabel2.setHorizontalAlignment(SwingConstants.TRAILING);
- jLabel2.setText(MessageManager.getString("label.url"));
+ jLabel2.setText(MessageManager.getString("label.url:"));
jLabel2.setBounds(new Rectangle(17, 37, 54, 27));
jLabel3.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
jLabel3.setText(MessageManager.getString("label.use_sequence_id_1"));
- jLabel3.setBounds(new Rectangle(21, 72, 351, 15));
+ jLabel3.setBounds(new Rectangle(21, 102, 351, 15));
jLabel4.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
jLabel4.setText(MessageManager.getString("label.use_sequence_id_2"));
- jLabel4.setBounds(new Rectangle(21, 88, 351, 15));
+ jLabel4.setBounds(new Rectangle(21, 118, 351, 15));
jLabel5.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
jLabel5.setText(MessageManager.getString("label.use_sequence_id_3"));
- jLabel5.setBounds(new Rectangle(21, 106, 351, 15));
+ jLabel5.setBounds(new Rectangle(21, 136, 351, 15));
String lastLabel = MessageManager.getString("label.use_sequence_id_4");
if (lastLabel.length() > 0)
// e.g. Spanish version has longer text
jLabel6.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
jLabel6.setText(lastLabel);
- jLabel6.setBounds(new Rectangle(21, 122, 351, 15));
+ jLabel6.setBounds(new Rectangle(21, 152, 351, 15));
}
jPanel1.setBorder(BorderFactory.createEtchedBorder());
jPanel1.add(jLabel1);
jPanel1.add(nameTB);
jPanel1.add(urlTB);
+ jPanel1.add(insertSeq);
+ jPanel1.add(insertDBAcc);
+ jPanel1.add(insert);
jPanel1.add(jLabel2);
jPanel1.add(jLabel3);
jPanel1.add(jLabel4);
jPanel1.add(jLabel5);
- int height = 130;
+ int height = 160;
if (lastLabel.length() > 0)
{
jPanel1.add(jLabel6);
- height = 146;
+ height = 176;
}
this.add(jPanel1, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
return false;
}
- JTextField nameTB = new JTextField();
-
- JTextField urlTB = new JTextField();
-
- JLabel jLabel1 = new JLabel();
-
- JLabel jLabel2 = new JLabel();
-
- JLabel jLabel3 = new JLabel();
-
- JLabel jLabel4 = new JLabel();
-
- JLabel jLabel5 = new JLabel();
-
- JLabel jLabel6 = new JLabel();
-
- JPanel jPanel1 = new JPanel();
-
- GridBagLayout gridBagLayout1 = new GridBagLayout();
+ public void notifyDuplicate()
+ {
+ JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,
+ MessageManager.getString("warn.name_cannot_be_duplicate"),
+ MessageManager.getString("label.invalid_name"),
+ JvOptionPane.WARNING_MESSAGE);
+ }
public void nameTB_keyTyped(KeyEvent e)
{
// }
}
+
+ public void insertSeq_action(ActionEvent e)
+ {
+ insertIntoUrl(insertSeq.getText());
+ }
+
+ public void insertDBAcc_action(ActionEvent e)
+ {
+ insertIntoUrl(insertDBAcc.getText());
+ }
+
+ private void insertIntoUrl(String insertion)
+ {
+ int pos = urlTB.getCaretPosition();
+ String text = urlTB.getText();
+ String newText = text.substring(0, pos) + insertion
+ + text.substring(pos);
+ urlTB.setText(newText);
+ }
}
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
slider.setDoubleBuffered(true);
slider.addMouseListener(new MouseAdapter()
{
+ @Override
public void mouseReleased(MouseEvent e)
{
slider_mouseReleased(e);
valueField.setPreferredSize(new Dimension(50, 12));
valueField.setText("");
valueField.setHorizontalAlignment(SwingConstants.CENTER);
- valueField.addActionListener(new java.awt.event.ActionListener()
+ valueField.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
- valueField_actionPerformed(e);
+ valueField_actionPerformed();
+ }
+ });
+ valueField.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusLost(FocusEvent e)
+ {
+ valueField_actionPerformed();
}
});
label.setFont(new java.awt.Font("Verdana", 0, 11));
applyButton.setText(MessageManager.getString("action.apply"));
applyButton.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
applyButton_actionPerformed(e);
undoButton.setText(MessageManager.getString("action.undo"));
undoButton.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
undoButton_actionPerformed(e);
.getString("action.apply_all_groups"));
allGroupsCheck.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
allGroupsCheck_actionPerformed(e);
}
/**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
+ * Action on changing the slider text field value
*/
- protected void valueField_actionPerformed(ActionEvent e)
+ protected void valueField_actionPerformed()
{
+ try
+ {
+ int i = Integer.valueOf(valueField.getText());
+ slider.setValue(i);
+ } catch (NumberFormatException ex)
+ {
+ valueField.setText(String.valueOf(slider.getValue()));
+ }
}
/**
package jalview.jbgui;
import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.gui.ColourMenuHelper.ColourChangeListener;
import jalview.util.MessageManager;
+import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import javax.swing.ButtonGroup;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JRadioButtonMenuItem;
public abstract class GStructureViewer extends JInternalFrame implements
- JalviewStructureDisplayI
+ JalviewStructureDisplayI, ColourChangeListener
{
// private AAStructureBindingModel bindingModel;
- protected JMenu savemenu = new JMenu();
+ protected JMenu savemenu;
- protected JMenu viewMenu = new JMenu();
+ protected JMenu viewMenu;
- protected JMenu chainMenu = new JMenu();
+ protected JMenu colourMenu;
- protected JMenu viewerActionMenu = new JMenu();
+ protected JMenu chainMenu;
- protected JMenuItem alignStructs = new JMenuItem();
+ protected JMenu viewerActionMenu;
- protected JMenuItem fitToWindow = new JMenuItem();
+ protected JMenuItem alignStructs;
- protected JRadioButtonMenuItem seqColour = new JRadioButtonMenuItem();
+ protected JMenuItem fitToWindow;
- protected JRadioButtonMenuItem chainColour = new JRadioButtonMenuItem();
+ protected JRadioButtonMenuItem seqColour;
- protected JRadioButtonMenuItem chargeColour = new JRadioButtonMenuItem();
+ protected JRadioButtonMenuItem chainColour;
- protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();
+ protected JRadioButtonMenuItem chargeColour;
- protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();
+ protected JRadioButtonMenuItem viewerColour;
- protected JRadioButtonMenuItem hydroColour = new JRadioButtonMenuItem();
+ protected JMenuItem helpItem;
- protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();
+ protected JLabel statusBar;
- protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem purinePyrimidineColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem userColour = new JRadioButtonMenuItem();
-
- protected JRadioButtonMenuItem viewerColour = new JRadioButtonMenuItem();
-
- protected JMenuItem helpItem = new JMenuItem();
-
- protected JLabel statusBar = new JLabel();
-
- protected JPanel statusPanel = new JPanel();
+ protected JPanel statusPanel;
/**
* Constructor
JMenu fileMenu = new JMenu();
fileMenu.setText(MessageManager.getString("action.file"));
+ savemenu = new JMenu();
savemenu.setActionCommand(MessageManager.getString("action.save_image"));
savemenu.setText(MessageManager.getString("action.save_as"));
viewMapping_actionPerformed(actionEvent);
}
});
+
+ viewMenu = new JMenu();
viewMenu.setText(MessageManager.getString("action.view"));
+ chainMenu = new JMenu();
chainMenu.setText(MessageManager.getString("action.show_chain"));
+ fitToWindow = new JMenuItem();
fitToWindow.setText(MessageManager.getString("label.fit_to_window"));
fitToWindow.addActionListener(new ActionListener()
{
}
});
- JMenu colourMenu = new JMenu();
- colourMenu.setText(MessageManager.getString("label.colours"));
-
- JMenuItem backGround = new JMenuItem();
- backGround
- .setText(MessageManager.getString("action.background_colour"));
- backGround.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- backGround_actionPerformed(actionEvent);
- }
- });
- seqColour.setSelected(false);
- seqColour.setText(MessageManager.getString("action.by_sequence"));
- seqColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- seqColour_actionPerformed(actionEvent);
- }
- });
- chainColour.setText(MessageManager.getString("action.by_chain"));
- chainColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- chainColour_actionPerformed(actionEvent);
- }
- });
- chargeColour.setText(MessageManager.getString("label.charge_cysteine"));
- chargeColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- chargeColour_actionPerformed(actionEvent);
- }
- });
- zappoColour.setText(MessageManager.getString("label.zappo"));
- zappoColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- zappoColour_actionPerformed(actionEvent);
- }
- });
- taylorColour.setText(MessageManager.getString("label.taylor"));
- taylorColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- taylorColour_actionPerformed(actionEvent);
- }
- });
- hydroColour.setText(MessageManager.getString("label.hydrophobicity"));
- hydroColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- hydroColour_actionPerformed(actionEvent);
- }
- });
- strandColour.setText(MessageManager
- .getString("label.strand_propensity"));
- strandColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- strandColour_actionPerformed(actionEvent);
- }
- });
- helixColour.setText(MessageManager.getString("label.helix_propensity"));
- helixColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- helixColour_actionPerformed(actionEvent);
- }
- });
- turnColour.setText(MessageManager.getString("label.turn_propensity"));
- turnColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- turnColour_actionPerformed(actionEvent);
- }
- });
- buriedColour.setText(MessageManager.getString("label.buried_index"));
- buriedColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- buriedColour_actionPerformed(actionEvent);
- }
- });
- purinePyrimidineColour.setText(MessageManager
- .getString("label.purine_pyrimidine"));
- purinePyrimidineColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- purinePyrimidineColour_actionPerformed(actionEvent);
- }
- });
-
- userColour.setText(MessageManager.getString("action.user_defined"));
- userColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- userColour_actionPerformed(actionEvent);
- }
- });
- viewerColour.setSelected(false);
- viewerColour
- .setText(MessageManager.getString("label.colour_with_jmol"));
- viewerColour.setToolTipText(MessageManager
- .getString("label.let_jmol_manage_structure_colours"));
- viewerColour.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent actionEvent)
- {
- viewerColour_actionPerformed(actionEvent);
- }
- });
-
JMenu helpMenu = new JMenu();
helpMenu.setText(MessageManager.getString("action.help"));
+ helpItem = new JMenuItem();
helpItem.setText(MessageManager.getString("label.jmol_help"));
helpItem.addActionListener(new ActionListener()
{
showHelp_actionPerformed(actionEvent);
}
});
- alignStructs
- .setText(MessageManager.getString("label.align_structures"));
+ alignStructs = new JMenuItem();
+ alignStructs.setText(MessageManager
+ .getString("label.superpose_structures"));
alignStructs.addActionListener(new ActionListener()
{
@Override
alignStructs_actionPerformed(actionEvent);
}
});
- viewerActionMenu.setText(MessageManager.getString("label.jmol"));
- menuBar.add(fileMenu);
- menuBar.add(viewMenu);
- menuBar.add(colourMenu);
- menuBar.add(viewerActionMenu);
+
+ viewerActionMenu = new JMenu(); // text set in sub-classes
viewerActionMenu.setVisible(false);
- menuBar.add(helpMenu);
+ viewerActionMenu.add(alignStructs);
+ colourMenu = new JMenu();
+ colourMenu.setText(MessageManager.getString("label.colours"));
fileMenu.add(savemenu);
fileMenu.add(viewMapping);
savemenu.add(pdbFile);
savemenu.add(png);
savemenu.add(eps);
viewMenu.add(chainMenu);
-
- colourMenu.add(seqColour);
- colourMenu.add(chainColour);
- colourMenu.add(chargeColour);
- colourMenu.add(zappoColour);
- colourMenu.add(taylorColour);
- colourMenu.add(hydroColour);
- colourMenu.add(helixColour);
- colourMenu.add(strandColour);
- colourMenu.add(turnColour);
- colourMenu.add(buriedColour);
- colourMenu.add(purinePyrimidineColour);
- colourMenu.add(userColour);
- colourMenu.add(viewerColour);
- colourMenu.add(backGround);
-
- ButtonGroup colourButtons = new ButtonGroup();
-
- colourButtons.add(seqColour);
- colourButtons.add(chainColour);
- colourButtons.add(chargeColour);
- colourButtons.add(zappoColour);
- colourButtons.add(taylorColour);
- colourButtons.add(hydroColour);
- colourButtons.add(helixColour);
- colourButtons.add(strandColour);
- colourButtons.add(turnColour);
- colourButtons.add(buriedColour);
- colourButtons.add(purinePyrimidineColour);
- colourButtons.add(userColour);
- colourButtons.add(viewerColour);
-
helpMenu.add(helpItem);
- viewerActionMenu.add(alignStructs);
+ menuBar.add(fileMenu);
+ menuBar.add(viewMenu);
+ menuBar.add(colourMenu);
+ menuBar.add(viewerActionMenu);
+ menuBar.add(helpMenu);
+
+ statusPanel = new JPanel();
statusPanel.setLayout(new GridLayout());
- this.getContentPane().add(statusPanel, java.awt.BorderLayout.SOUTH);
+ this.getContentPane().add(statusPanel, BorderLayout.SOUTH);
+ statusBar = new JLabel();
statusPanel.add(statusBar, null);
}
{
}
- protected void alignStructs_actionPerformed(ActionEvent actionEvent)
- {
- }
+ protected abstract String alignStructs_actionPerformed(
+ ActionEvent actionEvent);
public void pdbFile_actionPerformed(ActionEvent actionEvent)
{
}
- public void zappoColour_actionPerformed(ActionEvent actionEvent)
- {
-
- }
-
- public void taylorColour_actionPerformed(ActionEvent actionEvent)
- {
-
- }
-
- public void hydroColour_actionPerformed(ActionEvent actionEvent)
- {
-
- }
-
- public void helixColour_actionPerformed(ActionEvent actionEvent)
- {
-
- }
-
- public void strandColour_actionPerformed(ActionEvent actionEvent)
- {
-
- }
-
- public void turnColour_actionPerformed(ActionEvent actionEvent)
- {
-
- }
-
- public void buriedColour_actionPerformed(ActionEvent actionEvent)
- {
-
- }
-
- public void purinePyrimidineColour_actionPerformed(ActionEvent actionEvent)
- {
-
- }
-
- public void userColour_actionPerformed(ActionEvent actionEvent)
- {
-
- }
-
- public void backGround_actionPerformed(ActionEvent actionEvent)
+ public void background_actionPerformed(ActionEvent actionEvent)
{
}
{
}
-
- // {
- // return bindingModel;
- // }
-
- // public void setBindingModel(AAStructureBindingModel bindingModel)
- // {
- // this.bindingModel = bindingModel;
- // }
-
}
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
import javax.swing.JButton;
import javax.swing.JCheckBox;
protected JCheckBox caseSensitive = new JCheckBox();
- protected JButton lcaseColour = new JButton();
+ protected JCheckBox lcaseColour = new JCheckBox();
+
+ protected List<JButton> selectedButtons;
/**
* Creates a new GUserDefinedColours object.
okButton.setText(MessageManager.getString("action.ok"));
okButton.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
- okButton_actionPerformed(e);
+ okButton_actionPerformed();
}
});
applyButton.setFont(new java.awt.Font("Verdana", 0, 11));
applyButton.setText(MessageManager.getString("action.apply"));
- applyButton.addActionListener(new java.awt.event.ActionListener()
+ applyButton.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
- applyButton_actionPerformed(e);
+ applyButton_actionPerformed();
}
});
loadbutton.setFont(new java.awt.Font("Verdana", 0, 11));
loadbutton.setText(MessageManager.getString("action.load_scheme"));
loadbutton.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
loadbutton_actionPerformed(e);
savebutton.setText(MessageManager.getString("action.save_scheme"));
savebutton.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
savebutton_actionPerformed(e);
cancelButton.setText(MessageManager.getString("action.cancel"));
cancelButton.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
cancelButton_actionPerformed(e);
caseSensitive.setText(MessageManager.getString("label.case_sensitive"));
caseSensitive.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
caseSensitive_actionPerformed(e);
});
lcaseColour
.setText(MessageManager.getString("label.lower_case_colour"));
- lcaseColour.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- lcaseColour_actionPerformed(e);
- }
- });
+ lcaseColour.setToolTipText(MessageManager
+ .getString("label.lower_case_tip"));
saveLoadPanel.add(savebutton);
saveLoadPanel.add(loadbutton);
colorChooser
.setChooserPanels(new AbstractColorChooserPanel[] { choosers[0] });
}
+
+ selectedButtons = new ArrayList<JButton>();
}
/**
* DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
*/
- protected void okButton_actionPerformed(ActionEvent e)
+ protected void okButton_actionPerformed()
{
}
/**
* DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
*/
- protected void applyButton_actionPerformed(ActionEvent e)
+ protected void applyButton_actionPerformed()
{
}
import java.io.PrintStream;
/**
- * DOCUMENT ME!
- *
- * @author $author$
- * @version $Revision$
+ * A class to model rectangular matrices of double values and operations on them
*/
-public class Matrix
+public class Matrix implements MatrixI
{
- /**
- * SMJSPUBLIC
+ /*
+ * the cell values in row-major order
*/
- public double[][] value;
+ private double[][] value;
- /** DOCUMENT ME!! */
- public int rows;
+ /*
+ * the number of rows
+ */
+ protected int rows;
- /** DOCUMENT ME!! */
- public int cols;
+ /*
+ * the number of columns
+ */
+ protected int cols;
- /** DOCUMENT ME!! */
- public double[] d; // Diagonal
+ protected double[] d; // Diagonal
- /** DOCUMENT ME!! */
- public double[] e; // off diagonal
+ protected double[] e; // off diagonal
/**
* maximum number of iterations for tqli
*
*/
- int maxIter = 45; // fudge - add 15 iterations, just in case
+ private static final int maxIter = 45; // fudge - add 15 iterations, just in
+ // case
+
+ /**
+ * Default constructor
+ */
+ public Matrix()
+ {
+ }
+
/**
- * Creates a new Matrix object.
+ * Creates a new Matrix object. For example
*
- * @param value
- * DOCUMENT ME!
- * @param rows
- * DOCUMENT ME!
- * @param cols
- * DOCUMENT ME!
+ * <pre>
+ * new Matrix(new double[][] {{2, 3, 4}, {5, 6, 7})
+ * constructs
+ * (2 3 4)
+ * (5 6 7)
+ * </pre>
+ *
+ * Note that ragged arrays (with not all rows, or columns, of the same
+ * length), are not supported by this class. They can be constructed, but
+ * results of operations on them are undefined and may throw exceptions.
+ *
+ * @param values
+ * the matrix values in row-major order
*/
- public Matrix(double[][] value, int rows, int cols)
+ public Matrix(double[][] values)
{
- this.rows = rows;
- this.cols = cols;
- this.value = value;
+ this.rows = values.length;
+ this.cols = this.rows == 0 ? 0 : values[0].length;
+ this.value = values;
}
/**
- * DOCUMENT ME!
+ * Returns a new matrix which is the transpose of this one
*
* @return DOCUMENT ME!
*/
- public Matrix transpose()
+ @Override
+ public MatrixI transpose()
{
double[][] out = new double[cols][rows];
}
}
- return new Matrix(out, cols, rows);
+ return new Matrix(out);
}
/**
*
* @param ps
* DOCUMENT ME!
+ * @param format
*/
- public void print(PrintStream ps)
+ @Override
+ public void print(PrintStream ps, String format)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
- Format.print(ps, "%8.2f", value[i][j]);
+ Format.print(ps, format, getValue(i, j));
}
ps.println();
}
/**
- * DOCUMENT ME!
+ * Returns a new matrix which is the result of premultiplying this matrix by
+ * the supplied argument. If this of size AxB (A rows and B columns), and the
+ * argument is CxA (C rows and A columns), the result is of size CxB.
*
* @param in
- * DOCUMENT ME!
*
- * @return DOCUMENT ME!
+ * @return
+ * @throws IllegalArgumentException
+ * if the number of columns in the pre-multiplier is not equal to
+ * the number of rows in the multiplicand (this)
*/
- public Matrix preMultiply(Matrix in)
+ @Override
+ public MatrixI preMultiply(MatrixI in)
{
- double[][] tmp = new double[in.rows][this.cols];
+ if (in.width() != rows)
+ {
+ throw new IllegalArgumentException("Can't pre-multiply " + this.rows
+ + " rows by " + in.width() + " columns");
+ }
+ double[][] tmp = new double[in.height()][this.cols];
- for (int i = 0; i < in.rows; i++)
+ for (int i = 0; i < in.height(); i++)
{
for (int j = 0; j < this.cols; j++)
{
- tmp[i][j] = 0.0;
-
- for (int k = 0; k < in.cols; k++)
+ /*
+ * result[i][j] is the vector product of
+ * in.row[i] and this.column[j]
+ */
+ for (int k = 0; k < in.width(); k++)
{
- tmp[i][j] += (in.value[i][k] * this.value[k][j]);
+ tmp[i][j] += (in.getValue(i, k) * this.value[k][j]);
}
}
}
- return new Matrix(tmp, in.rows, this.cols);
+ return new Matrix(tmp);
}
/**
- * DOCUMENT ME!
*
* @param in
- * DOCUMENT ME!
*
- * @return DOCUMENT ME!
+ * @return
*/
public double[] vectorPostMultiply(double[] in)
{
}
/**
- * DOCUMENT ME!
+ * Returns a new matrix which is the result of postmultiplying this matrix by
+ * the supplied argument. If this of size AxB (A rows and B columns), and the
+ * argument is BxC (B rows and C columns), the result is of size AxC.
+ * <p>
+ * This method simply returns the result of in.preMultiply(this)
*
* @param in
- * DOCUMENT ME!
*
- * @return DOCUMENT ME!
+ * @return
+ * @throws IllegalArgumentException
+ * if the number of rows in the post-multiplier is not equal to the
+ * number of columns in the multiplicand (this)
+ * @see #preMultiply(Matrix)
*/
- public Matrix postMultiply(Matrix in)
+ @Override
+ public MatrixI postMultiply(MatrixI in)
{
- double[][] out = new double[this.rows][in.cols];
-
- for (int i = 0; i < this.rows; i++)
+ if (in.height() != this.cols)
{
- for (int j = 0; j < in.cols; j++)
- {
- out[i][j] = 0.0;
-
- for (int k = 0; k < rows; k++)
- {
- out[i][j] = out[i][j] + (value[i][k] * in.value[k][j]);
- }
- }
+ throw new IllegalArgumentException("Can't post-multiply " + this.cols
+ + " columns by " + in.height() + " rows");
}
-
- return new Matrix(out, this.cols, in.rows);
+ return in.preMultiply(this);
}
/**
- * DOCUMENT ME!
+ * Answers a new matrix with a copy of the values in this one
*
- * @return DOCUMENT ME!
+ * @return
*/
- public Matrix copy()
+ @Override
+ public MatrixI copy()
{
double[][] newmat = new double[rows][cols];
for (int i = 0; i < rows; i++)
{
- for (int j = 0; j < cols; j++)
- {
- newmat[i][j] = value[i][j];
- }
+ System.arraycopy(value[i], 0, newmat[i], 0, value[i].length);
}
- return new Matrix(newmat, rows, cols);
+ return new Matrix(newmat);
}
/**
* DOCUMENT ME!
*/
+ @Override
public void tred()
{
int n = rows;
- int l;
int k;
int j;
int i;
for (i = n; i >= 2; i--)
{
- l = i - 1;
+ final int l = i - 1;
h = 0.0;
scale = 0.0;
{
for (k = 1; k <= l; k++)
{
- scale += Math.abs(value[i - 1][k - 1]);
+ double v = Math.abs(getValue(i - 1, k - 1));
+ scale += v;
}
if (scale == 0.0)
{
- e[i - 1] = value[i - 1][l - 1];
+ e[i - 1] = getValue(i - 1, l - 1);
}
else
{
for (k = 1; k <= l; k++)
{
- value[i - 1][k - 1] /= scale;
- h += (value[i - 1][k - 1] * value[i - 1][k - 1]);
+ double v = divideValue(i - 1, k - 1, scale);
+ h += v * v;
}
- f = value[i - 1][l - 1];
+ f = getValue(i - 1, l - 1);
if (f > 0)
{
e[i - 1] = scale * g;
h -= (f * g);
- value[i - 1][l - 1] = f - g;
+ setValue(i - 1, l - 1, f - g);
f = 0.0;
for (j = 1; j <= l; j++)
{
- value[j - 1][i - 1] = value[i - 1][j - 1] / h;
+ double val = getValue(i - 1, j - 1) / h;
+ setValue(j - 1, i - 1, val);
g = 0.0;
for (k = 1; k <= j; k++)
{
- g += (value[j - 1][k - 1] * value[i - 1][k - 1]);
+ g += (getValue(j - 1, k - 1) * getValue(i - 1, k - 1));
}
for (k = j + 1; k <= l; k++)
{
- g += (value[k - 1][j - 1] * value[i - 1][k - 1]);
+ g += (getValue(k - 1, j - 1) * getValue(i - 1, k - 1));
}
e[j - 1] = g / h;
- f += (e[j - 1] * value[i - 1][j - 1]);
+ f += (e[j - 1] * getValue(i - 1, j - 1));
}
hh = f / (h + h);
for (j = 1; j <= l; j++)
{
- f = value[i - 1][j - 1];
+ f = getValue(i - 1, j - 1);
g = e[j - 1] - (hh * f);
e[j - 1] = g;
for (k = 1; k <= j; k++)
{
- value[j - 1][k - 1] -= ((f * e[k - 1]) + (g * value[i - 1][k - 1]));
+ double val = (f * e[k - 1]) + (g * getValue(i - 1, k - 1));
+ addValue(j - 1, k - 1, -val);
}
}
}
}
else
{
- e[i - 1] = value[i - 1][l - 1];
+ e[i - 1] = getValue(i - 1, l - 1);
}
d[i - 1] = h;
for (i = 1; i <= n; i++)
{
- l = i - 1;
+ final int l = i - 1;
if (d[i - 1] != 0.0)
{
for (k = 1; k <= l; k++)
{
- g += (value[i - 1][k - 1] * value[k - 1][j - 1]);
+ g += (getValue(i - 1, k - 1) * getValue(k - 1, j - 1));
}
for (k = 1; k <= l; k++)
{
- value[k - 1][j - 1] -= (g * value[k - 1][i - 1]);
+ addValue(k - 1, j - 1, -(g * getValue(k - 1, i - 1)));
}
}
}
- d[i - 1] = value[i - 1][i - 1];
- value[i - 1][i - 1] = 1.0;
+ d[i - 1] = getValue(i - 1, i - 1);
+ setValue(i - 1, i - 1, 1.0);
for (j = 1; j <= l; j++)
{
- value[j - 1][i - 1] = 0.0;
- value[i - 1][j - 1] = 0.0;
+ setValue(j - 1, i - 1, 0.0);
+ setValue(i - 1, j - 1, 0.0);
}
}
}
/**
+ * Adds f to the value at [i, j] and returns the new value
+ *
+ * @param i
+ * @param j
+ * @param f
+ */
+ protected double addValue(int i, int j, double f)
+ {
+ double v = value[i][j] + f;
+ value[i][j] = v;
+ return v;
+ }
+
+ /**
+ * Divides the value at [i, j] by divisor and returns the new value. If d is
+ * zero, returns the unchanged value.
+ *
+ * @param i
+ * @param j
+ * @param divisor
+ * @return
+ */
+ protected double divideValue(int i, int j, double divisor)
+ {
+ if (divisor == 0d)
+ {
+ return getValue(i, j);
+ }
+ double v = value[i][j];
+ v = v / divisor;
+ value[i][j] = v;
+ return v;
+ }
+
+ /**
* DOCUMENT ME!
*/
+ @Override
public void tqli() throws Exception
{
int n = rows;
double s;
double r;
double p;
- ;
double g;
double f;
for (k = 1; k <= n; k++)
{
- f = value[k - 1][i];
- value[k - 1][i] = (s * value[k - 1][i - 1]) + (c * f);
- value[k - 1][i - 1] = (c * value[k - 1][i - 1]) - (s * f);
+ f = getValue(k - 1, i);
+ setValue(k - 1, i, (s * getValue(k - 1, i - 1)) + (c * f));
+ setValue(k - 1, i - 1, (c * getValue(k - 1, i - 1)) - (s * f));
}
}
}
}
+ @Override
+ public double getValue(int i, int j)
+ {
+ return value[i][j];
+ }
+
+ public void setValue(int i, int j, double val)
+ {
+ value[i][j] = val;
+ }
+
/**
* DOCUMENT ME!
*/
}
/**
- * DOCUMENT ME!
+ * Answers the first argument with the sign of the second argument
*
* @param a
- * DOCUMENT ME!
* @param b
- * DOCUMENT ME!
*
- * @return DOCUMENT ME!
+ * @return
*/
- public double sign(double a, double b)
+ static double sign(double a, double b)
{
if (b < 0)
{
}
/**
- * DOCUMENT ME!
+ * Returns an array containing the values in the specified column
*
- * @param n
- * DOCUMENT ME!
+ * @param col
*
- * @return DOCUMENT ME!
+ * @return
*/
- public double[] getColumn(int n)
+ public double[] getColumn(int col)
{
double[] out = new double[rows];
for (int i = 0; i < rows; i++)
{
- out[i] = value[i][n];
+ out[i] = value[i][col];
}
return out;
*
* @param ps
* DOCUMENT ME!
+ * @param format
*/
- public void printD(PrintStream ps)
+ @Override
+ public void printD(PrintStream ps, String format)
{
for (int j = 0; j < rows; j++)
{
- Format.print(ps, "%15.4e", d[j]);
+ Format.print(ps, format, d[j]);
}
}
*
* @param ps
* DOCUMENT ME!
+ * @param format TODO
*/
- public void printE(PrintStream ps)
+ @Override
+ public void printE(PrintStream ps, String format)
{
for (int j = 0; j < rows; j++)
{
- Format.print(ps, "%15.4e", e[j]);
+ Format.print(ps, format, e[j]);
}
}
- /**
- * DOCUMENT ME!
- *
- * @param args
- * DOCUMENT ME!
- */
- public static void main(String[] args) throws Exception
+ @Override
+ public double[] getD()
+ {
+ return d;
+ }
+
+ @Override
+ public double[] getE()
{
- int n = Integer.parseInt(args[0]);
- double[][] in = new double[n][n];
+ return e;
+ }
+
+ @Override
+ public int height() {
+ return rows;
+ }
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < n; j++)
- {
- in[i][j] = (double) Math.random();
- }
- }
+ @Override
+ public int width()
+ {
+ return cols;
+ }
- Matrix origmat = new Matrix(in, n, n);
-
- // System.out.println(" --- Original matrix ---- ");
- // / origmat.print(System.out);
- // System.out.println();
- // System.out.println(" --- transpose matrix ---- ");
- Matrix trans = origmat.transpose();
-
- // trans.print(System.out);
- // System.out.println();
- // System.out.println(" --- OrigT * Orig ---- ");
- Matrix symm = trans.postMultiply(origmat);
-
- // symm.print(System.out);
- // System.out.println();
- // Copy the symmetric matrix for later
- // Matrix origsymm = symm.copy();
-
- // This produces the tridiagonal transformation matrix
- // long tstart = System.currentTimeMillis();
- symm.tred();
-
- // long tend = System.currentTimeMillis();
-
- // System.out.println("Time take for tred = " + (tend-tstart) + "ms");
- // System.out.println(" ---Tridiag transform matrix ---");
- // symm.print(System.out);
- // System.out.println();
- // System.out.println(" --- D vector ---");
- // symm.printD(System.out);
- // System.out.println();
- // System.out.println(" --- E vector ---");
- // symm.printE(System.out);
- // System.out.println();
- // Now produce the diagonalization matrix
- // tstart = System.currentTimeMillis();
- symm.tqli();
- // tend = System.currentTimeMillis();
-
- // System.out.println("Time take for tqli = " + (tend-tstart) + " ms");
- // System.out.println(" --- New diagonalization matrix ---");
- // symm.print(System.out);
- // System.out.println();
- // System.out.println(" --- D vector ---");
- // symm.printD(System.out);
- // System.out.println();
- // System.out.println(" --- E vector ---");
- // symm.printE(System.out);
- // System.out.println();
- // System.out.println(" --- First eigenvector --- ");
- // double[] eigenv = symm.getColumn(0);
- // for (int i=0; i < eigenv.length;i++) {
- // Format.print(System.out,"%15.4f",eigenv[i]);
- // }
- // System.out.println();
- // double[] neigenv = origsymm.vectorPostMultiply(eigenv);
- // for (int i=0; i < neigenv.length;i++) {
- // Format.print(System.out,"%15.4f",neigenv[i]/symm.d[0]);
- // }
- // System.out.println();
+ @Override
+ public double[] getRow(int i)
+ {
+ double[] row = new double[cols];
+ System.arraycopy(value[i], 0, row, 0, cols);
+ return row;
}
}
--- /dev/null
+package jalview.math;
+
+import java.io.PrintStream;
+
+public interface MatrixI
+{
+ /**
+ * Answers the number of columns
+ *
+ * @return
+ */
+ int width();
+
+ /**
+ * Answers the number of rows
+ *
+ * @return
+ */
+ int height();
+
+ /**
+ * Answers the value at row i, column j
+ *
+ * @param i
+ * @param j
+ * @return
+ */
+ double getValue(int i, int j);
+
+ /**
+ * Answers a copy of the values in the i'th row
+ *
+ * @return
+ */
+ double[] getRow(int i);
+
+ MatrixI copy();
+
+ MatrixI transpose();
+
+ MatrixI preMultiply(MatrixI m);
+
+ MatrixI postMultiply(MatrixI m);
+
+ double[] getD();
+
+ double[] getE();
+
+ void print(PrintStream ps, String format);
+
+ void printD(PrintStream ps, String format);
+
+ void printE(PrintStream ps, String format);
+
+ void tqli() throws Exception;
+
+ void tred();
+
+}
--- /dev/null
+package jalview.math;
+
+import jalview.ext.android.SparseDoubleArray;
+
+/**
+ * A variant of Matrix intended for use for sparse (mostly zero) matrices. This
+ * class uses a SparseDoubleArray to hold each row of the matrix. The sparse
+ * array only stores non-zero values. This gives a smaller memory footprint, and
+ * fewer matrix calculation operations, for mostly zero matrices.
+ *
+ * @author gmcarstairs
+ */
+public class SparseMatrix extends Matrix
+{
+ /*
+ * we choose columns for the sparse arrays as this allows
+ * optimisation of the preMultiply() method used in PCA.run()
+ */
+ SparseDoubleArray[] sparseColumns;
+
+ /**
+ * Constructor given data in [row][column] order
+ *
+ * @param v
+ */
+ public SparseMatrix(double[][] v)
+ {
+ rows = v.length;
+ if (rows > 0) {
+ cols = v[0].length;
+ }
+ sparseColumns = new SparseDoubleArray[cols];
+
+ /*
+ * transpose v[row][col] into [col][row] order
+ */
+ for (int col = 0; col < cols; col++)
+ {
+ SparseDoubleArray sparseColumn = new SparseDoubleArray();
+ sparseColumns[col] = sparseColumn;
+ for (int row = 0; row < rows; row++)
+ {
+ double value = v[row][col];
+ if (value != 0d)
+ {
+ sparseColumn.put(row, value);
+ }
+ }
+ }
+ }
+
+ /**
+ * Answers the value at row i, column j
+ */
+ @Override
+ public double getValue(int i, int j)
+ {
+ return sparseColumns[j].get(i);
+ }
+
+ /**
+ * Sets the value at row i, column j to val
+ */
+ @Override
+ public void setValue(int i, int j, double val)
+ {
+ if (val == 0d)
+ {
+ sparseColumns[j].delete(i);
+ }
+ else
+ {
+ sparseColumns[j].put(i, val);
+ }
+ }
+
+ @Override
+ public double[] getColumn(int i)
+ {
+ double[] col = new double[height()];
+
+ SparseDoubleArray vals = sparseColumns[i];
+ for (int nonZero = 0; nonZero < vals.size(); nonZero++)
+ {
+ col[vals.keyAt(nonZero)] = vals.valueAt(nonZero);
+ }
+ return col;
+ }
+
+ @Override
+ public MatrixI copy()
+ {
+ double[][] vals = new double[height()][width()];
+ for (int i = 0; i < height(); i++)
+ {
+ vals[i] = getRow(i);
+ }
+ return new SparseMatrix(vals);
+ }
+
+ @Override
+ public MatrixI transpose()
+ {
+ double[][] out = new double[cols][rows];
+
+ /*
+ * for each column...
+ */
+ for (int i = 0; i < cols; i++)
+ {
+ /*
+ * put non-zero values into the corresponding row
+ * of the transposed matrix
+ */
+ SparseDoubleArray vals = sparseColumns[i];
+ for (int nonZero = 0; nonZero < vals.size(); nonZero++)
+ {
+ out[i][vals.keyAt(nonZero)] = vals.valueAt(nonZero);
+ }
+ }
+
+ return new SparseMatrix(out);
+ }
+
+ /**
+ * Answers a new matrix which is the product in.this. If the product contains
+ * less than 20% non-zero values, it is returned as a SparseMatrix, else as a
+ * Matrix.
+ * <p>
+ * This method is optimised for the sparse arrays which store column values
+ * for a SparseMatrix. Note that postMultiply is not so optimised. That would
+ * require redundantly also storing sparse arrays for the rows, which has not
+ * been done. Currently only preMultiply is used in Jalview.
+ */
+ @Override
+ public MatrixI preMultiply(MatrixI in)
+ {
+ if (in.width() != rows)
+ {
+ throw new IllegalArgumentException("Can't pre-multiply " + this.rows
+ + " rows by " + in.width() + " columns");
+ }
+ double[][] tmp = new double[in.height()][this.cols];
+
+ long count = 0L;
+ for (int i = 0; i < in.height(); i++)
+ {
+ for (int j = 0; j < this.cols; j++)
+ {
+ /*
+ * result[i][j] is the vector product of
+ * in.row[i] and this.column[j]
+ * we only need to use non-zero values from the column
+ */
+ SparseDoubleArray vals = sparseColumns[j];
+ boolean added = false;
+ for (int nonZero = 0; nonZero < vals.size(); nonZero++)
+ {
+ int myRow = vals.keyAt(nonZero);
+ double myValue = vals.valueAt(nonZero);
+ tmp[i][j] += (in.getValue(i, myRow) * myValue);
+ added = true;
+ }
+ if (added && tmp[i][j] != 0d)
+ {
+ count++; // non-zero entry in product
+ }
+ }
+ }
+
+ /*
+ * heuristic rule - if product is more than 80% zero
+ * then construct a SparseMatrix, else a Matrix
+ */
+ if (count * 5 < in.height() * cols)
+ {
+ return new SparseMatrix(tmp);
+ }
+ else
+ {
+ return new Matrix(tmp);
+ }
+ }
+
+ @Override
+ protected double divideValue(int i, int j, double divisor)
+ {
+ if (divisor == 0d)
+ {
+ return getValue(i, j);
+ }
+ double v = sparseColumns[j].divide(i, divisor);
+ return v;
+ }
+
+ @Override
+ protected double addValue(int i, int j, double addend)
+ {
+ double v = sparseColumns[j].add(i, addend);
+ return v;
+ }
+
+ /**
+ * Returns the fraction of the whole matrix size that is actually modelled in
+ * sparse arrays (normally, the non-zero values)
+ *
+ * @return
+ */
+ public float getFillRatio()
+ {
+ long count = 0L;
+ for (SparseDoubleArray col : sparseColumns)
+ {
+ count += col.size();
+ }
+ return count / (float) (height() * width());
+ }
+}
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.ProfilesI;
import jalview.schemes.ColourSchemeI;
+import jalview.schemes.NucleotideColourScheme;
import jalview.schemes.ResidueProperties;
+import jalview.schemes.ZappoColourScheme;
import jalview.util.Platform;
import java.awt.BasicStroke;
boolean av_renderHistogram = true, av_renderProfile = true,
av_normaliseProfile = false;
- ColourSchemeI profcolour = null;
+ ResidueShaderI profcolour = null;
private ColumnSelection columnSelection;
av_renderHistogram = av.isShowConsensusHistogram();
av_renderProfile = av.isShowSequenceLogo();
av_normaliseProfile = av.isNormaliseSequenceLogo();
- profcolour = av.getGlobalColourScheme();
- if (profcolour == null)
+ profcolour = av.getResidueShading();
+ if (profcolour == null || profcolour.getColourScheme() == null)
{
- // Set the default colour for sequence logo if the alignnent has no
- // colourscheme set
- profcolour = av.getAlignment().isNucleotide() ? new jalview.schemes.NucleotideColourScheme()
- : new jalview.schemes.ZappoColourScheme();
+ /*
+ * Use default colour for sequence logo if
+ * the alignment has no colourscheme set
+ * (would like to use user preference but n/a for applet)
+ */
+ ColourSchemeI col = av.getAlignment().isNucleotide() ? new NucleotideColourScheme()
+ : new ZappoColourScheme();
+ profcolour = new ResidueShader(col);
}
columnSelection = av.getColumnSelection();
hconsensus = av.getSequenceConsensusHash();
--- /dev/null
+package jalview.renderer;
+
+import jalview.analysis.Conservation;
+import jalview.api.ViewStyleI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+import jalview.schemes.ColourSchemeI;
+import jalview.util.ColorUtils;
+import jalview.util.Comparison;
+
+import java.awt.Color;
+import java.util.Map;
+
+/**
+ * A class that computes the colouring of an alignment (or subgroup). Currently
+ * the factors that may influence residue colouring are
+ * <ul>
+ * <li>the colour scheme that provides a colour for each aligned residue</li>
+ * <li>any threshold for colour, based on percentage identity with consensus</li>
+ * <li>any graduation based on conservation of physico-chemical properties</li>
+ * </ul>
+ *
+ * @author gmcarstairs
+ *
+ */
+public class ResidueShader implements ResidueShaderI
+{
+ private static final int INITIAL_CONSERVATION = 30;
+
+ /*
+ * the colour scheme that gives the colour of each residue
+ * before applying any conservation or PID shading
+ */
+ private ColourSchemeI colourScheme;
+
+ /*
+ * the consensus data for each column
+ */
+ private ProfilesI consensus;
+
+ /*
+ * if true, apply shading of colour by conservation
+ */
+ private boolean conservationColouring;
+
+ /*
+ * the physico-chemical property conservation scores for columns, with values
+ * 0-9, '+' (all properties conserved), '*' (residue fully conserved) or '-' (gap)
+ * (may be null if colour by conservation is not selected)
+ */
+ private char[] conservation;
+
+ /*
+ * minimum percentage identity for colour to be applied;
+ * if above zero, residue must match consensus (or joint consensus)
+ * and column have >= pidThreshold identity with the residue
+ */
+ private int pidThreshold;
+
+ /*
+ * if true, ignore gaps in percentage identity calculation
+ */
+ private boolean ignoreGaps;
+
+ /*
+ * setting of the By Conservation slider
+ */
+ private int conservationIncrement = INITIAL_CONSERVATION;
+
+ public ResidueShader(ColourSchemeI cs)
+ {
+ colourScheme = cs;
+ }
+
+ /**
+ * Default constructor
+ */
+ public ResidueShader()
+ {
+ }
+
+ /**
+ * Constructor given view style settings
+ *
+ * @param viewStyle
+ */
+ public ResidueShader(ViewStyleI viewStyle)
+ {
+ // TODO remove duplicated storing of conservation / pid thresholds?
+ this();
+ setConservationApplied(viewStyle.isConservationColourSelected());
+ // setThreshold(viewStyle.getThreshold());
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#setConsensus(jalview.datamodel.ProfilesI)
+ */
+ @Override
+ public void setConsensus(ProfilesI cons)
+ {
+ consensus = cons;
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#conservationApplied()
+ */
+ @Override
+ public boolean conservationApplied()
+ {
+ return conservationColouring;
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#setConservationApplied(boolean)
+ */
+ @Override
+ public void setConservationApplied(boolean conservationApplied)
+ {
+ conservationColouring = conservationApplied;
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#setConservation(jalview.analysis.Conservation)
+ */
+ @Override
+ public void setConservation(Conservation cons)
+ {
+ if (cons == null)
+ {
+ conservationColouring = false;
+ conservation = null;
+ }
+ else
+ {
+ conservationColouring = true;
+ conservation = cons.getConsSequence().getSequenceAsString()
+ .toCharArray();
+ }
+
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#alignmentChanged(jalview.datamodel.AnnotatedCollectionI,
+ * java.util.Map)
+ */
+ @Override
+ public void alignmentChanged(AnnotatedCollectionI alignment,
+ Map<SequenceI, SequenceCollectionI> hiddenReps)
+ {
+ if (colourScheme != null)
+ {
+ colourScheme.alignmentChanged(alignment, hiddenReps);
+ }
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#setThreshold(int, boolean)
+ */
+ @Override
+ public void setThreshold(int consensusThreshold, boolean ignoreGaps)
+ {
+ pidThreshold = consensusThreshold;
+ this.ignoreGaps = ignoreGaps;
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#setConservationInc(int)
+ */
+ @Override
+ public void setConservationInc(int i)
+ {
+ conservationIncrement = i;
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#getConservationInc()
+ */
+ @Override
+ public int getConservationInc()
+ {
+ return conservationIncrement;
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#getThreshold()
+ */
+ @Override
+ public int getThreshold()
+ {
+ return pidThreshold;
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#findColour(char, int,
+ * jalview.datamodel.SequenceI)
+ */
+ @Override
+ public Color findColour(char symbol, int position, SequenceI seq)
+ {
+ /*
+ * get 'base' colour
+ */
+ ProfileI profile = consensus == null ? null : consensus.get(position);
+ String modalResidue = profile == null ? null : profile
+ .getModalResidue();
+ float pid = profile == null ? 0f : profile
+ .getPercentageIdentity(ignoreGaps);
+ Color colour = colourScheme == null ? Color.white : colourScheme
+ .findColour(symbol, position, seq, modalResidue, pid);
+
+ /*
+ * apply PID threshold and consensus fading if in force
+ */
+ colour = adjustColour(symbol, position, colour);
+
+ return colour;
+ }
+
+ /**
+ * Adjusts colour by applying thresholding or conservation shading, if in
+ * force. That is
+ * <ul>
+ * <li>if there is a threshold set for colouring, and the residue doesn't
+ * match the consensus (or a joint consensus) residue, or the consensus score
+ * is not above the threshold, then the colour is set to white</li>
+ * <li>if conservation colouring is selected, the colour is faded by an amount
+ * depending on the conservation score for the column, and the conservation
+ * colour threshold</li>
+ * </ul>
+ *
+ * @param symbol
+ * @param column
+ * @param colour
+ * @return
+ */
+ protected Color adjustColour(char symbol, int column, Color colour)
+ {
+ if (!aboveThreshold(symbol, column))
+ {
+ colour = Color.white;
+ }
+
+ if (conservationColouring)
+ {
+ colour = applyConservation(colour, column);
+ }
+ return colour;
+ }
+
+ /**
+ * Answers true if there is a consensus profile for the specified column, and
+ * the given residue matches the consensus (or joint consensus) residue for
+ * the column, and the percentage identity for the profile is equal to or
+ * greater than the current threshold; else answers false. The percentage
+ * calculation depends on whether or not we are ignoring gapped sequences.
+ *
+ * @param residue
+ * @param column
+ * (index into consensus profiles)
+ *
+ * @return
+ * @see #setThreshold(int, boolean)
+ */
+ protected boolean aboveThreshold(char residue, int column)
+ {
+ if (pidThreshold == 0)
+ {
+ return true;
+ }
+ if ('a' <= residue && residue <= 'z')
+ {
+ // TO UPPERCASE !!!
+ // Faster than toUpperCase
+ residue -= ('a' - 'A');
+ }
+
+ if (consensus == null)
+ {
+ return false;
+ }
+
+ ProfileI profile = consensus.get(column);
+
+ /*
+ * test whether this is the consensus (or joint consensus) residue
+ */
+ if (profile != null
+ && profile.getModalResidue().contains(String.valueOf(residue)))
+ {
+ if (profile.getPercentageIdentity(ignoreGaps) >= pidThreshold)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Applies a combination of column conservation score, and conservation
+ * percentage slider, to 'bleach' out the residue colours towards white.
+ * <p>
+ * If a column is fully conserved (identical residues, conservation score 11,
+ * shown as *), or all 10 physico-chemical properties are conserved
+ * (conservation score 10, shown as +), then the colour is left unchanged.
+ * <p>
+ * Otherwise a 'bleaching' factor is computed and applied to the colour. This
+ * is designed to fade colours for scores of 0-9 completely to white at slider
+ * positions ranging from 18% - 100% respectively.
+ *
+ * @param currentColour
+ * @param column
+ *
+ * @return bleached (or unmodified) colour
+ */
+ protected Color applyConservation(Color currentColour, int column)
+ {
+ if (conservation == null || conservation.length <= column)
+ {
+ return currentColour;
+ }
+ char conservationScore = conservation[column];
+
+ /*
+ * if residues are fully conserved (* or 11), or all properties
+ * are conserved (+ or 10), leave colour unchanged
+ */
+ if (conservationScore == '*' || conservationScore == '+'
+ || conservationScore == (char) 10
+ || conservationScore == (char) 11)
+ {
+ return currentColour;
+ }
+
+ if (Comparison.isGap(conservationScore))
+ {
+ return Color.white;
+ }
+
+ /*
+ * convert score 0-9 to a bleaching factor 1.1 - 0.2
+ */
+ float bleachFactor = (11 - (conservationScore - '0')) / 10f;
+
+ /*
+ * scale this up by 0-5 (percentage slider / 20)
+ * as a result, scores of: 0 1 2 3 4 5 6 7 8 9
+ * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100%
+ */
+ bleachFactor *= (conservationIncrement / 20f);
+
+ return ColorUtils.bleachColour(currentColour, bleachFactor);
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#getColourScheme()
+ */
+ @Override
+ public ColourSchemeI getColourScheme()
+ {
+ return this.colourScheme;
+ }
+
+ /**
+ * @see jalview.renderer.ResidueShaderI#setColourScheme(jalview.schemes.ColourSchemeI)
+ */
+ @Override
+ public void setColourScheme(ColourSchemeI cs)
+ {
+ colourScheme = cs;
+ }
+}
--- /dev/null
+package jalview.renderer;
+
+import jalview.analysis.Conservation;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+import jalview.schemes.ColourSchemeI;
+
+import java.awt.Color;
+import java.util.Map;
+
+public interface ResidueShaderI
+{
+
+ public abstract void setConsensus(ProfilesI cons);
+
+ public abstract boolean conservationApplied();
+
+ public abstract void setConservationApplied(boolean conservationApplied);
+
+ public abstract void setConservation(Conservation cons);
+
+ public abstract void alignmentChanged(AnnotatedCollectionI alignment,
+ Map<SequenceI, SequenceCollectionI> hiddenReps);
+
+ /**
+ * Sets the percentage consensus threshold value, and whether gaps are ignored
+ * in percentage identity calculation
+ *
+ * @param consensusThreshold
+ * @param ignoreGaps
+ */
+ public abstract void setThreshold(int consensusThreshold,
+ boolean ignoreGaps);
+
+ public abstract void setConservationInc(int i);
+
+ public abstract int getConservationInc();
+
+ /**
+ * Get the percentage threshold for this colour scheme
+ *
+ * @return Returns the percentage threshold
+ */
+ public abstract int getThreshold();
+
+ /**
+ * Returns the possibly context dependent colour for the given symbol at the
+ * aligned position in the given sequence. For example, the colour may depend
+ * on the symbol's relationship to the consensus residue for the column.
+ *
+ * @param symbol
+ * @param position
+ * @param seq
+ * @return
+ */
+ public abstract Color findColour(char symbol, int position, SequenceI seq);
+
+ public abstract ColourSchemeI getColourScheme();
+
+ public abstract void setColourScheme(ColourSchemeI cs);
+
+}
\ No newline at end of file
IdentityHashMap<SequenceI, AlignmentAnnotation> seqannot = null;
@Override
- public ColourSchemeI applyTo(AnnotatedCollectionI sg,
+ public ColourSchemeI getInstance(AnnotatedCollectionI sg,
Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
{
AnnotationColourGradient acg = new AnnotationColourGradient(annotation,
- colourScheme, aboveAnnotationThreshold);
+ getColourScheme(), aboveAnnotationThreshold);
acg.thresholdIsMinMax = thresholdIsMinMax;
acg.annotationThreshold = (annotationThreshold == null) ? null
: new GraphLine(annotationThreshold);
{
if (originalColour instanceof AnnotationColourGradient)
{
- colourScheme = ((AnnotationColourGradient) originalColour).colourScheme;
+ setColourScheme(((AnnotationColourGradient) originalColour)
+ .getColourScheme());
}
else
{
- colourScheme = originalColour;
+ setColourScheme(originalColour);
}
this.annotation = annotation;
*
* @return DOCUMENT ME!
*/
+ @Override
public Color findColour(char c)
{
return Color.red;
{
return currentColour;
}
- if ((threshold == 0) || aboveThreshold(c, j))
+ // if ((threshold == 0) || aboveThreshold(c, j))
+ // {
+ if (annotation.annotations != null && j < annotation.annotations.length
+ && annotation.annotations[j] != null
+ && !jalview.util.Comparison.isGap(c))
{
- if (annotation.annotations != null
- && j < annotation.annotations.length
- && annotation.annotations[j] != null
- && !jalview.util.Comparison.isGap(c))
+ Annotation aj = annotation.annotations[j];
+ // 'use original colours' => colourScheme != null
+ // -> look up colour to be used
+ // predefined colours => preconfigured shading
+ // -> only use original colours reference if thresholding enabled &
+ // minmax exists
+ // annotation.hasIcons => null or black colours replaced with glyph
+ // colours
+ // -> reuse original colours if present
+ // -> if thresholding enabled then return colour on non-whitespace glyph
+
+ if (aboveAnnotationThreshold == NO_THRESHOLD
+ || (annotationThreshold != null && (aboveAnnotationThreshold == ABOVE_THRESHOLD ? aj.value >= annotationThreshold.value
+ : aj.value <= annotationThreshold.value)))
{
- Annotation aj = annotation.annotations[j];
- // 'use original colours' => colourScheme != null
- // -> look up colour to be used
- // predefined colours => preconfigured shading
- // -> only use original colours reference if thresholding enabled &
- // minmax exists
- // annotation.hasIcons => null or black colours replaced with glyph
- // colours
- // -> reuse original colours if present
- // -> if thresholding enabled then return colour on non-whitespace glyph
-
- if (aboveAnnotationThreshold == NO_THRESHOLD
- || (annotationThreshold != null && (aboveAnnotationThreshold == ABOVE_THRESHOLD ? aj.value >= annotationThreshold.value
- : aj.value <= annotationThreshold.value)))
+ if (predefinedColours && aj.colour != null
+ && !aj.colour.equals(Color.black))
{
- if (predefinedColours && aj.colour != null
- && !aj.colour.equals(Color.black))
- {
- currentColour = aj.colour;
- }
- else if (annotation.hasIcons
- && annotation.graph == AlignmentAnnotation.NO_GRAPH)
+ currentColour = aj.colour;
+ }
+ else if (annotation.hasIcons
+ && annotation.graph == AlignmentAnnotation.NO_GRAPH)
+ {
+ if (aj.secondaryStructure > ' ' && aj.secondaryStructure != '.'
+ && aj.secondaryStructure != '-')
{
- if (aj.secondaryStructure > ' ' && aj.secondaryStructure != '.'
- && aj.secondaryStructure != '-')
+ if (getColourScheme() != null)
{
- if (colourScheme != null)
+ currentColour = getColourScheme().findColour(c, j, seq, null,
+ 0f);
+ }
+ else
+ {
+ if (annotation.isRNA())
{
- currentColour = colourScheme.findColour(c, j, seq);
+ currentColour = ColourSchemeProperty.rnaHelices[(int) aj.value];
}
else
{
- if (annotation.isRNA())
- {
- currentColour = ColourSchemeProperty.rnaHelices[(int) aj.value];
- }
- else
- {
- currentColour = annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR
- : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR
- : jalview.renderer.AnnotationRenderer.STEM_COLOUR;
- }
+ currentColour = annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR
+ : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR
+ : jalview.renderer.AnnotationRenderer.STEM_COLOUR;
}
}
- else
- {
- //
- return Color.white;
- }
}
- else if (noGradient)
+ else
{
- if (colourScheme != null)
- {
- currentColour = colourScheme.findColour(c, j, seq);
- }
- else
- {
- if (aj.colour != null)
- {
- currentColour = aj.colour;
- }
- }
+ //
+ return Color.white;
+ }
+ }
+ else if (noGradient)
+ {
+ if (getColourScheme() != null)
+ {
+ currentColour = getColourScheme().findColour(c, j, seq, null,
+ 0f);
}
else
{
- currentColour = shadeCalculation(annotation, j);
+ if (aj.colour != null)
+ {
+ currentColour = aj.colour;
+ }
}
}
- if (conservationColouring)
+ else
{
- currentColour = applyConservation(currentColour, j);
+ currentColour = shadeCalculation(annotation, j);
}
}
+ // if (conservationColouring)
+ // {
+ // currentColour = applyConservation(currentColour, j);
+ // }
}
+ // }
return currentColour;
}
{
seqAssociated = sassoc;
}
+
+ @Override
+ public String getSchemeName()
+ {
+ return "Annotation";
+ }
+
+ @Override
+ public boolean isSimple()
+ {
+ return false;
+ }
}
super();
}
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
@Override
- public Color findColour(char res, int j, SequenceI seq)
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
{
+ return new Blosum62ColourScheme();
+ }
+
+ @Override
+ public Color findColour(char res, int j, SequenceI seq,
+ String consensusResidue, float pid)
+ {
+ /*
+ * compare as upper case; note consensusResidue is
+ * always computed as uppercase
+ */
if ('a' <= res && res <= 'z')
{
- // TO UPPERCASE !!!
res -= ('a' - 'A');
}
- if (consensus == null || consensus.get(j) == null
- || (threshold != 0 && !aboveThreshold(res, j)))
+ if (Comparison.isGap(res) || consensusResidue == null)
{
return Color.white;
}
- Color currentColour;
+ Color colour;
- if (!Comparison.isGap(res))
+ if (consensusResidue.indexOf(res) > -1)
+ {
+ colour = DARK_BLUE;
+ }
+ else
{
- /*
- * test if this is the consensus (or joint consensus) residue
- */
- String max = consensus.get(j).getModalResidue();
+ int c = 0;
- if (max.indexOf(res) > -1)
+ for (char consensus : consensusResidue.toCharArray())
{
- currentColour = DARK_BLUE;
+ c += ResidueProperties.getBLOSUM62(consensus, res);
}
- else
- {
- int c = 0;
- int max_aa = 0;
- int n = max.length();
- do
- {
- c += ResidueProperties.getBLOSUM62(max.charAt(max_aa), res);
- } while (++max_aa < n);
-
- if (c > 0)
- {
- currentColour = LIGHT_BLUE;
- }
- else
- {
- currentColour = Color.white;
- }
+ if (c > 0)
+ {
+ colour = LIGHT_BLUE;
}
-
- if (conservationColouring)
+ else
{
- currentColour = applyConservation(currentColour, j);
+ colour = Color.white;
}
}
- else
- {
- return Color.white;
- }
+ return colour;
+ }
- return currentColour;
+ @Override
+ public boolean isPeptideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.Blosum62.toString();
}
@Override
- public ColourSchemeI applyTo(AnnotatedCollectionI sg,
- Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
+ public boolean isSimple()
{
- ColourSchemeI newcs = super.applyTo(sg, hiddenRepSequences);
- return newcs;
+ return false;
}
}
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
import java.awt.Color;
+import java.util.Map;
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
+ @Override
public Color makeColour(float c)
{
return new Color(0, (float) (1.0 - c), c);
}
+
+ @Override
+ public boolean isPeptideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.Buried.toString();
+ }
+
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new BuriedColourScheme();
+ }
}
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
import java.awt.Color;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
private static final int SIXTY = 60;
- /*
- * Map from conventional colour names to Clustal version of the same
- */
- private static Map<Color, Color> colhash = new HashMap<Color, Color>();
+ enum ClustalColour
+ {
+ RED(0.9f, 0.2f, 0.1f), BLUE(0.5f, 0.7f, 0.9f), GREEN(0.1f, 0.8f, 0.1f),
+ ORANGE(0.9f, 0.6f, 0.3f), CYAN(0.1f, 0.7f, 0.7f),
+ PINK(0.9f, 0.5f, 0.5f), MAGENTA(0.8f, 0.3f, 0.8f), YELLOW(0.8f, 0.8f,
+ 0.0f);
+
+ final Color colour;
+
+ ClustalColour(float r, float g, float b)
+ {
+ colour = new Color(r, g, b);
+ }
+ }
+ private class ConsensusColour
+ {
+ Consensus[] cons;
+
+ Color c;
+
+ public ConsensusColour(ClustalColour col, Consensus[] conses)
+ {
+ this.cons = conses;
+ this.c = col.colour;
+ }
+ }
private int[][] cons2;
private boolean includeGaps = true;
- static
+ /**
+ * Default constructor (required for Class.newInstance())
+ */
+ public ClustalxColourScheme()
{
- colhash.put(Color.RED, new Color(0.9f, 0.2f, 0.1f));
- colhash.put(Color.BLUE, new Color(0.5f, 0.7f, 0.9f));
- colhash.put(Color.GREEN, new Color(0.1f, 0.8f, 0.1f));
- colhash.put(Color.ORANGE, new Color(0.9f, 0.6f, 0.3f));
- colhash.put(Color.CYAN, new Color(0.1f, 0.7f, 0.7f));
- colhash.put(Color.PINK, new Color(0.9f, 0.5f, 0.5f));
- colhash.put(Color.MAGENTA, new Color(0.8f, 0.3f, 0.8f));
- colhash.put(Color.YELLOW, new Color(0.8f, 0.8f, 0.0f));
+
}
public ClustalxColourScheme(AnnotatedCollectionI alignment,
alignmentChanged(alignment, hiddenReps);
}
+ @Override
public void alignmentChanged(AnnotatedCollectionI alignment,
Map<SequenceI, SequenceCollectionI> hiddenReps)
{
includeGaps = isIncludeGaps(); // does nothing - TODO replace with call to
// get the current setting of the
// includeGaps param.
- int start = 0;
-
- // Initialize the array
- for (int j = 0; j < 24; j++)
- {
- for (int i = 0; i < maxWidth; i++)
- {
- cons2[i][j] = 0;
- }
- }
-
- int res;
- int i;
- int j = 0;
- char[] seq;
+ int res = 0;
for (SequenceI sq : seqs)
{
- seq = sq.getSequence();
+ char[] seq = sq.getSequence();
int end_j = seq.length - 1;
- for (i = start; i <= end_j; i++)
+ for (int i = 0; i <= end_j; i++)
{
if ((seq.length - 1) < i)
{
{
res = ResidueProperties.aaIndex[seq[i]];
}
-
cons2[i][res]++;
}
-
- j++;
}
this.size = seqs.size();
makeColours();
}
- public void makeColours()
+ void makeColours()
{
conses[0] = new Consensus("WLVIMAFCYHP", SIXTY);
conses[1] = new Consensus("WLVIMAFCYHP", EIGHTY);
Consensus[] tmp8 = new Consensus[1];
tmp8[0] = conses[30]; // G
- colours[7] = new ConsensusColour(colhash.get(Color.ORANGE), tmp8);
+ colours[7] = new ConsensusColour(ClustalColour.ORANGE, tmp8);
Consensus[] tmp9 = new Consensus[1];
tmp9[0] = conses[31]; // P
- colours[8] = new ConsensusColour(colhash.get(Color.YELLOW), tmp9);
+ colours[8] = new ConsensusColour(ClustalColour.YELLOW, tmp9);
Consensus[] tmp10 = new Consensus[1];
tmp10[0] = conses[27]; // C
- colours[9] = new ConsensusColour(colhash.get(Color.PINK), tmp8);
+ colours[9] = new ConsensusColour(ClustalColour.PINK, tmp8);
Consensus[] tmp1 = new Consensus[14];
tmp1[0] = conses[0]; // %
tmp1[11] = conses[25]; // Y
tmp1[12] = conses[18]; // P
tmp1[13] = conses[19]; // p
- colours[0] = new ConsensusColour(colhash.get(Color.BLUE), tmp1);
+ colours[0] = new ConsensusColour(ClustalColour.BLUE, tmp1);
- colours[10] = new ConsensusColour(colhash.get(Color.CYAN), tmp1);
+ colours[10] = new ConsensusColour(ClustalColour.CYAN, tmp1);
Consensus[] tmp2 = new Consensus[5];
tmp2[0] = conses[8]; // t
tmp2[2] = conses[22]; // T
tmp2[3] = conses[0]; // %
tmp2[4] = conses[1]; // #
- colours[1] = new ConsensusColour(colhash.get(Color.GREEN), tmp2);
+ colours[1] = new ConsensusColour(ClustalColour.GREEN, tmp2);
Consensus[] tmp3 = new Consensus[3];
tmp3[0] = conses[17]; // N
tmp3[1] = conses[29]; // D
tmp3[2] = conses[5]; // n
- colours[2] = new ConsensusColour(colhash.get(Color.GREEN), tmp3);
+ colours[2] = new ConsensusColour(ClustalColour.GREEN, tmp3);
Consensus[] tmp4 = new Consensus[6];
tmp4[0] = conses[6]; // q = QE
tmp4[3] = conses[3]; // +
tmp4[4] = conses[28]; // K
tmp4[5] = conses[20]; // R
- colours[3] = new ConsensusColour(colhash.get(Color.GREEN), tmp4);
+ colours[3] = new ConsensusColour(ClustalColour.GREEN, tmp4);
Consensus[] tmp5 = new Consensus[4];
tmp5[0] = conses[3]; // +
tmp5[1] = conses[28]; // K
tmp5[2] = conses[20]; // R
tmp5[3] = conses[19]; // Q
- colours[4] = new ConsensusColour(colhash.get(Color.RED), tmp5);
+ colours[4] = new ConsensusColour(ClustalColour.RED, tmp5);
Consensus[] tmp6 = new Consensus[6];
tmp6[0] = conses[3]; // -
tmp6[3] = conses[6]; // QE
tmp6[4] = conses[19]; // Q
tmp6[5] = conses[2]; // DE
- colours[5] = new ConsensusColour(colhash.get(Color.MAGENTA), tmp6);
+ colours[5] = new ConsensusColour(ClustalColour.MAGENTA, tmp6);
Consensus[] tmp7 = new Consensus[5];
tmp7[0] = conses[3]; // -
tmp7[2] = conses[10]; // E
tmp7[3] = conses[17]; // N
tmp7[4] = conses[2]; // DE
- colours[6] = new ConsensusColour(colhash.get(Color.MAGENTA), tmp7);
+ colours[6] = new ConsensusColour(ClustalColour.MAGENTA, tmp7);
// Now attach the ConsensusColours to the residue letters
residueColour = new ConsensusColour[20];
}
@Override
- public Color findColour(char c, int j, SequenceI seq)
+ protected Color findColour(char c, int j, SequenceI seq)
{
- Color currentColour;
-
- if (cons2.length <= j
- || (includeGaps && threshold != 0 && !aboveThreshold(c, j)))
+ // TODO why the test for includeGaps here?
+ if (cons2.length <= j || Comparison.isGap(c)
+ /*|| (includeGaps && threshold != 0 && !aboveThreshold(c, j))*/)
{
return Color.white;
}
int i = ResidueProperties.aaIndex[c];
- currentColour = Color.white;
+ Color colour = Color.white;
if (i > 19)
{
- return currentColour;
+ return colour;
}
- for (int k = 0; k < residueColour[i].conses.length; k++)
+ for (int k = 0; k < residueColour[i].cons.length; k++)
{
- if (residueColour[i].conses[k].isConserved(cons2, j, size,
+ if (residueColour[i].cons[k].isConserved(cons2, j, size,
includeGaps))
{
- currentColour = residueColour[i].c;
+ colour = residueColour[i].c;
}
}
if (i == 4)
{
+ /*
+ * override to colour C pink if >85% conserved
+ */
if (conses[27].isConserved(cons2, j, size, includeGaps))
{
- currentColour = colhash.get(Color.PINK);
+ colour = ClustalColour.PINK.colour;
}
}
- if (conservationColouring)
- {
- currentColour = applyConservation(currentColour, j);
- }
-
- return currentColour;
+ return colour;
}
/**
}
@Override
- public ColourSchemeI applyTo(AnnotatedCollectionI sg,
+ public ColourSchemeI getInstance(AnnotatedCollectionI sg,
Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
{
ClustalxColourScheme css = new ClustalxColourScheme(sg,
css.includeGaps = includeGaps;
return css;
}
-}
-class ConsensusColour
-{
- Consensus[] conses;
-
- Color c;
+ @Override
+ public boolean isPeptideSpecific()
+ {
+ return true;
+ }
- public ConsensusColour(Color c, Consensus[] conses)
+ @Override
+ public String getSchemeName()
{
- this.conses = conses;
+ return JalviewColourScheme.Clustal.toString();
+ }
- // this.list = list;
- this.c = c;
+ @Override
+ public boolean isSimple()
+ {
+ return false;
}
}
package jalview.schemes;
import jalview.datamodel.AnnotatedCollectionI;
-import jalview.datamodel.ProfilesI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
public interface ColourSchemeI
{
/**
+ * Returns the possibly context dependent colour for the given symbol at the
+ * aligned position in the given sequence. For example, the colour may depend
+ * on the symbol's relationship to the consensus residue for the column.
*
- * @param c
- * @return the colour for the given character
- */
- public Color findColour(char c);
-
- /**
- *
- * @param c
- * - sequence symbol or gap
- * @param j
- * - position in seq
+ * @param symbol
+ * @param position
* @param seq
- * - sequence being coloured
- * @return context dependent colour for the given symbol at the position in
- * the given sequence
- */
- public Color findColour(char c, int j, SequenceI seq);
-
- /**
- * assign the given consensus profile for the colourscheme
- */
- public void setConsensus(ProfilesI hconsensus);
-
- /**
- * assign the given conservation to the colourscheme
- *
- * @param c
- */
- public void setConservation(jalview.analysis.Conservation c);
-
- /**
- * enable or disable conservation shading for this colourscheme
- *
- * @param conservationApplied
- */
- public void setConservationApplied(boolean conservationApplied);
-
- /**
- *
- * @return true if conservation shading is enabled for this colourscheme
+ * @param consensusResidue
+ * the modal symbol (e.g. K) or symbols (e.g. KF) for the column
+ * @param pid
+ * the percentage identity of the column's consensus (if known)
+ * @return
*/
- public boolean conservationApplied();
-
- /**
- * set scale factor for bleaching of colour in unconserved regions
- *
- * @param i
- */
- public void setConservationInc(int i);
+ Color findColour(char symbol, int position, SequenceI seq,
+ String consensusResidue, float pid);
/**
+ * Recalculate dependent data using the given sequence collection, taking
+ * account of hidden rows
*
- * @return scale factor for bleaching colour in unconserved regions
+ * @param alignment
+ * @param hiddenReps
*/
- public int getConservationInc();
+ void alignmentChanged(AnnotatedCollectionI alignment,
+ Map<SequenceI, SequenceCollectionI> hiddenReps);
/**
+ * Creates and returns a new instance of the colourscheme configured to colour
+ * the given collection. Note that even simple colour schemes should return a
+ * new instance for each call to this method, as different instances may have
+ * differing shading by consensus or percentage identity applied.
*
- * @return percentage identity threshold for applying colourscheme
+ * @param sg
+ * @param hiddenRepSequences
+ * @return copy of current scheme with any inherited settings transferred
*/
- public int getThreshold();
+ ColourSchemeI getInstance(AnnotatedCollectionI sg,
+ Map<SequenceI, SequenceCollectionI> hiddenRepSequences);
/**
- * set percentage identity threshold and type of %age identity calculation for
- * shading
+ * Answers true if the colour scheme is suitable for the given data, else
+ * false. For example, some colour schemes are specific to either peptide or
+ * nucleotide, or only apply if certain kinds of annotation are present.
*
- * @param ct
- * 0..100 percentage identity for applying this colourscheme
- * @param ignoreGaps
- * when true, calculate PID without including gapped positions
+ * @param ac
+ * @return
*/
- public void setThreshold(int ct, boolean ignoreGaps);
+ // TODO can make this method static in Java 8
+ boolean isApplicableTo(AnnotatedCollectionI ac);
/**
- * recalculate dependent data using the given sequence collection, taking
- * account of hidden rows
+ * Answers the 'official' name of the colour scheme (as used, for example, as
+ * a Jalview startup parameter)
*
- * @param alignment
- * @param hiddenReps
+ * @return
*/
- public void alignmentChanged(AnnotatedCollectionI alignment,
- Map<SequenceI, SequenceCollectionI> hiddenReps);
+ String getSchemeName();
/**
- * create a new instance of the colourscheme configured to colour the given
- * connection
+ * Answers true if the colour scheme depends only on the sequence symbol, and
+ * not on other information such as alignment consensus or annotation. (Note
+ * that simple colour schemes may have a fading by percentage identity or
+ * conservation overlaid.) Simple colour schemes can be propagated to
+ * structure viewers.
*
- * @param sg
- * @param hiddenRepSequences
- * @return copy of current scheme with any inherited settings transfered
+ * @return
*/
- public ColourSchemeI applyTo(AnnotatedCollectionI sg,
- Map<SequenceI, SequenceCollectionI> hiddenRepSequences);
-
+ boolean isSimple();
}
package jalview.schemes;
import jalview.datamodel.AnnotatedCollectionI;
+import jalview.util.ColorUtils;
import java.awt.Color;
*/
public class ColourSchemeProperty
{
- /** Undefined Colourscheme Index */
- public static final int UNDEFINED = -1;
-
- /** for schemes defined on the fly */
- public static final int USER_DEFINED = 0;
-
- /** No Colourscheme Index */
- public static final int NONE = 1;
-
- /** DOCUMENT ME!! */
- public static final int CLUSTAL = 2;
-
- /** DOCUMENT ME!! */
- public static final int BLOSUM = 3;
-
- /** DOCUMENT ME!! */
- public static final int PID = 4;
-
- /** DOCUMENT ME!! */
- public static final int ZAPPO = 5;
-
- /** DOCUMENT ME!! */
- public static final int TAYLOR = 6;
-
- /** DOCUMENT ME!! */
- public static final int HYDROPHOBIC = 7;
-
- /** DOCUMENT ME!! */
- public static final int HELIX = 8;
-
- /** DOCUMENT ME!! */
- public static final int STRAND = 9;
-
- /** DOCUMENT ME!! */
- public static final int TURN = 10;
-
- /** DOCUMENT ME!! */
- public static final int BURIED = 11;
-
- /** DOCUMENT ME!! */
- public static final int NUCLEOTIDE = 12;
/**
- * purine/pyrimidine
- */
- public static final int PURINEPYRIMIDINE = 13;
-
- public static final int COVARIATION = 14;
-
- public static final int TCOFFEE = 15;
-
- public static final int RNAHELIX = 16;
-
- public static final int RNAINTERACTION = 17;
-
- /**
- * index of first colourscheme (includes 'None')
- */
- public static final int FIRST_COLOUR = NONE;
-
- public static final int LAST_COLOUR = RNAINTERACTION;
-
- /**
- * DOCUMENT ME!
+ * Returns a colour scheme for the given name, with which the given data may
+ * be coloured. The name is not case-sensitive, and may be one of
+ * <ul>
+ * <li>any currently registered colour scheme; Jalview by default provides</li>
+ * <ul>
+ * <li>Clustal</li>
+ * <li>Blosum62</li>
+ * <li>% Identity</li>
+ * <li>Hydrophobic</li>
+ * <li>Zappo</li>
+ * <li>Taylor</li>
+ * <li>Helix Propensity</li>
+ * <li>Strand Propensity</li>
+ * <li>Turn Propensity</li>
+ * <li>Buried Index</li>
+ * <li>Nucleotide</li>
+ * <li>Purine/Pyrimidine</li>
+ * <li>T-Coffee Scores</li>
+ * <li>RNA Helices</li>
+ * </ul>
+ * <li>the name of a programmatically added colour scheme</li> <li>an AWT
+ * colour name e.g. red</li> <li>an AWT hex rgb colour e.g. ff2288</li> <li>
+ * residue colours list e.g. D,E=red;K,R,H=0022FF;c=yellow</li> </ul>
*
- * @param name
- * DOCUMENT ME!
+ * If none of these formats is matched, the string is converted to a colour
+ * using a hashing algorithm. For name "None", returns null.
*
- * @return DOCUMENT ME!
+ * @param forData
+ * @param name
+ * @return
*/
- public static int getColourIndexFromName(String name)
+ public static ColourSchemeI getColourScheme(AnnotatedCollectionI forData,
+ String name)
{
- int ret = UNDEFINED;
-
- if (name.equalsIgnoreCase("Clustal"))
+ if (ResidueColourScheme.NONE.equalsIgnoreCase(name))
{
- ret = CLUSTAL;
- }
- else if (name.equalsIgnoreCase("Blosum62"))
- {
- ret = BLOSUM;
- }
- else if (name.equalsIgnoreCase("% Identity"))
- {
- ret = PID;
- }
- else if (name.equalsIgnoreCase("Zappo"))
- {
- ret = ZAPPO;
- }
- else if (name.equalsIgnoreCase("Taylor"))
- {
- ret = TAYLOR;
- }
- else if (name.equalsIgnoreCase("Hydrophobic"))
- {
- ret = HYDROPHOBIC;
- }
- else if (name.equalsIgnoreCase("Helix Propensity"))
- {
- ret = HELIX;
- }
- else if (name.equalsIgnoreCase("Strand Propensity"))
- {
- ret = STRAND;
- }
- else if (name.equalsIgnoreCase("Turn Propensity"))
- {
- ret = TURN;
- }
- else if (name.equalsIgnoreCase("Buried Index"))
- {
- ret = BURIED;
- }
- else if (name.equalsIgnoreCase("Nucleotide"))
- {
- ret = NUCLEOTIDE;
- }
- else if (name.equalsIgnoreCase("T-Coffee Scores"))
- {
- ret = TCOFFEE;
- }
+ return null;
- else if (name.equalsIgnoreCase("User Defined"))
- {
- ret = USER_DEFINED;
- }
- else if (name.equalsIgnoreCase("None"))
- {
- ret = NONE;
- }
- else if (name.equalsIgnoreCase("Purine/Pyrimidine"))
- {
- ret = PURINEPYRIMIDINE;
- }
- else if (name.equalsIgnoreCase("RNA Interaction type"))
- {
- ret = RNAINTERACTION;
- }
- else if (name.equalsIgnoreCase("RNA Helices"))
- {
- ret = RNAHELIX;
}
- // else if (name.equalsIgnoreCase("Covariation"))
- // {
- // ret = COVARIATION;
- // }
-
- return ret;
- }
- /**
- * DOCUMENT ME!
- *
- * @param cs
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public static String getColourName(ColourSchemeI cs)
- {
-
- int index = NONE;
-
- if (cs instanceof ClustalxColourScheme)
- {
- index = CLUSTAL;
- }
- else if (cs instanceof Blosum62ColourScheme)
- {
- index = BLOSUM;
- }
- else if (cs instanceof PIDColourScheme)
- {
- index = PID;
- }
- else if (cs instanceof ZappoColourScheme)
- {
- index = ZAPPO;
- }
- else if (cs instanceof TaylorColourScheme)
- {
- index = TAYLOR;
- }
- else if (cs instanceof HydrophobicColourScheme)
- {
- index = HYDROPHOBIC;
- }
- else if (cs instanceof HelixColourScheme)
- {
- index = HELIX;
- }
- else if (cs instanceof StrandColourScheme)
- {
- index = STRAND;
- }
- else if (cs instanceof TurnColourScheme)
- {
- index = TURN;
- }
- else if (cs instanceof BuriedColourScheme)
- {
- index = BURIED;
- }
- else if (cs instanceof NucleotideColourScheme)
- {
- index = NUCLEOTIDE;
- }
- else if (cs instanceof PurinePyrimidineColourScheme)
- {
- index = PURINEPYRIMIDINE;
- }
- else if (cs instanceof TCoffeeColourScheme)
- {
- index = TCOFFEE;
- }
- else if (cs instanceof RNAHelicesColour)
- {
- index = RNAHELIX;
- }
/*
- * else if (cs instanceof CovariationColourScheme) { index = COVARIATION; }
+ * if this is the name of a registered colour scheme, just
+ * create a new instance of it
*/
- else if (cs instanceof UserColourScheme)
+ ColourSchemeI scheme = ColourSchemes.getInstance().getColourScheme(
+ name, forData, null);
+ if (scheme != null)
{
- if ((((UserColourScheme) cs).getName() != null)
- && (((UserColourScheme) cs).getName().length() > 0))
- {
- return ((UserColourScheme) cs).getName();
- }
- // get default colourscheme name
- index = USER_DEFINED;
+ return scheme;
}
- return getColourName(index);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param index
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public static String getColourName(int index)
- {
- String ret = null;
-
- switch (index)
- {
- case CLUSTAL:
- ret = "Clustal";
-
- break;
-
- case BLOSUM:
- ret = "Blosum62";
-
- break;
-
- case PID:
- ret = "% Identity";
-
- break;
-
- case ZAPPO:
- ret = "Zappo";
-
- break;
-
- case TAYLOR:
- ret = "Taylor";
- break;
-
- case HYDROPHOBIC:
- ret = "Hydrophobic";
-
- break;
-
- case HELIX:
- ret = "Helix Propensity";
-
- break;
-
- case STRAND:
- ret = "Strand Propensity";
-
- break;
-
- case TURN:
- ret = "Turn Propensity";
-
- break;
-
- case BURIED:
- ret = "Buried Index";
-
- break;
-
- case NUCLEOTIDE:
- ret = "Nucleotide";
-
- break;
-
- case PURINEPYRIMIDINE:
- ret = "Purine/Pyrimidine";
-
- break;
-
- case TCOFFEE:
- ret = "T-Coffee Scores";
-
- break;
-
- case RNAINTERACTION:
- ret = "RNA Interaction type";
-
- break;
- case RNAHELIX:
- ret = "RNA Helices";
-
- break;
/*
- * case COVARIATION: ret = "Covariation";
- *
- * break;
+ * try to parse the string as a residues colour scheme
+ * e.g. A=red;T,G=blue etc
+ * else parse the name as a colour specification
+ * e.g. "red" or "ff00ed",
+ * or failing that hash the name to a colour
*/
- case USER_DEFINED:
- ret = "User Defined";
-
- break;
-
- default:
- ret = "None";
-
- break;
- }
-
- return ret;
- }
-
- /**
- * retrieve or create colourscheme associated with name
- *
- * @param seqs
- * sequences to colour
- * @param width
- * range of sequences to colour
- * @param name
- * colourscheme name, applet colour parameter specification, or
- * string to parse as colour for new coloursheme
- * @return Valid Colourscheme
- */
- public static ColourSchemeI getColour(AnnotatedCollectionI alignment,
- String name)
- {
- int colindex = getColourIndexFromName(name);
- if (colindex == UNDEFINED)
- {
- if (name.indexOf('=') == -1)
- {
- // try to build a colour from the string directly
- try
- {
- return new UserColourScheme(name);
- } catch (Exception e)
- {
- // System.err.println("Ignoring unknown colourscheme name");
- }
- }
- else
- {
- // try to parse the string as a residue colourscheme
- try
- {
- // fix the launchApp user defined coloursheme transfer bug
- jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
- "white");
- ucs.parseAppletParameter(name);
-
- } catch (Exception e)
- {
- // System.err.println("Ignoring exception when parsing colourscheme as applet-parameter");
- }
- }
- }
- return getColour(alignment, getColourIndexFromName(name));
- }
-
- /**
- * Construct an instance of ColourSchemeI corresponding to the given
- * colourscheme index
- *
- * @param seqs
- * sequences to be coloured by colourscheme
- * @param width
- * geometry of alignment
- * @param index
- * colourscheme number
- *
- * @return null or an instance of the colourscheme configured to colour given
- * sequence set
- */
- public static ColourSchemeI getColour(
- jalview.datamodel.AnnotatedCollectionI coll, int index)
- {
- // TODO 3.0 2.8 refactor signature to take an alignmentI like container so
- // colourschemes based on annotation can be initialised
- ColourSchemeI cs = null;
-
- switch (index)
- {
- case CLUSTAL:
- cs = new ClustalxColourScheme(coll, null);
-
- break;
-
- case BLOSUM:
- cs = new Blosum62ColourScheme();
-
- break;
-
- case PID:
- cs = new PIDColourScheme();
-
- break;
-
- case ZAPPO:
- cs = new ZappoColourScheme();
-
- break;
-
- case TAYLOR:
- cs = new TaylorColourScheme();
- break;
-
- case HYDROPHOBIC:
- cs = new HydrophobicColourScheme();
-
- break;
-
- case HELIX:
- cs = new HelixColourScheme();
-
- break;
-
- case STRAND:
- cs = new StrandColourScheme();
-
- break;
-
- case TURN:
- cs = new TurnColourScheme();
-
- break;
-
- case BURIED:
- cs = new BuriedColourScheme();
-
- break;
-
- case NUCLEOTIDE:
- cs = new NucleotideColourScheme();
-
- break;
-
- case PURINEPYRIMIDINE:
- cs = new PurinePyrimidineColourScheme();
-
- break;
-
- case TCOFFEE:
- cs = new TCoffeeColourScheme(coll);
- break;
-
- case RNAHELIX:
- cs = new RNAHelicesColour(coll);
- break;
-
- // case COVARIATION:
- // cs = new CovariationColourScheme(annotation);
- // break;
-
- case USER_DEFINED:
- Color[] col = new Color[24];
- for (int i = 0; i < 24; i++)
- {
- col[i] = Color.white;
- }
- cs = new UserColourScheme(col);
- break;
-
- default:
- break;
- }
-
- return cs;
- }
-
- public static Color getAWTColorFromName(String name)
- {
- Color col = null;
- name = name.toLowerCase();
- if (name.equals("black"))
- {
- col = Color.black;
- }
- else if (name.equals("blue"))
- {
- col = Color.blue;
- }
- else if (name.equals("cyan"))
- {
- col = Color.cyan;
- }
- else if (name.equals("darkGray"))
- {
- col = Color.darkGray;
- }
- else if (name.equals("gray"))
- {
- col = Color.gray;
- }
- else if (name.equals("green"))
- {
- col = Color.green;
- }
- else if (name.equals("lightGray"))
- {
- col = Color.lightGray;
- }
- else if (name.equals("magenta"))
- {
- col = Color.magenta;
- }
- else if (name.equals("orange"))
- {
- col = Color.orange;
- }
- else if (name.equals("pink"))
- {
- col = Color.pink;
- }
- else if (name.equals("red"))
- {
- col = Color.red;
- }
- else if (name.equals("white"))
- {
- col = Color.white;
- }
- else if (name.equals("yellow"))
- {
- col = Color.yellow;
- }
-
- return col;
+ UserColourScheme ucs = new UserColourScheme(name);
+ return ucs;
}
public static Color rnaHelices[] = null;
// Generate random colors and store
for (; j <= n; j++)
{
- rnaHelices[j] = jalview.util.ColorUtils
- .generateRandomColor(Color.white);
+ rnaHelices[j] = ColorUtils.generateRandomColor(Color.white);
}
}
/**
- * delete the existing cached RNA helces colours
+ * delete the existing cached RNA helices colours
*/
public static void resetRnaHelicesShading()
{
rnaHelices = null;
}
+ /**
+ * Returns the name of the colour scheme (or "None" if it is null)
+ *
+ * @param cs
+ * @return
+ */
+ public static String getColourName(ColourSchemeI cs)
+ {
+ return cs == null ? ResidueColourScheme.NONE : cs
+ .getSchemeName();
+ }
+
}
--- /dev/null
+package jalview.schemes;
+
+import jalview.binding.JalviewUserColours;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class ColourSchemes
+{
+ /*
+ * singleton instance of this class
+ */
+ private static ColourSchemes instance = new ColourSchemes();
+
+ /*
+ * a map from scheme name to an instance of it
+ */
+ private Map<String, ColourSchemeI> schemes;
+
+ /**
+ * Returns the singleton instance of this class
+ *
+ * @return
+ */
+ public static ColourSchemes getInstance()
+ {
+ return instance;
+ }
+
+ private ColourSchemes()
+ {
+ loadColourSchemes();
+ }
+
+ /**
+ * Loads an instance of each standard or user-defined colour scheme
+ *
+ * @return
+ */
+ void loadColourSchemes()
+ {
+ /*
+ * store in an order-preserving map, so items can be added to menus
+ * in the order in which they are 'discovered'
+ */
+ schemes = new LinkedHashMap<String, ColourSchemeI>();
+
+ for (JalviewColourScheme cs : JalviewColourScheme.values())
+ {
+ try
+ {
+ registerColourScheme(cs.getSchemeClass().newInstance());
+ } catch (InstantiationException | IllegalAccessException e)
+ {
+ System.err.println("Error instantiating colour scheme for "
+ + cs.toString() + " " + e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Registers a colour scheme
+ *
+ * @param cs
+ */
+ public void registerColourScheme(ColourSchemeI cs)
+ {
+ String name = cs.getSchemeName();
+ if (name == null)
+ {
+ System.err.println("ColourScheme name may not be null");
+ return;
+ }
+
+ /*
+ * name is lower-case for non-case-sensitive lookup
+ * (name in the colour keeps its true case)
+ */
+ String lower = name.toLowerCase();
+ if (schemes.containsKey(lower))
+ {
+ System.err
+ .println("Warning: overwriting colour scheme named " + name);
+ }
+ schemes.put(lower, cs);
+ }
+
+ /**
+ * Removes a colour scheme by name
+ *
+ * @param name
+ */
+ public void removeColourScheme(String name)
+ {
+ schemes.remove(name);
+ }
+
+ /**
+ * Returns an instance of the colour scheme with which the given view may be
+ * coloured
+ *
+ * @param name
+ * name of the colour scheme
+ * @param forData
+ * the data to be coloured
+ * @param optional
+ * map from hidden representative sequences to the sequences they
+ * represent
+ * @return
+ */
+ public ColourSchemeI getColourScheme(String name,
+ AnnotatedCollectionI forData,
+ Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
+ {
+ if (name == null)
+ {
+ return null;
+ }
+ ColourSchemeI cs = schemes.get(name.toLowerCase());
+ return cs == null ? null : cs.getInstance(forData, hiddenRepSequences);
+ }
+
+ /**
+ * Returns an instance of the colour scheme with which the given view may be
+ * coloured
+ *
+ * @param name
+ * name of the colour scheme
+ * @param forData
+ * the data to be coloured
+ * @return
+ */
+ public ColourSchemeI getColourScheme(String name,
+ AnnotatedCollectionI forData)
+ {
+ return getColourScheme(name, forData, null);
+ }
+
+ /**
+ * Returns an iterable set of the colour schemes, in the order in which they
+ * were added
+ *
+ * @return
+ */
+ public Iterable<ColourSchemeI> getColourSchemes()
+ {
+ return schemes.values();
+ }
+
+ /**
+ * Answers true if there is a scheme with the given name, else false. The test
+ * is not case-sensitive.
+ *
+ * @param name
+ * @return
+ */
+ public boolean nameExists(String name)
+ {
+ if (name == null)
+ {
+ return false;
+ }
+ name = name.toLowerCase();
+ for (ColourSchemeI scheme : getColourSchemes())
+ {
+ if (name.equals(scheme.getSchemeName().toLowerCase()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Loads a user defined colour scheme from file. The file should contain a
+ * definition of residue colours in XML format as defined in
+ * JalviewUserColours.xsd.
+ *
+ * @param filePath
+ *
+ * @return
+ */
+ public static UserColourScheme loadColourScheme(String filePath)
+ {
+ UserColourScheme ucs = null;
+ Color[] newColours = null;
+ File file = new File(filePath);
+ try
+ {
+ InputStreamReader in = new InputStreamReader(
+ new FileInputStream(file), "UTF-8");
+
+ jalview.schemabinding.version2.JalviewUserColours jucs = new jalview.schemabinding.version2.JalviewUserColours();
+
+ org.exolab.castor.xml.Unmarshaller unmar = new org.exolab.castor.xml.Unmarshaller(
+ jucs);
+ jucs = (jalview.schemabinding.version2.JalviewUserColours) unmar
+ .unmarshal(in);
+
+ /*
+ * non-case-sensitive colours are for 20 amino acid codes,
+ * B, Z, X and Gap
+ * optionally, lower-case alternatives for all except Gap
+ */
+ newColours = new Color[24];
+ Color[] lowerCase = new Color[23];
+ boolean caseSensitive = false;
+
+ String name;
+ int index;
+ for (int i = 0; i < jucs.getColourCount(); i++)
+ {
+ name = jucs.getColour(i).getName();
+ if (ResidueProperties.aa3Hash.containsKey(name))
+ {
+ index = ResidueProperties.aa3Hash.get(name).intValue();
+ }
+ else
+ {
+ index = ResidueProperties.aaIndex[name.charAt(0)];
+ }
+ if (index == -1)
+ {
+ continue;
+ }
+
+ Color color = new Color(Integer.parseInt(jucs.getColour(i)
+ .getRGB(), 16));
+ if (name.toLowerCase().equals(name))
+ {
+ caseSensitive = true;
+ lowerCase[index] = color;
+ }
+ else
+ {
+ newColours[index] = color;
+ }
+ }
+
+ /*
+ * instantiate the colour scheme
+ */
+ ucs = new UserColourScheme(newColours);
+ ucs.setName(jucs.getSchemeName());
+ if (caseSensitive)
+ {
+ ucs.setLowerCaseColours(lowerCase);
+ }
+ } catch (Exception ex)
+ {
+ // Could be old Jalview Archive format
+ try
+ {
+ InputStreamReader in = new InputStreamReader(new FileInputStream(
+ file), "UTF-8");
+
+ jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();
+
+ jucs = JalviewUserColours.unmarshal(in);
+
+ newColours = new Color[jucs.getColourCount()];
+
+ for (int i = 0; i < 24; i++)
+ {
+ newColours[i] = new Color(Integer.parseInt(jucs.getColour(i)
+ .getRGB(), 16));
+ }
+ ucs = new UserColourScheme(newColours);
+ ucs.setName(jucs.getSchemeName());
+ } catch (Exception ex2)
+ {
+ ex2.printStackTrace();
+ }
+
+ if (newColours == null)
+ {
+ System.out.println("Error loading User ColourFile\n" + ex);
+ }
+ }
+
+ return ucs;
+ }
+}
package jalview.schemes;
import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
import java.awt.Color;
import java.util.Hashtable;
+import java.util.Map;
/**
* Became RNAHelicesColour.java. Placeholder for true covariation color scheme
*/
public class CovariationColourScheme extends ResidueColourScheme
{
- public Hashtable helixcolorhash = new Hashtable();
+ public Map<String, Color> helixcolorhash = new Hashtable<String, Color>();
- public Hashtable positionsToHelix = new Hashtable();
+ public Map<Integer, String> positionsToHelix = new Hashtable<Integer, String>();
int numHelix = 0;
public AlignmentAnnotation annotation;
/**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new CovariationColourScheme(coll.getAlignmentAnnotation()[0]);
+ }
+
+ /**
* Creates a new CovariationColourScheme object.
*/
public CovariationColourScheme(AlignmentAnnotation annotation)
for (int j = 0; j <= numHelix; j++)
{
- helixcolorhash.put(Integer.toString(j),
- jalview.util.ColorUtils.generateRandomColor(Color.white));
+ helixcolorhash.put(String.valueOf(j),
+ ColorUtils.generateRandomColor(Color.white));
}
}
*
* @return DOCUMENT ME!
*/
+ @Override
public Color findColour(char c)
{
// System.out.println("called"); log.debug
Color currentColour = Color.white;
String currentHelix = null;
// System.out.println(c + " " + j);
- currentHelix = (String) positionsToHelix.get(j);
+ currentHelix = positionsToHelix.get(j);
// System.out.println(positionsToHelix.get(j));
if (currentHelix != null)
{
- currentColour = (Color) helixcolorhash.get(currentHelix);
+ currentColour = helixcolorhash.get(currentHelix);
}
// System.out.println(c + " " + j + " helix " + currentHelix + " " +
return currentColour;
}
+ @Override
+ public boolean isNucleotideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return "Covariation";
+ }
+
+ @Override
+ public boolean isSimple()
+ {
+ return false;
+ }
}
import jalview.api.FeatureColourI;
import jalview.datamodel.SequenceFeature;
+import jalview.util.ColorUtils;
import jalview.util.Format;
import java.awt.Color;
/*
* only a simple colour specification - parse it
*/
- Color colour = UserColourScheme.getColourFromString(descriptor);
+ Color colour = ColorUtils.parseColourString(descriptor);
if (colour == null)
{
throw new IllegalArgumentException("Invalid colour descriptor: "
FeatureColour featureColour;
try
{
- featureColour = new FeatureColour(
- new UserColourScheme(mincol).findColour('A'),
- new UserColourScheme(maxcol).findColour('A'), min, max);
+ Color minColour = ColorUtils.parseColourString(mincol);
+ Color maxColour = ColorUtils.parseColourString(maxcol);
+ featureColour = new FeatureColour(minColour, maxColour, min, max);
featureColour.setColourByLabel(labelColour);
featureColour.setAutoScaled(autoScaled);
// add in any additional parameters
*/
public FeatureColour(Color low, Color high, float min, float max)
{
+ if (low == null)
+ {
+ low = Color.white;
+ }
+ if (high == null)
+ {
+ high = Color.black;
+ }
graduatedColour = true;
colour = null;
minColour = low;
{
if (isColourByLabel())
{
- return UserColourScheme
+ return ColorUtils
.createColourFromName(feature.getDescription());
}
*/
package jalview.schemes;
-import jalview.analysis.Conservation;
-import jalview.datamodel.ProfilesI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
+import java.util.Map;
/**
* Colourscheme that takes its colours from some other colourscheme
public class FollowerColourScheme extends ResidueColourScheme
{
- protected ColourSchemeI colourScheme;
+ private ColourSchemeI colourScheme;
public ColourSchemeI getBaseColour()
{
}
@Override
- public void setConsensus(ProfilesI consensus)
+ public String getSchemeName()
{
- if (colourScheme != null)
- {
- colourScheme.setConsensus(consensus);
- }
+ return "Follower";
}
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
@Override
- public void setConservation(Conservation cons)
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
{
- if (colourScheme != null)
- {
- colourScheme.setConservation(cons);
- }
+ return new FollowerColourScheme();
}
- @Override
- public void setConservationInc(int i)
+ protected ColourSchemeI getColourScheme()
+ {
+ return colourScheme;
+ }
+
+ protected void setColourScheme(ColourSchemeI colourScheme)
{
- if (colourScheme != null)
- {
- colourScheme.setConservationInc(i);
- }
+ this.colourScheme = colourScheme;
}
}
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
import java.awt.Color;
+import java.util.Map;
public class HelixColourScheme extends ScoreColourScheme
{
ResidueProperties.helixmin, ResidueProperties.helixmax);
}
+ @Override
public Color makeColour(float c)
{
return new Color(c, (float) 1.0 - c, c);
}
+
+ @Override
+ public boolean isPeptideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.Helix.toString();
+ }
+
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new HelixColourScheme();
+ }
}
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
import java.awt.Color;
+import java.util.Map;
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
+ @Override
public Color makeColour(float c)
{
return new Color(c, (float) 0.0, (float) 1.0 - c);
}
+
+ @Override
+ public boolean isPeptideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.Hydrophobic.toString();
+ }
+
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new HydrophobicColourScheme();
+ }
}
--- /dev/null
+package jalview.schemes;
+
+
+/**
+ * An enum with the colour schemes supported by Jalview.
+ */
+public enum JalviewColourScheme
+{
+ /*
+ * the order of declaration is the default order in which
+ * items are added to Colour menus
+ */
+ Clustal("Clustal", ClustalxColourScheme.class), Blosum62("Blosum62",
+ Blosum62ColourScheme.class), PID("% Identity",
+ PIDColourScheme.class), Zappo("Zappo", ZappoColourScheme.class),
+ Taylor("Taylor", TaylorColourScheme.class), Hydrophobic("Hydrophobic",
+ HydrophobicColourScheme.class), Helix("Helix Propensity",
+ HelixColourScheme.class), Strand("Strand Propensity",
+ StrandColourScheme.class), Turn("Turn Propensity",
+ TurnColourScheme.class), Buried("Buried Index",
+ BuriedColourScheme.class), Nucleotide("Nucleotide",
+ NucleotideColourScheme.class), PurinePyrimidine(
+ "Purine/Pyrimidine", PurinePyrimidineColourScheme.class),
+ RNAHelices("RNA Helices", RNAHelicesColour.class), TCoffee(
+ "T-Coffee Scores", TCoffeeColourScheme.class);
+ // RNAInteraction("RNA Interaction type", RNAInteractionColourScheme.class)
+
+ private String name;
+
+ private Class<? extends ColourSchemeI> myClass;
+
+ /**
+ * Constructor given the name of the colour scheme (as used in Jalview
+ * parameters). Note this is not necessarily the same as the 'display name'
+ * used in menu options (as this may be language-dependent).
+ *
+ * @param s
+ */
+ JalviewColourScheme(String s, Class<? extends ColourSchemeI> cl)
+ {
+ name = s;
+ myClass = cl;
+ }
+
+ /**
+ * Returns the class of the colour scheme
+ *
+ * @return
+ */
+ public Class<? extends ColourSchemeI> getSchemeClass()
+ {
+ return myClass;
+ }
+
+ /**
+ * Returns the 'official' name of this colour scheme. This is the name that
+ * identifies the colour scheme as a start-up parameter for the Jalview
+ * application or applet. Note that it may not be the name shown in menu
+ * options, as these may be internationalised.
+ */
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+}
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
-import java.awt.Color;
+import java.util.Map;
/**
* DOCUMENT ME!
*/
public NucleotideColourScheme()
{
- super(ResidueProperties.nucleotideIndex, ResidueProperties.nucleotide,
- 0);
+ super(ResidueProperties.nucleotideIndex, ResidueProperties.nucleotide);
+ }
+
+ @Override
+ public boolean isNucleotideSpecific()
+ {
+ return true;
}
- /**
- * DOCUMENT ME!
- *
- * @param n
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
@Override
- public Color findColour(char c)
+ public String getSchemeName()
{
- // System.out.println("called"); log.debug
- return colors[ResidueProperties.nucleotideIndex[c]];
+ return JalviewColourScheme.Nucleotide.toString();
}
/**
- * DOCUMENT ME!
- *
- * @param n
- * DOCUMENT ME!
- * @param j
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
*/
@Override
- public Color findColour(char c, int j, SequenceI seq)
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
{
- Color currentColour;
- if ((threshold == 0) || aboveThreshold(c, j))
- {
- try
- {
- currentColour = colors[ResidueProperties.nucleotideIndex[c]];
- } catch (Exception ex)
- {
- return Color.white;
- }
- }
- else
- {
- return Color.white;
- }
-
- if (conservationColouring)
- {
- currentColour = applyConservation(currentColour, j);
- }
-
- return currentColour;
+ return new NucleotideColourScheme();
}
}
*/
package jalview.schemes;
-import jalview.datamodel.ProfileI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.util.Comparison;
import java.awt.Color;
+import java.util.Map;
public class PIDColourScheme extends ResidueColourScheme
{
- public Color[] pidColours;
+ private static final Color[] pidColours = { new Color(100, 100, 255),
+ new Color(153, 153, 255), new Color(204, 204, 255), };
- public float[] thresholds;
+ private static final float[] thresholds = { 80, 60, 40, };
SequenceGroup group;
public PIDColourScheme()
{
- this.pidColours = ResidueProperties.pidColours;
- this.thresholds = ResidueProperties.pidThresholds;
}
@Override
- public Color findColour(char c, int j, SequenceI seq)
+ public Color findColour(char c, int j, SequenceI seq,
+ String consensusResidue, float pid)
{
+ /*
+ * compare as upper case; note consensusResidue is
+ * always computed as uppercase
+ */
if ('a' <= c && c <= 'z')
{
c -= ('a' - 'A');
}
- if (consensus == null || consensus.get(j) == null)
- {
- return Color.white;
- }
-
- if ((threshold != 0) && !aboveThreshold(c, j))
+ if (consensusResidue == null || Comparison.isGap(c))
{
return Color.white;
}
- Color currentColour = Color.white;
-
- double sc = 0;
-
+ Color colour = Color.white;
/*
* test whether this is the consensus (or joint consensus) residue
*/
- ProfileI profile = consensus.get(j);
- boolean matchesConsensus = profile.getModalResidue().contains(
+ boolean matchesConsensus = consensusResidue.contains(
String.valueOf(c));
if (matchesConsensus)
{
- sc = profile.getPercentageIdentity(ignoreGaps);
-
- if (!Comparison.isGap(c))
+ for (int i = 0; i < thresholds.length; i++)
{
- for (int i = 0; i < thresholds.length; i++)
+ if (pid > thresholds[i])
{
- if (sc > thresholds[i])
- {
- currentColour = pidColours[i];
- break;
- }
+ colour = pidColours[i];
+ break;
}
}
}
- if (conservationColouring)
- {
- currentColour = applyConservation(currentColour, j);
- }
+ return colour;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.PID.toString();
+ }
- return currentColour;
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new PIDColourScheme();
+ }
+
+ @Override
+ public boolean isSimple()
+ {
+ return false;
}
}
*/
package jalview.schemes;
-import java.awt.Color;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
+import java.util.Map;
/**
* Class is based off of NucleotideColourScheme
public PurinePyrimidineColourScheme()
{
super(ResidueProperties.purinepyrimidineIndex,
- ResidueProperties.purinepyrimidine, 0);
+ ResidueProperties.purinepyrimidine);
}
- /**
- * Finds the corresponding color for the type of character inputed
- *
- * @param c
- * Character in sequence
- *
- * @return Color from purinepyrimidineIndex in
- * jalview.schemes.ResidueProperties
- */
- public Color findColour(char c)
+ @Override
+ public boolean isNucleotideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
{
- return colors[ResidueProperties.purinepyrimidineIndex[c]];
+ return JalviewColourScheme.PurinePyrimidine.toString();
}
/**
- * Returns color based on conservation
- *
- * @param c
- * Character in sequence
- * @param j
- * Threshold
- *
- * @return Color in RGB
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
*/
- public Color findColour(char c, int j)
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
{
- Color currentColour;
- if ((threshold == 0) || aboveThreshold(c, j))
- {
- try
- {
- currentColour = colors[ResidueProperties.purinepyrimidineIndex[c]];
- } catch (Exception ex)
- {
- return Color.white;
- }
- }
- else
- {
- return Color.white;
- }
-
- if (conservationColouring)
- {
- currentColour = applyConservation(currentColour, j);
- }
-
- return currentColour;
+ return new PurinePyrimidineColourScheme();
}
}
package jalview.schemes;
import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
public AlignmentAnnotation annotation;
/**
+ * Default constructor (required for ColourSchemes cache)
+ */
+ public RNAHelicesColour()
+ {
+
+ }
+
+ /**
* Creates a new RNAHelicesColour object.
*/
public RNAHelicesColour(AlignmentAnnotation annotation)
}
@Override
- public ColourSchemeI applyTo(AnnotatedCollectionI sg,
+ public ColourSchemeI getInstance(AnnotatedCollectionI sg,
Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
{
- return new RNAHelicesColour(this);
+ return new RNAHelicesColour(sg);
+ }
+
+ @Override
+ public boolean isNucleotideSpecific()
+ {
+ return true;
+ }
+
+ /**
+ * Answers true if the data has RNA secondary structure annotation
+ */
+ @Override
+ public boolean isApplicableTo(AnnotatedCollectionI ac)
+ {
+ if (ac instanceof AlignmentI && ((AlignmentI) ac).hasRNAStructure())
+ {
+ return true;
+ }
+
+ /*
+ * not currently supporting this option for group annotation / colouring
+ */
+ return false;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.RNAHelices.toString();
+ }
+
+ @Override
+ public boolean isSimple()
+ {
+ return false;
}
-}
\ No newline at end of file
+}
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.SequenceGroup;
-import java.awt.event.ActionEvent;
import java.util.Hashtable;
+import java.util.Map;
import java.util.Vector;
/**
* change colors based on covariation.
*
* @author Lauren Michelle Lui
- *
+ * @deprecated this seems to be unfinished - just use RNAHelicesColour
*/
+@Deprecated
public class RNAHelicesColourChooser
{
ColourSchemeI oldcs;
- Hashtable oldgroupColours;
+ Map<SequenceGroup, ColourSchemeI> oldgroupColours;
- jalview.datamodel.AlignmentAnnotation currentAnnotation;
+ AlignmentAnnotation currentAnnotation;
boolean adjusting = false;
oldcs = av.getGlobalColourScheme();
if (av.getAlignment().getGroups() != null)
{
- oldgroupColours = new Hashtable();
+ oldgroupColours = new Hashtable<SequenceGroup, ColourSchemeI>();
for (SequenceGroup sg : ap.getAlignment().getGroups())
{
- if (sg.cs != null)
+ if (sg.getColourScheme() != null)
{
- oldgroupColours.put(sg, sg.cs);
+ oldgroupColours.put(sg, sg.getColourScheme());
}
}
}
this.av = av;
this.ap = ap;
- if (oldcs instanceof RNAHelicesColour)
- {
- RNAHelicesColour rhc = (RNAHelicesColour) oldcs;
-
- }
-
adjusting = true;
- Vector list = new Vector();
+ Vector<String> list = new Vector<String>();
int index = 1;
AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
if (anns != null)
}
adjusting = false;
-
changeColour();
-
}
void changeColour()
{
return;
}
- RNAHelicesColour rhc = null;
-
- rhc = new RNAHelicesColour(av.getAlignment());
+ RNAHelicesColour rhc = new RNAHelicesColour(av.getAlignment());
av.setGlobalColourScheme(rhc);
ap.paintAlignment(true);
}
-
- void reset()
- {
- av.setGlobalColourScheme(oldcs);
- if (av.getAlignment().getGroups() != null)
- {
- for (SequenceGroup sg : ap.getAlignment().getGroups())
- {
- sg.cs = (ColourSchemeI) oldgroupColours.get(sg);
- }
- }
- }
-
- public void annotations_actionPerformed(ActionEvent e)
- {
- changeColour();
- }
-
}
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
import java.awt.Color;
+import java.util.Map;
public class RNAInteractionColourScheme extends ResidueColourScheme
{
super();
}
- /**
- * DOCUMENT ME!
- *
- * @param n
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
@Override
public Color findColour(char c)
{
- // System.out.println("called"); log.debug
+ // FIXME this is just a copy of NucleotideColourScheme
return colors[ResidueProperties.nucleotideIndex[c]];
}
- /**
- * DOCUMENT ME!
- *
- * @param n
- * DOCUMENT ME!
- * @param j
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
@Override
public Color findColour(char c, int j, SequenceI seq)
{
- Color currentColour;
- if ((threshold == 0) || aboveThreshold(c, j))
+ // FIXME this is just a copy of NucleotideColourScheme
+ Color currentColour = Color.white;
+ try
{
- try
- {
- currentColour = colors[ResidueProperties.nucleotideIndex[c]];
- } catch (Exception ex)
- {
- return Color.white;
- }
- }
- else
+ currentColour = colors[ResidueProperties.nucleotideIndex[c]];
+ } catch (Exception ex)
{
- return Color.white;
- }
-
- if (conservationColouring)
- {
- currentColour = applyConservation(currentColour, j);
}
return currentColour;
}
+
+ @Override
+ public boolean isNucleotideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return "RNA Interaction type";
+ }
+
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new RNAInteractionColourScheme();
+ }
}
*/
package jalview.schemes;
-import jalview.analysis.Conservation;
import jalview.datamodel.AnnotatedCollectionI;
-import jalview.datamodel.ProfileI;
-import jalview.datamodel.ProfilesI;
import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.util.ColorUtils;
import jalview.util.Comparison;
-import jalview.util.MessageManager;
import java.awt.Color;
import java.util.Map;
/**
- * DOCUMENT ME!
- *
- * @author $author$
- * @version $Revision$
+ * Base class for residue-based colour schemes
*/
-public class ResidueColourScheme implements ColourSchemeI
+public abstract class ResidueColourScheme implements ColourSchemeI
{
- final int[] symbolIndex;
+ public static final String NONE = "None";
- boolean conservationColouring = false;
-
- Color[] colors = null;
-
- int threshold = 0;
-
- /* Set when threshold colouring to either pid_gaps or pid_nogaps */
- protected boolean ignoreGaps = false;
+ public static final String USER_DEFINED = "User Defined";
/*
- * Consensus data indexed by column
+ * lookup up by character value e.g. 'G' to the colors array index
+ * e.g. if symbolIndex['K'] = 11 then colors[11] is the colour for K
*/
- ProfilesI consensus;
+ final int[] symbolIndex;
/*
- * Conservation string as a char array
+ * colour for residue characters as indexed by symbolIndex
*/
- char[] conservation;
+ Color[] colors = null;
- /*
- * The conservation slider percentage setting
- */
- int inc = 30;
+ /* Set when threshold colouring to either pid_gaps or pid_nogaps */
+ protected boolean ignoreGaps = false;
/**
* Creates a new ResidueColourScheme object.
* ResidueProperties.aaIndex)
* @param colors
* colours for symbols in sequences
- * @param threshold
- * threshold for conservation shading
*/
- public ResidueColourScheme(int[] aaOrnaIndex, Color[] colours,
- int threshold)
+ public ResidueColourScheme(int[] aaOrnaIndex, Color[] colours)
{
symbolIndex = aaOrnaIndex;
this.colors = colours;
- this.threshold = threshold;
}
/**
/**
* Find a colour without an index in a sequence
*/
- @Override
public Color findColour(char c)
{
- return colors == null ? Color.white : colors[symbolIndex[c]];
- }
+ Color colour = Color.white;
- @Override
- public Color findColour(char c, int j, SequenceI seq)
- {
- Color currentColour;
-
- if (colors != null && symbolIndex != null && (threshold == 0)
- || aboveThreshold(c, j))
+ if (!Comparison.isGap(c) && colors != null && symbolIndex != null
+ && c < symbolIndex.length
+ && symbolIndex[c] < colors.length)
{
- currentColour = colors[symbolIndex[c]];
- }
- else
- {
- currentColour = Color.white;
- }
-
- if (conservationColouring)
- {
- currentColour = applyConservation(currentColour, j);
+ colour = colors[symbolIndex[c]];
}
- return currentColour;
+ return colour;
}
/**
- * Get the percentage threshold for this colour scheme
- *
- * @return Returns the percentage threshold
+ * Default is to call the overloaded method that ignores consensus. A colour
+ * scheme that depends on consensus (for example, Blosum62), should override
+ * this method instead.
*/
@Override
- public int getThreshold()
+ public Color findColour(char c, int j, SequenceI seq,
+ String consensusResidue, float pid)
{
- return threshold;
+ return findColour(c, j, seq);
}
/**
- * Sets the percentage consensus threshold value, and whether gaps are ignored
- * in percentage identity calculation
- *
- * @param consensusThreshold
- * @param ignoreGaps
- */
- @Override
- public void setThreshold(int consensusThreshold, boolean ignoreGaps)
- {
- threshold = consensusThreshold;
- this.ignoreGaps = ignoreGaps;
- }
-
- /**
- * Answers true if there is a consensus profile for the specified column, and
- * the given residue matches the consensus (or joint consensus) residue for
- * the column, and the percentage identity for the profile is equal to or
- * greater than the current threshold; else answers false. The percentage
- * calculation depends on whether or not we are ignoring gapped sequences.
- *
- * @param residue
- * @param column
- * (index into consensus profiles)
+ * Default implementation looks up the residue colour in a fixed scheme, or
+ * returns White if not found. Override this method for a colour scheme that
+ * depends on the column position or sequence.
*
+ * @param c
+ * @param j
+ * @param seq
* @return
- * @see #setThreshold(int, boolean)
*/
- public boolean aboveThreshold(char residue, int column)
- {
- if ('a' <= residue && residue <= 'z')
- {
- // TO UPPERCASE !!!
- // Faster than toUpperCase
- residue -= ('a' - 'A');
- }
-
- if (consensus == null)
- {
- return false;
- }
-
- ProfileI profile = consensus.get(column);
-
- /*
- * test whether this is the consensus (or joint consensus) residue
- */
- if (profile != null
- && profile.getModalResidue().contains(String.valueOf(residue)))
- {
- if (profile.getPercentageIdentity(ignoreGaps) >= threshold)
- {
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public boolean conservationApplied()
- {
- return conservationColouring;
- }
-
- @Override
- public void setConservationApplied(boolean conservationApplied)
- {
- conservationColouring = conservationApplied;
- }
-
- @Override
- public void setConservationInc(int i)
+ protected Color findColour(char c, int j, SequenceI seq)
{
- inc = i;
+ return findColour(c);
}
@Override
- public int getConservationInc()
+ public void alignmentChanged(AnnotatedCollectionI alignment,
+ Map<SequenceI, SequenceCollectionI> hiddenReps)
{
- return inc;
}
/**
- * DOCUMENT ME!
- *
- * @param consensus
- * DOCUMENT ME!
+ * Answers false if the colour scheme is nucleotide or peptide specific, and
+ * the data does not match, else true. Override to modify or extend this test
+ * as required.
*/
@Override
- public void setConsensus(ProfilesI consensus)
- {
- if (consensus == null)
- {
- return;
- }
-
- this.consensus = consensus;
- }
-
- @Override
- public void setConservation(Conservation cons)
+ public boolean isApplicableTo(AnnotatedCollectionI ac)
{
- if (cons == null)
+ if (!isPeptideSpecific() && !isNucleotideSpecific())
{
- conservationColouring = false;
- conservation = null;
+ return true;
}
- else
+ if (ac == null)
{
- conservationColouring = true;
- int iSize = cons.getConsSequence().getLength();
- conservation = new char[iSize];
- for (int i = 0; i < iSize; i++)
- {
- conservation[i] = cons.getConsSequence().getCharAt(i);
- }
+ return true;
}
-
- }
-
- /**
- * Applies a combination of column conservation score, and conservation
- * percentage slider, to 'bleach' out the residue colours towards white.
- * <p>
- * If a column is fully conserved (identical residues, conservation score 11,
- * shown as *), or all 10 physico-chemical properties are conserved
- * (conservation score 10, shown as +), then the colour is left unchanged.
- * <p>
- * Otherwise a 'bleaching' factor is computed and applied to the colour. This
- * is designed to fade colours for scores of 0-9 completely to white at slider
- * positions ranging from 18% - 100% respectively.
- *
- * @param currentColour
- * @param column
- *
- * @return bleached (or unmodified) colour
- */
- Color applyConservation(Color currentColour, int column)
- {
- if (conservation == null || conservation.length <= column)
- {
- return currentColour;
- }
- char conservationScore = conservation[column];
-
/*
- * if residues are fully conserved (* or 11), or all properties
- * are conserved (+ or 10), leave colour unchanged
+ * pop-up menu on selection group before group created
+ * (no alignment context)
*/
- if (conservationScore == '*' || conservationScore == '+'
- || conservationScore == (char) 10
- || conservationScore == (char) 11)
+ // TODO: add nucleotide flag to SequenceGroup?
+ if (ac instanceof SequenceGroup && ac.getContext() == null)
{
- return currentColour;
- }
-
- if (Comparison.isGap(conservationScore))
- {
- return Color.white;
+ return true;
}
/*
- * convert score 0-9 to a bleaching factor 1.1 - 0.2
+ * inspect the data context (alignment) for residue type
*/
- float bleachFactor = (11 - (conservationScore - '0')) / 10f;
+ boolean nucleotide = ac.isNucleotide();
/*
- * scale this up by 0-5 (percentage slider / 20)
- * as a result, scores of: 0 1 2 3 4 5 6 7 8 9
- * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100%
+ * does data type match colour scheme type?
*/
- bleachFactor *= (inc / 20f);
+ return (nucleotide && isNucleotideSpecific())
+ || (!nucleotide && isPeptideSpecific());
+ }
- return ColorUtils.bleachColour(currentColour, bleachFactor);
+ /**
+ * Answers true if the colour scheme is normally only for peptide data
+ *
+ * @return
+ */
+ public boolean isPeptideSpecific()
+ {
+ return false;
}
- @Override
- public void alignmentChanged(AnnotatedCollectionI alignment,
- Map<SequenceI, SequenceCollectionI> hiddenReps)
+ /**
+ * Answers true if the colour scheme is normally only for nucleotide data
+ *
+ * @return
+ */
+ public boolean isNucleotideSpecific()
{
+ return false;
}
+ /**
+ * Default method returns true. Override this to return false in colour
+ * schemes that are not determined solely by the sequence symbol.
+ */
@Override
- public ColourSchemeI applyTo(AnnotatedCollectionI sg,
- Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
+ public boolean isSimple()
{
- try
- {
- return getClass().newInstance();
- } catch (Exception q)
- {
- throw new Error(MessageManager.formatMessage(
- "error.implementation_error_cannot_duplicate_colour_scheme",
- new String[] { getClass().getName() }), q);
- }
+ return true;
}
}
-3, 3, 0, -1, -4 },
{ -2, -2, 1, 6, -3, 0, 2, -1, -1, -3, -4, -1, -3, -3, -1, 0, -1, -4,
-3, -3, 4, 1, -1, -4 },
- { 0, 3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1,
+ { 0, -3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1,
-2, -2, -1, -3, -3, -2, -4 },
{ -1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2, 1, 0, -3, -1, 0, -1, -2, -1,
-2, 0, 3, -1, -4 },
scoreMatrices.put("DNA", new ScoreMatrix("DNA", DNA, 1));
}
- public static final Color[] pidColours = { midBlue,
- new Color(153, 153, 255),
- // Color.lightGray,
- new Color(204, 204, 255), };
-
- public static final float[] pidThresholds = { 80, 60, 40, };
-
public static List<String> STOP = Arrays.asList("TGA", "TAA", "TAG");
public static String START = "ATG";
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
import java.awt.Color;
+import java.util.Map;
/**
* DOCUMENT ME!
/**
* DOCUMENT ME!
*
- * @param s
- * DOCUMENT ME!
- * @param j
+ * @param c
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
- @Override
- public Color findColour(char c, int j, SequenceI seq)
+ public Color makeColour(float c)
{
- if (threshold > 0)
- {
- if (!aboveThreshold(c, j))
- {
- return Color.white;
- }
- }
-
- if (jalview.util.Comparison.isGap(c))
- {
- return Color.white;
- }
-
- Color currentColour = colors[ResidueProperties.aaIndex[c]];
-
- if (conservationColouring)
- {
- currentColour = applyConservation(currentColour, j);
- }
+ return new Color(c, (float) 0.0, (float) 1.0 - c);
+ }
- return currentColour;
+ @Override
+ public String getSchemeName()
+ {
+ return "Score";
}
/**
- * DOCUMENT ME!
- *
- * @param c
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
*/
- public Color makeColour(float c)
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
{
- return new Color(c, (float) 0.0, (float) 1.0 - c);
+ return new ScoreColourScheme(symbolIndex, scores, min, max);
}
}
package jalview.schemes;
import jalview.analysis.scoremodels.PairwiseSeqScoreModel;
-import jalview.api.analysis.ScoreModelI;
+import jalview.math.Matrix;
+import jalview.math.MatrixI;
-public class ScoreMatrix extends PairwiseSeqScoreModel implements
- ScoreModelI
+public class ScoreMatrix extends PairwiseSeqScoreModel
{
String name;
}
/**
+ * Answers the score for substituting first char in A1 with first char in A2
*
* @param A1
* @param A2
- * @return score for substituting first char in A1 with first char in A2
+ * @return
*/
public int getPairwiseScore(String A1, String A2)
{
return getPairwiseScore(A1.charAt(0), A2.charAt(0));
}
+ @Override
public int getPairwiseScore(char c, char d)
{
- int pog = 0;
+ int score = 0;
try
{
: ResidueProperties.nucleotideIndex[c];
int b = (type == 0) ? ResidueProperties.aaIndex[d]
: ResidueProperties.nucleotideIndex[d];
-
- pog = matrix[a][b];
+ score = matrix[a][b];
} catch (Exception e)
{
// System.out.println("Unknown residue in " + A1 + " " + A2);
}
- return pog;
+ return score;
}
/**
* pretty print the matrix
*/
+ @Override
public String toString()
{
return outputMatrix(false);
}
return sb.toString();
}
+
+ /**
+ * Computes an NxN matrix where N is the number of sequences, and entry [i, j]
+ * is sequence[i] pairwise multiplied with sequence[j], as a sum of scores
+ * computed using the current score matrix. For example
+ * <ul>
+ * <li>Sequences:</li>
+ * <li>FKL</li>
+ * <li>R-D</li>
+ * <li>QIA</li>
+ * <li>GWC</li>
+ * <li>Score matrix is BLOSUM62</li>
+ * <li>Gaps treated same as X (unknown)</li>
+ * <li>product [0, 0] = F.F + K.K + L.L = 6 + 5 + 4 = 15</li>
+ * <li>product [1, 1] = R.R + -.- + D.D = 5 + -1 + 6 = 10</li>
+ * <li>product [2, 2] = Q.Q + I.I + A.A = 5 + 4 + 4 = 13</li>
+ * <li>product [3, 3] = G.G + W.W + C.C = 6 + 11 + 9 = 26</li>
+ * <li>product[0, 1] = F.R + K.- + L.D = -3 + -1 + -3 = -8
+ * <li>and so on</li>
+ * </ul>
+ */
+ public MatrixI computePairwiseScores(String[] seqs)
+ {
+ double[][] values = new double[seqs.length][];
+ for (int row = 0; row < seqs.length; row++)
+ {
+ values[row] = new double[seqs.length];
+ for (int col = 0; col < seqs.length; col++)
+ {
+ int total = 0;
+ int width = Math.min(seqs[row].length(), seqs[col].length());
+ for (int i = 0; i < width; i++)
+ {
+ char c1 = seqs[row].charAt(i);
+ char c2 = seqs[col].charAt(i);
+ int score = getPairwiseScore(c1, c2);
+ total += score;
+ }
+ values[row][col] = total;
+ }
+ }
+ return new Matrix(values);
+ }
}
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
import java.awt.Color;
+import java.util.Map;
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
+ @Override
public Color makeColour(float c)
{
return new Color(c, c, (float) 1.0 - c);
}
+
+ @Override
+ public boolean isPeptideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.Strand.toString();
+ }
+
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new StrandColourScheme();
+ }
}
import java.awt.Color;
import java.util.ArrayList;
import java.util.IdentityHashMap;
+import java.util.List;
import java.util.Map;
/**
*/
public class TCoffeeColourScheme extends ResidueColourScheme
{
+ IdentityHashMap<SequenceI, Color[]> seqMap;
- static final Color[] colors = { new Color(102, 102, 255), // #6666FF
- new Color(0, 255, 0), // #00FF00
- new Color(102, 255, 0), // #66FF00
- new Color(204, 255, 0), // #CCFF00
- new Color(255, 255, 0), // #FFFF00
- new Color(255, 204, 0), // #FFCC00
- new Color(255, 153, 0), // #FF9900
- new Color(255, 102, 0), // #FF6600
- new Color(255, 51, 0), // #FF3300
- new Color(255, 34, 0) // #FF2000
- };
+ /**
+ * Default constructor (required for Class.newInstance())
+ */
+ public TCoffeeColourScheme()
+ {
- IdentityHashMap<SequenceI, Color[]> seqMap;
+ }
/**
* the color scheme needs to look at the alignment to get and cache T-COFFEE
alignmentChanged(alignment, null);
}
+ /**
+ * Finds the TCoffeeScore annotation (if any) for each sequence and notes the
+ * annotation colour for each column position. The colours are fixed for
+ * scores 0-9 and are set when annotation is parsed.
+ *
+ * @see TCoffeeScoreFile#annotateAlignment(AlignmentI, boolean)
+ */
@Override
public void alignmentChanged(AnnotatedCollectionI alignment,
Map<SequenceI, SequenceCollectionI> hiddenReps)
// assume only one set of TCOFFEE scores - but could have more than one
// potentially.
- ArrayList<AlignmentAnnotation> annots = new ArrayList<AlignmentAnnotation>();
+ List<AlignmentAnnotation> annots = new ArrayList<AlignmentAnnotation>();
// Search alignment to get all tcoffee annotation and pick one set of
// annotation to use to colour seqs.
seqMap = new IdentityHashMap<SequenceI, Color[]>();
@Override
public Color findColour(char c, int j, SequenceI seq)
{
- Color[] cols;
-
- if (seqMap == null || (cols = seqMap.get(seq)) == null)
+ if (seqMap == null)
+ {
+ return Color.WHITE;
+ }
+ Color[] cols = seqMap.get(seq);
+ if (cols == null)
{
// see above TODO about computing a colour for each residue in each
// column: cc = _rcols[i][indexFor[c]];
}
@Override
- public ColourSchemeI applyTo(AnnotatedCollectionI sg,
+ public ColourSchemeI getInstance(AnnotatedCollectionI sg,
Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
{
return new TCoffeeColourScheme(sg);
}
+
+ /**
+ * Answers true if the data has TCoffee score annotation
+ */
+ @Override
+ public boolean isApplicableTo(AnnotatedCollectionI ac)
+ {
+ AnnotatedCollectionI alcontext = ac instanceof AlignmentI ? ac : ac
+ .getContext();
+ if (alcontext == null)
+ {
+ return false;
+ }
+ Iterable<AlignmentAnnotation> anns = alcontext
+ .findAnnotation(TCoffeeScoreFile.TCOFFEE_SCORE);
+ return anns.iterator().hasNext();
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.TCoffee.toString();
+ }
+
+ @Override
+ public boolean isSimple()
+ {
+ return false;
+ }
}
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
+import java.util.Map;
+
public class TaylorColourScheme extends ResidueColourScheme
{
public TaylorColourScheme()
{
- super(ResidueProperties.aaIndex, ResidueProperties.taylor, 0);
+ super(ResidueProperties.aaIndex, ResidueProperties.taylor);
+ }
+
+ @Override
+ public boolean isPeptideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.Taylor.toString();
+ }
+
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new TaylorColourScheme();
}
}
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
import java.awt.Color;
+import java.util.Map;
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
+ @Override
public Color makeColour(float c)
{
return new Color(c, 1 - c, 1 - c);
}
+
+ @Override
+ public boolean isPeptideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.Turn.toString();
+ }
+
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new TurnColourScheme();
+ }
}
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
+import jalview.util.StringUtils;
import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.StringTokenizer;
public class UserColourScheme extends ResidueColourScheme
{
+ /*
+ * lookup (by symbol index) of lower case colours (if configured)
+ */
Color[] lowerCaseColours;
protected String schemeName;
}
@Override
- public ColourSchemeI applyTo(AnnotatedCollectionI sg,
+ public ColourSchemeI getInstance(AnnotatedCollectionI sg,
Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
{
- UserColourScheme usc = new UserColourScheme(colors);
- if (lowerCaseColours != null)
+ return new UserColourScheme(this);
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @return
+ */
+ protected UserColourScheme(UserColourScheme from)
+ {
+ this(from.colors);
+ schemeName = from.schemeName;
+ if (from.lowerCaseColours != null)
{
- usc.schemeName = new String(schemeName);
- usc.lowerCaseColours = new Color[lowerCaseColours.length];
- System.arraycopy(lowerCaseColours, 0, usc.lowerCaseColours, 0,
- lowerCaseColours.length);
+ lowerCaseColours = new Color[from.lowerCaseColours.length];
+ System.arraycopy(from.lowerCaseColours, 0, lowerCaseColours, 0,
+ from.lowerCaseColours.length);
}
- return usc;
}
+ /**
+ * Constructor for an animino acid colour scheme. The colour specification may
+ * be one of
+ * <ul>
+ * <li>an AWT colour name e.g. red</li>
+ * <li>an AWT hex rgb colour e.g. ff2288</li>
+ * <li>residue colours list e.g. D,E=red;K,R,H=0022FF;c=yellow</li>
+ * </ul>
+ *
+ * @param colour
+ */
public UserColourScheme(String colour)
{
super(ResidueProperties.aaIndex);
- Color col = getColourFromString(colour);
+
+ if (colour.contains("="))
+ {
+ /*
+ * a list of colours per residue(s)
+ */
+ parseAppletParameter(colour);
+ return;
+ }
+
+ Color col = ColorUtils.parseColourString(colour);
if (col == null)
{
System.out.println("Making colour from name: " + colour);
- col = createColourFromName(colour);
+ col = ColorUtils.createColourFromName(colour);
}
- colors = new Color[24];
- for (int i = 0; i < 24; i++)
+ setAll(col);
+ schemeName = colour;
+ }
+
+ /**
+ * Sets all symbols to the specified colour
+ *
+ * @param col
+ */
+ protected void setAll(Color col)
+ {
+ if (symbolIndex == null)
+ {
+ return;
+ }
+ int max = 0;
+ for (int index : symbolIndex)
+ {
+ max = Math.max(max, index);
+ }
+ colors = new Color[max + 1];
+ for (int i = 0; i <= max; i++)
{
colors[i] = col;
}
- schemeName = colour;
}
public Color[] getColours()
return schemeName;
}
- public static Color getColourFromString(String colour)
- {
- if (colour == null)
- {
- return null;
- }
- colour = colour.trim();
-
- Color col = null;
- try
- {
- int value = Integer.parseInt(colour, 16);
- col = new Color(value);
- } catch (NumberFormatException ex)
- {
- }
-
- if (col == null)
- {
- col = ColourSchemeProperty.getAWTColorFromName(colour);
- }
-
- if (col == null)
- {
- try
- {
- java.util.StringTokenizer st = new java.util.StringTokenizer(
- colour, ",");
- int r = Integer.parseInt(st.nextToken());
- int g = Integer.parseInt(st.nextToken());
- int b = Integer.parseInt(st.nextToken());
- col = new Color(r, g, b);
- } catch (Exception ex)
- {
- }
- }
-
- return col;
-
- }
-
- public static Color createColourFromName(String name)
+ /**
+ * Parse and save residue colours specified as (for example)
+ *
+ * <pre>
+ * D,E=red; K,R,H=0022FF; c=100,50,75
+ * </pre>
+ *
+ * This should be a semi-colon separated list of colours, which may be defined
+ * by colour name, hex value or comma-separated RGB triple. Each colour is
+ * defined for a comma-separated list of amino acid single letter codes. (Note
+ * that this also allows a colour scheme to be defined for ACGT, but not for
+ * U.)
+ *
+ * @param paramValue
+ */
+ void parseAppletParameter(String paramValue)
{
- int r, g, b;
-
- int lsize = name.length();
- int start = 0, end = lsize / 3;
-
- int rgbOffset = Math.abs(name.hashCode() % 10) * 15;
-
- r = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20;
- start = end;
- end += lsize / 3;
- if (end > lsize)
- {
- end = lsize;
- }
+ setAll(Color.white);
- g = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20;
-
- b = Math.abs(name.substring(end).hashCode() + rgbOffset) % 210 + 20;
-
- Color color = new Color(r, g, b);
-
- return color;
- }
-
- public void parseAppletParameter(String paramValue)
- {
- // TODO: need a function to generate appletParameter colour string from a
- // UCS
StringTokenizer st = new StringTokenizer(paramValue, ";");
StringTokenizer st2;
String token = null, colour, residues;
st2 = new StringTokenizer(residues, " ,");
while (st2.hasMoreTokens())
{
- token = st2.nextToken();
+ String residue = st2.nextToken();
- if (ResidueProperties.aaIndex[token.charAt(0)] == -1)
+ int colIndex = ResidueProperties.aaIndex[residue.charAt(0)];
+ if (colIndex == -1)
{
continue;
}
- int colIndex = ResidueProperties.aaIndex[token.charAt(0)];
-
- if (token.equalsIgnoreCase("lowerCase"))
+ if (residue.equalsIgnoreCase("lowerCase"))
{
if (lowerCaseColours == null)
{
- lowerCaseColours = new Color[23];
+ lowerCaseColours = new Color[colors.length];
}
- for (int i = 0; i < 23; i++)
+ for (int i = 0; i < lowerCaseColours.length; i++)
{
if (lowerCaseColours[i] == null)
{
- lowerCaseColours[i] = getColourFromString(colour);
+ lowerCaseColours[i] = ColorUtils.parseColourString(colour);
}
}
continue;
}
- if (token.equals(token.toLowerCase()))
+ if (residue.equals(residue.toLowerCase()))
{
if (lowerCaseColours == null)
{
- lowerCaseColours = new Color[23];
+ lowerCaseColours = new Color[colors.length];
}
- lowerCaseColours[colIndex] = getColourFromString(colour);
+ lowerCaseColours[colIndex] = ColorUtils.parseColourString(colour);
}
else
{
- colors[colIndex] = getColourFromString(colour);
+ colors[colIndex] = ColorUtils.parseColourString(colour);
}
}
}
}
- @Override
- public Color findColour(char c, int j, SequenceI seq)
+ public void setLowerCaseColours(Color[] lcolours)
{
- Color currentColour;
- int index = ResidueProperties.aaIndex[c];
+ lowerCaseColours = lcolours;
+ }
- if ((threshold == 0) || aboveThreshold(c, j))
+ /**
+ * Returns the colour for the given residue character. If the residue is
+ * lower-case, and there is a specific colour defined for lower case, that
+ * colour is returned, else the colour for the upper case residue.
+ */
+ @Override
+ public Color findColour(char c)
+ {
+ if ('a' <= c && c <= 'z' && lowerCaseColours != null)
{
- if (lowerCaseColours != null && 'a' <= c && c <= 'z')
- {
- currentColour = lowerCaseColours[index];
- }
- else
+ Color colour = lowerCaseColours[symbolIndex[c]];
+ if (colour != null)
{
- currentColour = colors[index];
+ return colour;
}
}
- else
+ return super.findColour(c);
+ }
+
+ /**
+ * Answers the customised name of the colour scheme, if it has one, else
+ * "User Defined"
+ */
+ @Override
+ public String getSchemeName()
+ {
+ if (schemeName != null && schemeName.length() > 0)
{
- currentColour = Color.white;
+ return schemeName;
}
+ return "User Defined";
+ }
+
+ /**
+ * Generate an applet colour parameter like A,C,D=12ffe9;Q,W=2393fd;w=9178dd
+ *
+ * @return
+ */
+ public String toAppletParameter()
+ {
+ /*
+ * step 1: build a map from colours to the symbol(s) that have the colour
+ */
+ Map<Color, List<String>> colours = new HashMap<Color, List<String>>();
- if (conservationColouring)
+ for (char symbol = 'A'; symbol <= 'Z'; symbol++)
{
- currentColour = applyConservation(currentColour, j);
+ String residue = String.valueOf(symbol);
+ int index = symbolIndex[symbol];
+ Color c = colors[index];
+ if (c != null && !c.equals(Color.white))
+ {
+ if (colours.get(c) == null)
+ {
+ colours.put(c, new ArrayList<String>());
+ }
+ colours.get(c).add(residue);
+ }
+ if (lowerCaseColours != null)
+ {
+ c = lowerCaseColours[index];
+ if (c != null && !c.equals(Color.white))
+ {
+ residue = residue.toLowerCase();
+ if (colours.get(c) == null)
+ {
+ colours.put(c, new ArrayList<String>());
+ }
+ colours.get(c).add(residue);
+ }
+ }
}
- return currentColour;
- }
+ /*
+ * step 2: make a list of { A,G,R=12f9d6 } residues/colour specs
+ */
+ List<String> residueColours = new ArrayList<String>();
+ for (Entry<Color, List<String>> cols : colours.entrySet())
+ {
+ boolean first = true;
+ StringBuilder sb = new StringBuilder();
+ for (String residue : cols.getValue())
+ {
+ if (!first)
+ {
+ sb.append(",");
+ }
+ sb.append(residue);
+ first = false;
+ }
+ sb.append("=");
+ /*
+ * get color as hex value, dropping the alpha (ff) part
+ */
+ String hexString = Integer.toHexString(cols.getKey().getRGB())
+ .substring(2);
+ sb.append(hexString);
+ residueColours.add(sb.toString());
+ }
- public void setLowerCaseColours(Color[] lcolours)
- {
- lowerCaseColours = lcolours;
+ /*
+ * sort and output
+ */
+ Collections.sort(residueColours);
+ return StringUtils.listToDelimitedString(residueColours, ";");
}
-
}
*/
package jalview.schemes;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
+import java.util.Map;
+
/**
* DOCUMENT ME!
*
*/
public ZappoColourScheme()
{
- super(ResidueProperties.aaIndex, ResidueProperties.zappo, 0);
+ super(ResidueProperties.aaIndex, ResidueProperties.zappo);
+ }
+
+ @Override
+ public boolean isPeptideSpecific()
+ {
+ return true;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.Zappo.toString();
+ }
+
+ /**
+ * Returns a new instance of this colour scheme with which the given data may
+ * be coloured
+ */
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI coll,
+ Map<SequenceI, SequenceCollectionI> hrs)
+ {
+ return new ZappoColourScheme();
}
}
*/
public class AtomSpec
{
- // TODO clarify do we want pdbFile here, or pdbId?
- // compare highlightAtom in 2.8.2 for JalviewJmolBinding and
- // javascript.MouseOverStructureListener
+ int modelNo;
+
private String pdbFile;
private String chain;
private int atomIndex;
/**
+ * Parses a Chimera atomspec e.g. #1:12.A to construct an AtomSpec model (with
+ * null pdb file name)
+ *
+ * @param spec
+ * @return
+ * @throw IllegalArgumentException if the spec cannot be parsed, or represents
+ * more than one residue
+ */
+ public static AtomSpec fromChimeraAtomspec(String spec)
+ {
+ int colonPos = spec.indexOf(":");
+ if (colonPos == -1)
+ {
+ throw new IllegalArgumentException(spec);
+ }
+
+ int hashPos = spec.indexOf("#");
+ if (hashPos == -1 && colonPos != 0)
+ {
+ // # is missing but something precedes : - reject
+ throw new IllegalArgumentException(spec);
+ }
+
+ String modelSubmodel = spec.substring(hashPos + 1, colonPos);
+ int dotPos = modelSubmodel.indexOf(".");
+ int modelId = 0;
+ try
+ {
+ modelId = Integer.valueOf(dotPos == -1 ? modelSubmodel
+ : modelSubmodel.substring(0, dotPos));
+ } catch (NumberFormatException e)
+ {
+ // ignore, default to model 0
+ }
+
+ String residueChain = spec.substring(colonPos + 1);
+ dotPos = residueChain.indexOf(".");
+ int resNum = 0;
+ try
+ {
+ resNum = Integer.parseInt(dotPos == -1 ? residueChain
+ : residueChain.substring(0, dotPos));
+ } catch (NumberFormatException e)
+ {
+ // could be a range e.g. #1:4-7.B
+ throw new IllegalArgumentException(spec);
+ }
+
+ String chainId = dotPos == -1 ? "" : residueChain.substring(dotPos + 1);
+
+ return new AtomSpec(modelId, chainId, resNum, 0);
+ }
+
+ /**
* Constructor
*
* @param pdbFile
this.atomIndex = atomNo;
}
+ /**
+ * Constructor
+ *
+ * @param modelId
+ * @param chainId
+ * @param resNo
+ * @param atomNo
+ */
+ public AtomSpec(int modelId, String chainId, int resNo, int atomNo)
+ {
+ this.modelNo = modelId;
+ this.chain = chainId;
+ this.pdbResNum = resNo;
+ this.atomIndex = atomNo;
+ }
+
public String getPdbFile()
{
return pdbFile;
return atomIndex;
}
+ public int getModelNumber()
+ {
+ return modelNo;
+ }
+
+ public void setPdbFile(String file)
+ {
+ pdbFile = file;
+ }
+
@Override
public String toString()
{
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.SequenceI;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
public class StructureMapping
{
// and atomNo
HashMap<Integer, int[]> mapping;
+ /**
+ * Constructor
+ *
+ * @param seq
+ * @param pdbfile
+ * @param pdbid
+ * @param chain
+ * @param mapping
+ * a map from sequence to two values, { resNo, atomNo } in the
+ * structure
+ * @param mappingDetails
+ */
public StructureMapping(SequenceI seq, String pdbfile, String pdbid,
String chain, HashMap<Integer, int[]> mapping,
String mappingDetails)
}
/**
+ * Returns a (possibly empty) list of [start, end] residue positions in the
+ * mapped structure, corresponding to the given range of sequence positions
+ *
+ * @param fromSeqPos
+ * @param toSeqPos
+ * @return
+ */
+ public List<int[]> getPDBResNumRanges(int fromSeqPos, int toSeqPos)
+ {
+ List<int[]> result = new ArrayList<int[]>();
+ int startRes = -1;
+ int endRes = -1;
+
+ for (int i = fromSeqPos; i <= toSeqPos; i++)
+ {
+ int resNo = getPDBResNum(i);
+ if (resNo == UNASSIGNED_VALUE)
+ {
+ continue; // no mapping from this sequence position
+ }
+ if (startRes == -1)
+ {
+ startRes = resNo;
+ endRes = resNo;
+ }
+ if (resNo >= startRes && resNo <= endRes)
+ {
+ // within the current range - no change
+ continue;
+ }
+ if (resNo == startRes - 1)
+ {
+ // extend beginning of current range
+ startRes--;
+ continue;
+ }
+ if (resNo == endRes + 1)
+ {
+ // extend end of current range
+ endRes++;
+ continue;
+ }
+
+ /*
+ * resNo is not within or contiguous with last range,
+ * so write out the last range
+ */
+ result.add(new int[] { startRes, endRes });
+ startRes = resNo;
+ endRes = resNo;
+ }
+
+ /*
+ * and add the last range
+ */
+ if (startRes != -1)
+ {
+ result.add(new int[] { startRes, endRes });
+ }
+
+ return result;
+ }
+
+ /**
*
* @param pdbResNum
* @return -1 or the corresponding sequence position for a pdb residue number
return;
}
+ SearchResultsI results = findAlignmentPositionsForStructurePositions(atoms);
+ for (Object li : listeners)
+ {
+ if (li instanceof SequenceListener)
+ {
+ ((SequenceListener) li).highlightSequence(results);
+ }
+ }
+ }
+
+ /**
+ * Constructs a SearchResults object holding regions (if any) in the Jalview
+ * alignment which have a mapping to the structure viewer positions in the
+ * supplied list
+ *
+ * @param atoms
+ * @return
+ */
+ public SearchResultsI findAlignmentPositionsForStructurePositions(
+ List<AtomSpec> atoms)
+ {
SearchResultsI results = new SearchResults();
for (AtomSpec atom : atoms)
{
}
}
}
- for (Object li : listeners)
- {
- if (li instanceof SequenceListener)
- {
- ((SequenceListener) li).highlightSequence(results);
- }
- }
+ return results;
}
/**
return instances.values().iterator().next();
}
+ public void addStructureMapping(StructureMapping smapping)
+ {
+ mappings.add(smapping);
+ }
+
}
*/
package jalview.structures.models;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureRenderer;
+import jalview.api.SequenceRenderer;
import jalview.api.StructureSelectionManagerProvider;
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.io.DataSourceType;
+import jalview.schemes.ColourSchemeI;
import jalview.structure.AtomSpec;
import jalview.structure.StructureListener;
import jalview.structure.StructureMapping;
+import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import jalview.util.Comparison;
import jalview.util.MessageManager;
+import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.List;
/**
*/
protected String[] modelFileNames = null;
+ public String fileLoadingError;
+
/**
* Data bean class to simplify parameterisation in superposeStructures
*/
* the sequence alignment which is the basis of structure
* superposition
* @param matched
- * an array of booleans, indexed by alignment column, where true
- * indicates that every structure has a mapped residue present in the
- * column (so the column can participate in structure alignment)
+ * a BitSet, where bit j is set to indicate that every structure has
+ * a mapped residue present in column j (so the column can
+ * participate in structure alignment)
* @param structures
* an array of data beans corresponding to pdb file index
* @return
*/
protected int findSuperposableResidues(AlignmentI alignment,
- boolean[] matched, SuperposeData[] structures)
+ BitSet matched, SuperposeData[] structures)
{
int refStructure = -1;
String[] files = getPdbFile();
{
refStructure = pdbfnum;
}
- for (int r = 0; r < matched.length; r++)
+ for (int r = 0; r < alignment.getWidth(); r++)
{
- if (!matched[r])
+ if (!matched.get(r))
{
continue;
}
int pos = getMappedPosition(theSequence, r, mapping);
if (pos < 1 || pos == lastPos)
{
- matched[r] = false;
+ matched.clear(r);
continue;
}
lastPos = pos;
{
return null;
}
+
+ public abstract void setJalviewColourScheme(ColourSchemeI cs);
+
+ /**
+ * Constructs and sends a command to align structures against a reference
+ * structure, based on one or more sequence alignments. May optionally return
+ * an error or warning message for the alignment command.
+ *
+ * @param alignments
+ * an array of alignments to process
+ * @param structureIndices
+ * an array of corresponding reference structures (index into pdb
+ * file array); if a negative value is passed, the first PDB file
+ * mapped to an alignment sequence is used as the reference for
+ * superposition
+ * @param hiddenCols
+ * an array of corresponding hidden columns for each alignment
+ * @return
+ */
+ public abstract String superposeStructures(AlignmentI[] alignments, int[] structureIndices,
+ ColumnSelection[] hiddenCols);
+
+ public abstract void setBackgroundColour(Color col);
+
+ protected abstract StructureMappingcommandSet[] getColourBySequenceCommands(
+ String[] files, SequenceRenderer sr, FeatureRenderer fr,
+ AlignViewportI alignViewportI);
+
+ /**
+ * returns the current featureRenderer that should be used to colour the
+ * structures
+ *
+ * @param alignment
+ *
+ * @return
+ */
+ public abstract FeatureRenderer getFeatureRenderer(AlignmentViewPanel alignment);
+
+ /**
+ * returns the current sequenceRenderer that should be used to colour the
+ * structures
+ *
+ * @param alignment
+ *
+ * @return
+ */
+ public abstract SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment);
+
+ protected abstract void colourBySequence(
+ StructureMappingcommandSet[] colourBySequenceCommands);
+
+ public abstract void colourByChain();
+
+ public abstract void colourByCharge();
+
+ /**
+ * colour any structures associated with sequences in the given alignment
+ * using the getFeatureRenderer() and getSequenceRenderer() renderers but only
+ * if colourBySequence is enabled.
+ */
+ public void colourBySequence(AlignmentViewPanel alignmentv)
+ {
+ if (!colourBySequence || !isLoadingFinished())
+ {
+ return;
+ }
+ if (getSsm() == null)
+ {
+ return;
+ }
+ String[] files = getPdbFile();
+
+ SequenceRenderer sr = getSequenceRenderer(alignmentv);
+
+ FeatureRenderer fr = null;
+ boolean showFeatures = alignmentv.getAlignViewport()
+ .isShowSequenceFeatures();
+ if (showFeatures)
+ {
+ fr = getFeatureRenderer(alignmentv);
+ }
+
+ StructureMappingcommandSet[] colourBySequenceCommands = getColourBySequenceCommands(
+ files, sr, fr, alignmentv.getAlignViewport());
+ colourBySequence(colourBySequenceCommands);
+ }
+
+ public boolean hasFileLoadingError()
+ {
+ return fileLoadingError != null && fileLoadingError.length() > 0;
+ }
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.DELIM;
+import static jalview.util.UrlConstants.SEP;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+
+import jalview.util.MessageManager;
+import jalview.util.UrlConstants;
+import jalview.util.UrlLink;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.StringTokenizer;
+
+/**
+ *
+ * Implements the UrlProviderI interface for a UrlProvider object which serves
+ * custom URLs defined by the user
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class CustomUrlProvider extends UrlProviderImpl
+{
+ // Default sequence URL link label for SRS
+ private static final String SRS_LABEL = "SRS";
+
+ // map of string ids to urlLinks (selected)
+ private HashMap<String, UrlLink> selectedUrls;
+
+ // map of string ids to urlLinks (not selected)
+ private HashMap<String, UrlLink> nonselectedUrls;
+
+ /**
+ * Construct UrlProvider for custom (user-entered) URLs
+ *
+ * @param inMenuUrlList
+ * list of URLs set to be displayed in menu, in form stored in Cache.
+ * i.e. SEP delimited string
+ * @param storedUrlList
+ * list of custom URLs entered by user but not currently displayed in
+ * menu, in form stored in Cache
+ */
+ public CustomUrlProvider(String inMenuUrlList, String storedUrlList)
+ {
+ try
+ {
+ selectedUrls = parseUrlStrings(inMenuUrlList);
+ nonselectedUrls = parseUrlStrings(storedUrlList);
+ } catch (Exception ex)
+ {
+ System.out
+ .println(ex.getMessage() + "\nError parsing sequence links");
+ }
+ }
+
+ /**
+ * Construct UrlProvider for custom (user-entered) URLs
+ *
+ * @param urlList
+ * list of URLs to be displayed in menu, as (label,url) pairs
+ * @param storedUrlList
+ * list of custom URLs entered by user but not currently displayed in
+ * menu, as (label,url) pairs
+ */
+ public CustomUrlProvider(Map<String, String> inMenuUrlList,
+ Map<String, String> storedUrlList)
+ {
+ try
+ {
+ selectedUrls = parseUrlList(inMenuUrlList);
+ nonselectedUrls = parseUrlList(storedUrlList);
+ } catch (Exception ex)
+ {
+ System.out
+ .println(ex.getMessage() + "\nError parsing sequence links");
+ }
+ }
+
+ private HashMap<String, UrlLink> parseUrlStrings(String urlStrings)
+ {
+ // cachedUrlList is in form <label>|<url>|<label>|<url>...
+ // parse cachedUrlList into labels (used as id) and url links
+ HashMap<String, UrlLink> urls = new HashMap<String, UrlLink>();
+
+ StringTokenizer st = new StringTokenizer(urlStrings, SEP);
+ while (st.hasMoreElements())
+ {
+ String name = st.nextToken();
+
+ if (!isMiriamId(name))
+ {
+ // this one of our custom urls
+ String url = st.nextToken();
+ // check for '|' within a regex
+ int rxstart = url.indexOf(DELIM + DB_ACCESSION + DELIM);
+ if (rxstart == -1)
+ {
+ rxstart = url.indexOf(DELIM + SEQUENCE_ID + DELIM);
+ }
+ while (rxstart == -1 && url.indexOf("/=" + DELIM) == -1
+ && st.hasMoreTokens())
+ {
+ url = url + SEP + st.nextToken();
+ }
+ urls.put(name, new UrlLink(name, url, name));
+ }
+ }
+ upgradeOldLinks(urls);
+ return urls;
+ }
+
+ private HashMap<String, UrlLink> parseUrlList(Map<String, String> urlList)
+ {
+ HashMap<String, UrlLink> urls = new HashMap<String, UrlLink>();
+ if (urlList == null)
+ {
+ return urls;
+ }
+
+ Iterator<Map.Entry<String, String>> it = urlList.entrySet().iterator();
+ while (it.hasNext())
+ {
+ Map.Entry<String, String> pair = it.next();
+ urls.put(pair.getKey(),
+ new UrlLink(pair.getKey(), pair.getValue(),
+ pair.getKey()));
+ }
+ upgradeOldLinks(urls);
+ return urls;
+ }
+
+ /*
+ * Upgrade any legacy links which may have been left lying around
+ */
+ private void upgradeOldLinks(HashMap<String, UrlLink> urls)
+ {
+ // upgrade old SRS link
+ if (urls.containsKey(SRS_LABEL))
+ {
+ urls.remove(SRS_LABEL);
+ UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
+ link.setLabel(UrlConstants.DEFAULT_LABEL);
+ urls.put(UrlConstants.DEFAULT_LABEL, link);
+ }
+ }
+
+ @Override
+ public List<String> getLinksForMenu()
+ {
+ List<String> links = new ArrayList<String>();
+ Iterator<Map.Entry<String, UrlLink>> it = selectedUrls.entrySet()
+ .iterator();
+ while (it.hasNext())
+ {
+ Map.Entry<String, UrlLink> pair = it.next();
+ links.add(pair.getValue().toString());
+ }
+ return links;
+ }
+
+ @Override
+ public List<UrlLinkDisplay> getLinksForTable()
+ {
+ ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
+ displayLinks = getLinksForTable(selectedUrls, true);
+ displayLinks.addAll(getLinksForTable(nonselectedUrls, false));
+ return displayLinks;
+ }
+
+ private ArrayList<UrlLinkDisplay> getLinksForTable(
+ HashMap<String, UrlLink> urlList, boolean selected)
+ {
+ return super.getLinksForTable(urlList, null, selected);
+ }
+
+ @Override
+ public boolean setPrimaryUrl(String id)
+ {
+ if (selectedUrls.containsKey(id))
+ {
+ primaryUrl = id;
+ }
+ else if (nonselectedUrls.containsKey(id))
+ {
+ primaryUrl = id;
+ }
+ else
+ {
+ primaryUrl = null;
+ }
+
+ return (primaryUrl != null);
+ }
+
+ @Override
+ public String writeUrlsAsString(boolean selected)
+ {
+ StringBuffer links = new StringBuffer();
+ HashMap<String, UrlLink> urls;
+ if (selected)
+ {
+ urls = selectedUrls;
+ }
+ else
+ {
+ urls = nonselectedUrls;
+ }
+ if (urls.size() > 0)
+ {
+ for (Entry<String, UrlLink> entry : urls.entrySet())
+ {
+ links.append(entry.getValue().toString());
+ links.append(SEP);
+ }
+
+ // remove last SEP
+ links.setLength(links.length() - 1);
+ }
+ else
+ {
+ urls.clear();
+ }
+ return links.toString();
+ }
+
+ @Override
+ public String getPrimaryUrl(String seqid)
+ {
+ String result = super.getPrimaryUrl(seqid, selectedUrls);
+ if (result == null)
+ {
+ result = super.getPrimaryUrl(seqid, nonselectedUrls);
+ }
+ return result;
+ }
+
+ @Override
+ public String getPrimaryUrlId()
+ {
+ return primaryUrl;
+ }
+
+ @Override
+ public String getPrimaryTarget(String seqid)
+ {
+ return selectedUrls.get(primaryUrl).getTarget();
+ }
+
+ @Override
+ public void setUrlData(List<UrlLinkDisplay> links)
+ {
+ HashMap<String, UrlLink> unselurls = new HashMap<String, UrlLink>();
+ HashMap<String, UrlLink> selurls = new HashMap<String, UrlLink>();
+
+ Iterator<UrlLinkDisplay> it = links.iterator();
+ while (it.hasNext())
+ {
+ UrlLinkDisplay link = it.next();
+
+ // MIRIAM ids will be handled by a different UrlProvider class
+ if (!isMiriamId(link.getId()))
+ {
+ // don't allow duplicate key names as entries will be overwritten
+ if (unselurls.containsKey(link.getId())
+ || selurls.containsKey(link.getId()))
+ {
+ throw new IllegalArgumentException(MessageManager.formatMessage(
+ "exception.url_cannot_have_duplicate_id", link.getId()));
+ }
+ if (link.getIsSelected())
+ {
+ selurls.put(link.getId(),
+ new UrlLink(link.getDescription(), link.getUrl(), link.getDescription()));
+ }
+ else
+ {
+ unselurls
+ .put(link.getId(),
+ new UrlLink(link.getDescription(), link.getUrl(), link
+ .getDescription()));
+ }
+ // sort out primary and selected ids
+ if (link.getIsPrimary())
+ {
+ setPrimaryUrl(link.getId());
+ }
+ }
+
+ }
+ nonselectedUrls = unselurls;
+ selectedUrls = selurls;
+ }
+
+ @Override
+ public String choosePrimaryUrl()
+ {
+ // unilaterally set the primary id to the EMBL_EBI link
+ if ((!nonselectedUrls.containsKey(UrlConstants.DEFAULT_LABEL))
+ && (!selectedUrls.containsKey(UrlConstants.DEFAULT_LABEL)))
+ {
+ UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
+ link.setLabel(UrlConstants.DEFAULT_LABEL);
+ selectedUrls.put(UrlConstants.DEFAULT_LABEL, link);
+ }
+ primaryUrl = UrlConstants.DEFAULT_LABEL;
+ return UrlConstants.DEFAULT_LABEL;
+ }
+
+ @Override
+ public boolean contains(String id)
+ {
+ return (selectedUrls.containsKey(id) || nonselectedUrls.containsKey(id));
+ }
+
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+/**
+ * Holds settings for identifiers.org e.g. url, download location
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class IdOrgSettings
+{
+ private static String url;
+
+ private static String location;
+
+ public static void setUrl(String seturl)
+ {
+ url = seturl;
+ }
+
+ public static void setDownloadLocation(String setloc)
+ {
+ location = setloc;
+ }
+
+ public static String getUrl()
+ {
+ return url;
+ }
+
+ public static String getDownloadLocation()
+ {
+ return location;
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.DELIM;
+import static jalview.util.UrlConstants.SEP;
+
+import jalview.util.UrlLink;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+/**
+ *
+ * Implements the UrlProviderI interface for a UrlProvider object which serves
+ * URLs from identifiers.org
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class IdentifiersUrlProvider extends UrlProviderImpl
+{
+
+ private static final String LOCAL_KEY = "Local";
+
+ private static final String ID_ORG_KEY = "identifiers.org";
+
+ // map of string ids to urls
+ private HashMap<String, UrlLink> urls;
+
+ // list of selected urls
+ private ArrayList<String> selectedUrls;
+
+ public IdentifiersUrlProvider(String cachedUrlList)
+ {
+ urls = readIdentifiers(IdOrgSettings.getDownloadLocation());
+ selectedUrls = new ArrayList<String>();
+ checkSelectionMatchesUrls(cachedUrlList);
+ }
+
+ /**
+ * Read data from an identifiers.org download file
+ *
+ * @param idFileName
+ * name of identifiers.org download file
+ * @return hashmap of identifiers.org data, keyed by MIRIAM id
+ */
+ private HashMap<String, UrlLink> readIdentifiers(
+ String idFileName)
+ {
+ JSONParser parser = new JSONParser();
+
+ // identifiers.org data
+ HashMap<String, UrlLink> idData = new HashMap<String, UrlLink>();
+
+ try
+ {
+ FileReader reader = new FileReader(idFileName);
+ String key = "";
+ JSONObject obj = (JSONObject) parser.parse(reader);
+ if (obj.containsKey(ID_ORG_KEY))
+ {
+ key = ID_ORG_KEY;
+ }
+ else if (obj.containsKey(LOCAL_KEY))
+ {
+ key = LOCAL_KEY;
+ }
+ else
+ {
+ System.out
+ .println("Unexpected key returned from identifiers jalview service");
+ return idData;
+ }
+
+ JSONArray jsonarray = (JSONArray) obj.get(key);
+
+ // loop over each entry in JSON array and build HashMap entry
+ for (int i = 0; i < jsonarray.size(); i++)
+ {
+ JSONObject item = (JSONObject) jsonarray.get(i);
+
+ String url = (String) item.get("url") + "/" + DELIM + DB_ACCESSION
+ + DELIM;
+ UrlLink link = new UrlLink((String) item.get("name"), url,
+ (String) item.get("prefix"));
+ idData.put((String) item.get("id"), link);
+ }
+ } catch (FileNotFoundException e)
+ {
+ e.printStackTrace();
+ idData.clear();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ idData.clear();
+ } catch (ParseException e)
+ {
+ e.printStackTrace();
+ idData.clear();
+ }
+ return idData;
+ }
+
+ private void checkSelectionMatchesUrls(String cachedUrlList)
+ {
+ StringTokenizer st = new StringTokenizer(cachedUrlList, SEP);
+ while (st.hasMoreElements())
+ {
+ String id = st.nextToken();
+
+ if (isMiriamId(id))
+ {
+ // this is an identifiers.org MIRIAM id
+ if (urls.containsKey(id))
+ {
+ selectedUrls.add(id);
+ }
+ }
+ }
+
+ // reset defaultUrl in case it is no longer selected
+ setPrimaryUrl(primaryUrl);
+ }
+
+ @Override
+ public boolean setPrimaryUrl(String id)
+ {
+ if (urls.containsKey(id))
+ {
+ primaryUrl = id;
+ }
+ else
+ {
+ primaryUrl = null;
+ }
+
+ return urls.containsKey(id);
+ }
+
+ @Override
+ public String writeUrlsAsString(boolean selected)
+ {
+ if (!selected)
+ {
+ return ""; // we don't cache unselected identifiers.org urls
+ }
+
+ StringBuffer links = new StringBuffer();
+ if (!selectedUrls.isEmpty())
+ {
+ for (String k : selectedUrls)
+ {
+ links.append(k);
+ links.append(SEP);
+ }
+ // remove last SEP
+ links.setLength(links.length() - 1);
+ }
+ return links.toString();
+ }
+
+ @Override
+ public List<String> getLinksForMenu()
+ {
+ List<String> links = new ArrayList<String>();
+ for (String key : selectedUrls)
+ {
+ links.add(urls.get(key).toStringWithTarget());
+ }
+ return links;
+ }
+
+ @Override
+ public List<UrlLinkDisplay> getLinksForTable()
+ {
+ return super.getLinksForTable(urls, selectedUrls, false);
+ }
+
+ @Override
+ public void setUrlData(List<UrlLinkDisplay> links)
+ {
+ selectedUrls = new ArrayList<String>();
+
+ Iterator<UrlLinkDisplay> it = links.iterator();
+ while (it.hasNext())
+ {
+ UrlLinkDisplay link = it.next();
+
+ // Handle links with MIRIAM ids only
+ if (isMiriamId(link.getId()))
+ {
+ // select/deselect links accordingly and set default url
+ if (urls.containsKey(link.getId()))
+ {
+ if (link.getIsSelected())
+ {
+ selectedUrls.add(link.getId());
+ }
+ if (link.getIsPrimary())
+ {
+ setPrimaryUrl(link.getId());
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getPrimaryUrl(String seqid)
+ {
+ return super.getPrimaryUrl(seqid, urls);
+ }
+
+ @Override
+ public String getPrimaryUrlId()
+ {
+ return primaryUrl;
+ }
+
+ @Override
+ public String getPrimaryTarget(String seqid)
+ {
+ return null;
+ }
+
+ @Override
+ public String choosePrimaryUrl()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean contains(String id)
+ {
+ return (urls.containsKey(id));
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import jalview.util.MessageManager;
+import jalview.util.UrlLink;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * UrlLink table row definition
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public class UrlLinkDisplay
+{
+ private String id; // id is not supplied to display, but used to identify
+ // entries when saved
+
+ private boolean isPrimary;
+
+ private boolean isSelected;
+
+ private UrlLink link;
+
+ // Headers for columns in table
+ private final static List<String> colNames = new ArrayList<String>()
+ {
+ {
+ add(MessageManager.formatMessage("label.database"));
+ add(MessageManager.formatMessage("label.name"));
+ add(MessageManager.formatMessage("label.url"));
+ add(MessageManager.formatMessage("label.inmenu"));
+ add(MessageManager.formatMessage("label.primary"));
+ add(MessageManager.formatMessage("label.id"));
+ }
+ };
+
+ // column positions
+ public final static int DATABASE = 0;
+
+ public final static int NAME = 1;
+
+ public final static int URL = 2;
+
+ public final static int SELECTED = 3;
+
+ public final static int PRIMARY = 4;
+
+ public final static int ID = 5;
+
+ public UrlLinkDisplay(String rowId, UrlLink rowLink,
+ boolean rowSelected, boolean rowDefault)
+ {
+ id = rowId;
+ isPrimary = rowDefault;
+ isSelected = rowSelected;
+
+ link = rowLink;
+ }
+
+ // getters/setters
+ public String getId()
+ {
+ return id;
+ }
+
+ public String getDescription()
+ {
+ return link.getLabel();
+ }
+
+ public String getDBName()
+ {
+ return link.getTarget();
+ }
+
+ public String getUrl()
+ {
+ return link.getUrlWithToken();
+ }
+
+ public boolean getIsPrimary()
+ {
+ return isPrimary;
+ }
+
+ public boolean getIsSelected()
+ {
+ return isSelected;
+ }
+
+ public void setDBName(String name)
+ {
+ link.setTarget(name);
+ }
+
+ public void setUrl(String rowUrl)
+ {
+ link = new UrlLink(getDescription(), rowUrl, getDBName());
+ }
+
+ public void setDescription(String desc)
+ {
+ link.setLabel(desc);
+ }
+
+ public void setIsDefault(boolean rowDefault)
+ {
+ isPrimary = rowDefault;
+ }
+
+ public void setIsSelected(boolean rowSelected)
+ {
+ isSelected = rowSelected;
+ }
+
+ public Object getValue(int index)
+ {
+ switch (index)
+ {
+ case ID:
+ return id;
+ case URL:
+ return getUrl();
+ case PRIMARY:
+ return isPrimary;
+ case SELECTED:
+ return isSelected;
+ case NAME:
+ return getDescription();
+ case DATABASE:
+ return getDBName();
+ default:
+ return null;
+ }
+ }
+
+ public void setValue(int index, Object value)
+ {
+ switch (index)
+ {
+ case ID:
+ id = (String) value;
+ break;
+ case URL:
+ setUrl((String) value);
+ break;
+ case PRIMARY:
+ isPrimary = (boolean) value;
+ break;
+ case SELECTED:
+ isSelected = (boolean) value;
+ break;
+ case NAME:
+ setDescription((String) value);
+ case DATABASE:
+ setDBName((String) value);
+ break;
+ default:
+ // do nothing
+ }
+ }
+
+ /**
+ * Identify editable columns
+ *
+ * @param index
+ * index of column
+ * @return whether column can be edited in table
+ */
+ public boolean isEditable(int index)
+ {
+ if (index == PRIMARY)
+ {
+ // primary link must not be a $DB_ACCESSION$ link
+ // so only allow editing if it is not
+ return (!link.usesDBAccession());
+ }
+ else if (index == SELECTED)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Get list of column names to display in UI
+ *
+ * @return column names
+ */
+ public static List<String> getDisplayColumnNames()
+ {
+ // Display names between DESCRIPTION and ID (excludes ID)
+ return colNames.subList(DATABASE, ID);
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import jalview.bin.Cache;
+import jalview.urls.api.UrlProviderI;
+import jalview.util.UrlLink;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.swing.RowFilter.Entry;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+
+/**
+ * TableModel for UrlLinks table
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public class UrlLinkTableModel extends AbstractTableModel
+{
+ // local storage of data
+ private List<UrlLinkDisplay> data;
+
+ // supplier of url data
+ private UrlProviderI dataProvider;
+
+ // list of columns to display in table in correct order
+ private List<String> displayColumns;
+
+ // row in table which is currently the primary
+ private int primaryRow;
+
+ /**
+ * UrlLinkTableModel constructor
+ *
+ * @param baseData
+ * base data set to be presented in table
+ * @param entryNames
+ * keys of entries in baseData's nested hashmap. Should match order
+ * in displayColNames
+ * @param displayColNames
+ * names of columns to display in order.
+ * @param keyColName
+ * name of column corresponding to keys in baseData
+ */
+ public UrlLinkTableModel(UrlProviderI baseData)
+ {
+ dataProvider = baseData;
+ data = baseData.getLinksForTable();
+ displayColumns = UrlLinkDisplay.getDisplayColumnNames();
+
+ // find the primary row
+ primaryRow = 0;
+ Iterator<UrlLinkDisplay> it = data.iterator();
+ while (it.hasNext())
+ {
+ if (it.next().getIsPrimary())
+ {
+ break;
+ }
+ else
+ {
+ primaryRow++;
+ }
+ }
+
+ // set up listener which updates data source when table changes
+ this.addTableModelListener(new TableModelListener()
+ {
+ @Override
+ public void tableChanged(TableModelEvent e)
+ {
+ try
+ {
+ // update the UrlProvider from data list
+ dataProvider.setUrlData(data);
+ } catch (IllegalArgumentException ex)
+ {
+ Cache.log.error(ex.getMessage());
+ }
+ }
+ });
+
+ }
+
+ @Override
+ public int getRowCount()
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+ else
+ {
+ return data.size();
+ }
+ }
+
+ @Override
+ public int getColumnCount()
+ {
+ return displayColumns.size();
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex)
+ {
+ return data.get(rowIndex).getValue(columnIndex);
+ }
+
+ @Override
+ public boolean isCellEditable(int rowIndex, int columnIndex)
+ {
+ return data.get(rowIndex).isEditable(columnIndex);
+ }
+
+ /**
+ * Determine if a row is editable indirectly (rather than directly in table as
+ * in isCellEditable)
+ *
+ * @param rowIndex
+ * @return true if row can be edited indirectly
+ */
+ public boolean isRowEditable(int rowIndex)
+ {
+ // to edit, row must be a user entered row
+ return (dataProvider.isUserEntry(data.get(rowIndex).getId()));
+ }
+
+ /**
+ * Determine if a row is deletable
+ *
+ * @param rowIndex
+ * the row to be tested
+ * @return true if row can be deleted
+ */
+ public boolean isRowDeletable(int rowIndex)
+ {
+ // to delete, row must be a user entered row, and not the default row
+ return (dataProvider.isUserEntry(data.get(rowIndex).getId()) && !data
+ .get(rowIndex).getIsPrimary());
+ }
+
+ @Override
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex)
+ {
+ if (columnIndex == UrlLinkDisplay.PRIMARY)
+ {
+ // Default url column: exactly one row must always be true
+ if (rowIndex != primaryRow)
+ {
+ // selected row is not currently the default
+ // set the current default to false
+ data.get(primaryRow).setValue(columnIndex, false);
+ fireTableRowsUpdated(primaryRow, primaryRow);
+
+ // set the default to be the selected row
+ primaryRow = rowIndex;
+ data.get(rowIndex).setValue(columnIndex, aValue);
+
+ fireTableRowsUpdated(rowIndex, rowIndex);
+ }
+ }
+ else
+ {
+ data.get(rowIndex).setValue(columnIndex, aValue);
+ fireTableRowsUpdated(rowIndex, rowIndex);
+ }
+ }
+
+ @Override
+ public Class<?> getColumnClass(int columnIndex)
+ {
+ return getValueAt(0, columnIndex).getClass();
+ }
+
+ @Override
+ public String getColumnName(int columnIndex)
+ {
+ return displayColumns.get(columnIndex);
+ }
+
+ public void removeRow(int rowIndex)
+ {
+ // remove the row from data
+ data.remove(rowIndex);
+
+ // update default row
+ if (primaryRow > rowIndex)
+ {
+ primaryRow--;
+ }
+
+ // fire update which will update data source
+ fireTableRowsDeleted(rowIndex, rowIndex);
+ }
+
+ public int insertRow(String name, String url)
+ {
+ // add a row to the data
+ UrlLink link = new UrlLink(name, url, name);
+ UrlLinkDisplay u = new UrlLinkDisplay(name, link, true, false);
+ int index = data.size();
+ data.add(u);
+
+ // fire update which will update data source
+ fireTableRowsInserted(index, index);
+ return index;
+ }
+
+ public int getPrimaryColumn()
+ {
+ return UrlLinkDisplay.PRIMARY;
+ }
+
+ public int getNameColumn()
+ {
+ return UrlLinkDisplay.NAME;
+ }
+
+ public int getDatabaseColumn()
+ {
+ return UrlLinkDisplay.DATABASE;
+ }
+
+ public int getIdColumn()
+ {
+ return UrlLinkDisplay.ID;
+ }
+
+ public int getUrlColumn()
+ {
+ return UrlLinkDisplay.URL;
+ }
+
+ public int getSelectedColumn()
+ {
+ return UrlLinkDisplay.SELECTED;
+ }
+
+ public boolean isUserEntry(
+ Entry<? extends TableModel, ? extends Object> entry)
+ {
+ return dataProvider
+ .isUserEntry(entry.getStringValue(UrlLinkDisplay.ID));
+ }
+
+ public boolean isUniqueName(String name)
+ {
+ return !dataProvider.contains(name);
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import static jalview.util.UrlConstants.SEP;
+
+import jalview.urls.api.UrlProviderI;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ *
+ * Implements the UrlProviderI interface for a composite UrlProvider object
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class UrlProvider implements UrlProviderI
+{
+ // List of actual URL link providers
+ private List<UrlProviderI> providers;
+
+ // Specific reference to custom URL link provider
+ private UrlProviderI customProvider;
+
+ /**
+ * Constructor for UrlProvider composite
+ *
+ * @param defaultUrlString
+ * id of default url
+ * @param allProviders
+ * list of UrlProviders this provider gives access to
+ */
+ public UrlProvider(String defaultUrlString,
+ List<UrlProviderI> allProviders)
+ {
+ providers = allProviders;
+
+ customProvider = findCustomProvider();
+
+ // check that the defaultUrl still exists
+ if (!contains(defaultUrlString))
+ {
+ // if the defaultUrl can't be found in any of the providers
+ // set up a custom default url
+ choosePrimaryUrl();
+ }
+ else
+ {
+ setPrimaryUrl(defaultUrlString);
+ }
+ }
+
+ /*
+ * Store ref to custom url provider
+ */
+ private UrlProviderI findCustomProvider()
+ {
+ for (UrlProviderI p : providers)
+ {
+ if (p instanceof CustomUrlProvider)
+ {
+ return p;
+ }
+ }
+
+ System.out
+ .println("Error initialising UrlProvider - no custom url provider");
+ return null;
+ }
+
+ @Override
+ public boolean setPrimaryUrl(String id)
+ {
+ boolean outcome = false;
+ for (UrlProviderI p : providers)
+ {
+ if (p.setPrimaryUrl(id))
+ {
+ outcome = true;
+ }
+ }
+ if (!outcome)
+ {
+ throw new IllegalArgumentException();
+ }
+ return outcome;
+ }
+
+ @Override
+ public boolean contains(String id)
+ {
+ boolean outcome = false;
+ for (UrlProviderI p : providers)
+ {
+ if (p.contains(id))
+ {
+ outcome = true;
+ }
+ }
+ return outcome;
+ }
+
+ @Override
+ public String writeUrlsAsString(boolean selected)
+ {
+ String result = "";
+ for (UrlProviderI p : providers)
+ {
+ String next = p.writeUrlsAsString(selected);
+ if (!next.isEmpty())
+ {
+ result += next;
+ result += SEP;
+ }
+ }
+ // remove last sep
+ if (!result.isEmpty())
+ {
+ result = result.substring(0, result.length() - 1);
+ }
+ return result;
+ }
+
+ @Override
+ public Vector<String> getLinksForMenu()
+ {
+ Vector<String> fullLinks = new Vector<String>();
+ for (UrlProviderI p : providers)
+ {
+ List<String> links = p.getLinksForMenu();
+ if (links != null)
+ {
+ // will obliterate links with same keys from different providers
+ // must have checks in place to prevent user from duplicating ids
+ fullLinks.addAll(links);
+ }
+ }
+ return fullLinks;
+ }
+
+ @Override
+ public List<UrlLinkDisplay> getLinksForTable()
+ {
+ ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
+ for (UrlProviderI p : providers)
+ {
+ displayLinks.addAll(p.getLinksForTable());
+ }
+ return displayLinks;
+ }
+
+ @Override
+ public void setUrlData(List<UrlLinkDisplay> links)
+ {
+ for (UrlProviderI p : providers)
+ {
+ p.setUrlData(links);
+ }
+ }
+
+ @Override
+ public String getPrimaryUrl(String seqid)
+ {
+ String link = null;
+ for (UrlProviderI p : providers)
+ {
+ if (p.getPrimaryUrl(seqid) == null)
+ {
+ continue;
+ }
+ else
+ {
+ link = p.getPrimaryUrl(seqid);
+ break;
+ }
+ }
+ return link;
+ }
+
+ @Override
+ public String getPrimaryUrlId()
+ {
+ String id = null;
+ for (UrlProviderI p : providers)
+ {
+ if (p.getPrimaryUrlId() == null)
+ {
+ continue;
+ }
+ else
+ {
+ id = p.getPrimaryUrlId();
+ break;
+ }
+ }
+ return id;
+ }
+
+ @Override
+ public String getPrimaryTarget(String seqid)
+ {
+ String target = null;
+ for (UrlProviderI p : providers)
+ {
+ if (p.getPrimaryTarget(seqid) == null)
+ {
+ continue;
+ }
+ else
+ {
+ target = p.getPrimaryTarget(seqid);
+ break;
+ }
+ }
+ return target;
+ }
+
+ @Override
+ public String choosePrimaryUrl()
+ {
+ // choose a custom url default
+ return customProvider.choosePrimaryUrl();
+ }
+
+ @Override
+ public boolean isUserEntry(String id)
+ {
+ return customProvider.isUserEntry(id);
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.util.UrlLink;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+
+/**
+ * Leaf node of UrlProvider composite
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public abstract class UrlProviderImpl implements UrlProviderI
+{
+ // minimum length of substitution in url link string
+ protected static final int MIN_SUBST_LENGTH = 4;
+
+ private static final Pattern MIRIAM_PATTERN = Pattern
+ .compile("^MIR:\\d{8}$");
+
+ protected String primaryUrl;
+
+ protected String getPrimaryUrl(String seqid, HashMap<String, UrlLink> urls)
+ {
+ if (seqid.length() < MIN_SUBST_LENGTH)
+ {
+ return null;
+ }
+ else if (primaryUrl == null)
+ {
+ return null;
+ }
+ else if (!urls.containsKey(primaryUrl))
+ {
+ return null;
+ }
+ else
+ {
+ String url = null;
+ UrlLink urlLink = urls.get(primaryUrl);
+ String[] primaryUrls = urlLink.makeUrls(seqid, true);
+ if (primaryUrls == null || primaryUrls[0] == null
+ || primaryUrls[0].length() < MIN_SUBST_LENGTH)
+ {
+ url = null;
+ }
+ else
+ {
+ // just take first URL made from regex
+ url = primaryUrls[1];
+ }
+ return url;
+ }
+ }
+
+ @Override
+ public List<UrlLinkDisplay> getLinksForTable()
+ {
+ return null;
+ }
+
+ protected ArrayList<UrlLinkDisplay> getLinksForTable(
+ HashMap<String, UrlLink> urls, ArrayList<String> selectedUrls,
+ boolean selected)
+ {
+ ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
+ for (Entry<String, UrlLink> entry : urls.entrySet())
+ {
+ String key = entry.getKey();
+ boolean isPrimary = (key.equals(primaryUrl));
+ boolean isSelected;
+ if (selectedUrls != null)
+ {
+ isSelected = selectedUrls.contains(key);
+ }
+ else
+ {
+ isSelected = selected;
+ }
+ displayLinks.add(new UrlLinkDisplay(key, entry.getValue(),
+ isSelected, isPrimary));
+ }
+ return displayLinks;
+ }
+
+ protected boolean isMiriamId(String id)
+ {
+ return MIRIAM_PATTERN.matcher(id).matches();
+ }
+
+ @Override
+ public boolean isUserEntry(String id)
+ {
+ return !isMiriamId(id);
+ }
+}
+
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls.api;
+
+
+/**
+ * Interface to UrlProvider factories
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public interface UrlProviderFactoryI
+{
+ public UrlProviderI createUrlProvider();
+
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls.api;
+
+import jalview.urls.UrlLinkDisplay;
+
+import java.util.List;
+
+/**
+ * Methods for providing consistent access to up-to-date URLs
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public interface UrlProviderI
+{
+
+ /**
+ * Get names and urls in the UrlProvider as strings for display
+ *
+ */
+ List<String> getLinksForMenu();
+
+ /**
+ * Get names and urls as strings for display
+ *
+ */
+ List<UrlLinkDisplay> getLinksForTable();
+
+ /**
+ * Set names and urls from display settings
+ */
+ void setUrlData(List<UrlLinkDisplay> links);
+
+ /**
+ * Get the link for the primary URL
+ *
+ * @seqid sequence id for which to build link
+ * @return link for the primary URL
+ */
+ String getPrimaryUrl(String seqid);
+
+ /**
+ * Get the primary URL id
+ *
+ * @return id for primary URL
+ */
+ String getPrimaryUrlId();
+
+ /**
+ * Get the target of the link for the primary URL
+ *
+ * @seqid sequence id for which to build link
+ * @return target of link for the primary URL
+ */
+ String getPrimaryTarget(String seqid);
+
+ /**
+ * Set the primary URL: if only one URL can be used, this URL is the one which
+ * should be chosen, e.g. provides the URL to be used on double-click of a
+ * sequence id
+ *
+ * @param id
+ * the id of the URL to set as primary
+ * @return true if setting is successful
+ * @throws IllegalArgumentException
+ * if id does not exist as a url in the UrlProvider
+ */
+ boolean setPrimaryUrl(String id) throws IllegalArgumentException;
+
+ /**
+ * Test if UrlProvider contains a url
+ *
+ * @param id
+ * to test for
+ * @return true of UrlProvider contains this id, false otherwise
+ */
+ boolean contains(String id);
+
+ /**
+ * Write out all URLs as a string suitable for serialising
+ *
+ * @return string representation of available URLs
+ */
+ String writeUrlsAsString(boolean selected);
+
+ /**
+ * Choose the primary URL in the event of the selected primary being
+ * unavailable
+ *
+ * @return id of chosen primary url
+ */
+ String choosePrimaryUrl();
+
+ /**
+ * Determine if id is for a user-defined URL
+ */
+ boolean isUserEntry(String id);
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls.applet;
+
+import jalview.urls.CustomUrlProvider;
+import jalview.urls.UrlProvider;
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * UrlProvider factory for applet code
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public class AppletUrlProviderFactory implements UrlProviderFactoryI
+{
+ private String provDefaultUrl;
+
+ private Map<String, String> provUrlList;
+
+ public AppletUrlProviderFactory(String defaultUrlString,
+ Map<String, String> urlList)
+ {
+ provDefaultUrl = defaultUrlString;
+ provUrlList = urlList;
+ }
+
+ @Override
+ public UrlProviderI createUrlProvider()
+ {
+ // create all the UrlProviders we need
+ List<UrlProviderI> providers = new ArrayList<UrlProviderI>();
+ UrlProviderI customProvider = new CustomUrlProvider(provUrlList, null);
+ providers.add(customProvider);
+
+ UrlProviderI prov = new UrlProvider(provDefaultUrl, providers);
+ return prov;
+ }
+
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls.desktop;
+
+import jalview.urls.CustomUrlProvider;
+import jalview.urls.IdentifiersUrlProvider;
+import jalview.urls.UrlProvider;
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * UrlProvider factory for desktop code
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public class DesktopUrlProviderFactory implements UrlProviderFactoryI
+{
+
+ private String provDefaultUrl;
+
+ private String menuUrlList;
+
+ private String nonMenuUrlList;
+
+ public DesktopUrlProviderFactory(String defaultUrlString,
+ String cachedUrlList, String userUrlList)
+ {
+ provDefaultUrl = defaultUrlString;
+ menuUrlList = cachedUrlList;
+ nonMenuUrlList = userUrlList;
+ }
+
+ @Override
+ public UrlProviderI createUrlProvider()
+ {
+ // create all the UrlProviders we need
+ List<UrlProviderI> providers = new ArrayList<UrlProviderI>();
+
+ UrlProviderI idProvider = new IdentifiersUrlProvider(menuUrlList);
+ UrlProviderI customProvider = new CustomUrlProvider(menuUrlList,
+ nonMenuUrlList);
+ providers.add(idProvider);
+ providers.add(customProvider);
+
+ return new UrlProvider(provDefaultUrl, providers);
+ }
+
+}
return new Color(red, green, blue);
}
}
+
+ /**
+ * Parses a string into a Color, where the accepted formats are
+ * <ul>
+ * <li>an AWT colour name e.g. white</li>
+ * <li>a hex colour value (without prefix) e.g. ff0000</li>
+ * <li>an rgb triple e.g. 100,50,150</li>
+ * </ul>
+ *
+ * @param colour
+ * @return the parsed colour, or null if parsing fails
+ */
+ public static Color parseColourString(String colour)
+ {
+ if (colour == null)
+ {
+ return null;
+ }
+ colour = colour.trim();
+
+ Color col = null;
+ try
+ {
+ int value = Integer.parseInt(colour, 16);
+ col = new Color(value);
+ } catch (NumberFormatException ex)
+ {
+ }
+
+ if (col == null)
+ {
+ col = ColorUtils.getAWTColorFromName(colour);
+ }
+
+ if (col == null)
+ {
+ try
+ {
+ String[] tokens = colour.split(",");
+ if (tokens.length == 3)
+ {
+ int r = Integer.parseInt(tokens[0].trim());
+ int g = Integer.parseInt(tokens[1].trim());
+ int b = Integer.parseInt(tokens[2].trim());
+ col = new Color(r, g, b);
+ }
+ } catch (Exception ex)
+ {
+ // non-numeric token or out of 0-255 range
+ }
+ }
+
+ return col;
+ }
+
+ /**
+ * Constructs a colour from a text string. The hashcode of the whole string is
+ * scaled to the range 0-135. This is added to RGB values made from the
+ * hashcode of each third of the string, and scaled to the range 20-229.
+ *
+ * @param name
+ * @return
+ */
+ public static Color createColourFromName(String name)
+ {
+ if (name == null)
+ {
+ return Color.white;
+ }
+ int lsize = name.length();
+ int start = 0;
+ int end = lsize / 3;
+
+ int rgbOffset = Math.abs(name.hashCode() % 10) * 15; // 0-135
+
+ /*
+ * red: first third
+ */
+ int r = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20;
+ start = end;
+ end += lsize / 3;
+ if (end > lsize)
+ {
+ end = lsize;
+ }
+
+ /*
+ * green: second third
+ */
+ int g = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20;
+
+ /*
+ * blue: third third
+ */
+ int b = Math.abs(name.substring(end).hashCode() + rgbOffset) % 210 + 20;
+
+ Color color = new Color(r, g, b);
+
+ return color;
+ }
+
+ /**
+ * Returns the Color constant for a given colour name e.g. "pink", or null if
+ * the name is not recognised
+ *
+ * @param name
+ * @return
+ */
+ public static Color getAWTColorFromName(String name)
+ {
+ if (name == null)
+ {
+ return null;
+ }
+ Color col = null;
+ name = name.toLowerCase();
+
+ // or make a static map; or use reflection on the field name
+ switch (name)
+ {
+ case "black":
+ col = Color.black;
+ break;
+ case "blue":
+ col = Color.blue;
+ break;
+ case "cyan":
+ col = Color.cyan;
+ break;
+ case "darkgray":
+ col = Color.darkGray;
+ break;
+ case "gray":
+ col = Color.gray;
+ break;
+ case "green":
+ col = Color.green;
+ break;
+ case "lightgray":
+ col = Color.lightGray;
+ break;
+ case "magenta":
+ col = Color.magenta;
+ break;
+ case "orange":
+ col = Color.orange;
+ break;
+ case "pink":
+ col = Color.pink;
+ break;
+ case "red":
+ col = Color.red;
+ break;
+ case "white":
+ col = Color.white;
+ break;
+ case "yellow":
+ col = Color.yellow;
+ break;
+ }
+
+ return col;
+ }
}
String f = "";
int e = 0;
double dd = d;
- double factor = 1;
if (d != 0)
{
while (dd > 10)
{
e++;
- factor /= 10;
dd = dd / 10;
}
while (dd < 1)
{
e--;
- factor *= 10;
dd = dd * 10;
}
}
return fixed_format(d);
}
- d = d * factor;
- f = f + fixed_format(d);
+ f = f + fixed_format(dd);
if ((fmt == 'e') || (fmt == 'g'))
{
*/
package jalview.util;
-import jalview.bin.Cache;
import jalview.bin.Jalview;
import jalview.gui.EPSOptions;
import jalview.gui.IProgressIndicator;
{
return null;
}
- return new JalviewFileChooser(Cache.getProperty("LAST_DIRECTORY"),
- PNG_EXTENSION, PNG_DESCRIPTION);
+ return new JalviewFileChooser(PNG_EXTENSION, PNG_DESCRIPTION);
}
static JalviewFileChooser getEPSChooser()
{
return null;
}
- return new JalviewFileChooser(Cache.getProperty("LAST_DIRECTORY"),
- EPS_EXTENSION, EPS_DESCRIPTION);
+ return new JalviewFileChooser(EPS_EXTENSION, EPS_DESCRIPTION);
}
private void setProgressMessage(String message)
{
return null;
}
- return new JalviewFileChooser(Cache.getProperty("LAST_DIRECTORY"),
- SVG_EXTENSION, SVG_DESCRIPTION);
+ return new JalviewFileChooser(SVG_EXTENSION, SVG_DESCRIPTION);
}
}
* Copy group name, colours etc, but not sequences or sequence colour scheme
*/
SequenceGroup mappedGroup = new SequenceGroup(sg);
- mappedGroup.cs = mapTo.getGlobalColourScheme();
+ mappedGroup.setColourScheme(mapTo.getGlobalColourScheme());
mappedGroup.clear();
int minStartCol = -1;
public ParseHtmlBodyAndLinks(String description, boolean removeHTML,
String newline)
{
- StringBuilder sb = new StringBuilder(description.length());
if (description == null || description.length() == 0)
{
htmlContent = false;
return;
}
+ StringBuilder sb = new StringBuilder(description.length());
if (description.toUpperCase().indexOf("<HTML>") == -1)
{
htmlContent = false;
--- /dev/null
+package jalview.util;
+
+import java.util.Comparator;
+
+/**
+ * A comparator to order [from, to] ranges into ascending or descending order of
+ * their start position
+ */
+public class RangeComparator implements Comparator<int[]>
+{
+ boolean forwards;
+
+ public RangeComparator(boolean forward)
+ {
+ forwards = forward;
+ }
+
+ @Override
+ public int compare(int[] o1, int[] o2)
+ {
+ int compared = Integer.compare(o1[0], o2[0]);
+ return forwards ? compared : -compared;
+ }
+
+}
\ No newline at end of file
public static final String SEQUENCE_ID = "SEQUENCE_ID";
/*
- * Default sequence URL link string for EMBL-EBI search
+ * Separator character used in Url links
+ */
+ public static final String SEP = "|";
+
+ /*
+ * Delimiter character used in Url links
*/
- public static final String EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+ public static final String DELIM = "$";
/*
- * Default sequence URL link string for SRS
+ * Default sequence URL link label for EMBL-EBI search
+ */
+ public static final String DEFAULT_LABEL = "EMBL-EBI Search";
+
+ /*
+ * Default sequence URL link string for EMBL-EBI search
*/
- public static final String SRS_STRING = "SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry";
+ public static final String DEFAULT_STRING = DEFAULT_LABEL
+ + "|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
/*
* not instantiable
package jalview.util;
import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.DELIM;
+import static jalview.util.UrlConstants.SEP;
import static jalview.util.UrlConstants.SEQUENCE_ID;
import jalview.datamodel.DBRefEntry;
* documentation todo.
*/
- // Internal constants
- private static final String SEP = "|";
+ private static final String EQUALS = "=";
- private static final String DELIM = "$";
+ private static final String SPACE = " ";
private String urlSuffix;
private String label;
+ private String dbname;
+
private String regexReplace;
private boolean dynamic = false;
dynamic = true;
usesDBaccession = true;
- sep = parseTargetAndLabel(sep, psqid, link);
+ sep = parseLabel(sep, psqid, link);
- parseUrl(link, DB_ACCESSION, psqid, sep);
+ int endOfRegex = parseUrl(link, DB_ACCESSION, psqid, sep);
+ parseTarget(link, sep, endOfRegex);
}
else if (nsqid > -1)
{
dynamic = true;
- sep = parseTargetAndLabel(sep, nsqid, link);
+ sep = parseLabel(sep, nsqid, link);
+
+ int endOfRegex = parseUrl(link, SEQUENCE_ID, nsqid, sep);
- parseUrl(link, SEQUENCE_ID, nsqid, sep);
+ parseTarget(link, sep, endOfRegex);
}
else
{
- target = link.substring(0, sep);
- sep = link.lastIndexOf(SEP);
- label = link.substring(0, sep);
- urlPrefix = link.substring(sep + 1).trim();
+ label = link.substring(0, sep).trim();
+
+ // if there's a third element in the url link string
+ // it is the target name, otherwise target=label
+ int lastsep = link.lastIndexOf(SEP);
+ if (lastsep != sep)
+ {
+ urlPrefix = link.substring(sep + 1, lastsep).trim();
+ target = link.substring(lastsep + 1).trim();
+ }
+ else
+ {
+ urlPrefix = link.substring(sep + 1).trim();
+ target = label;
+ }
+
regexReplace = null; // implies we trim any prefix if necessary //
urlSuffix = null;
}
}
/**
+ * Alternative constructor for separate name, link and description
+ *
+ * @param name
+ * The string used to match the link to a DB reference id
+ * @param url
+ * The url to link to
+ * @param desc
+ * The description of the associated target DB
+ */
+ public UrlLink(String name, String url, String desc)
+ {
+ this(name + SEP + url + SEP + desc);
+ }
+
+ /**
* @return the url_suffix
*/
- public String getUrl_suffix()
+ public String getUrlSuffix()
{
return urlSuffix;
}
/**
* @return the url_prefix
*/
- public String getUrl_prefix()
+ public String getUrlPrefix()
{
return urlPrefix;
}
return label;
}
+ public String getUrlWithToken()
+ {
+ String var = (usesDBaccession ? DB_ACCESSION : SEQUENCE_ID);
+
+ return urlPrefix
+ + (dynamic ? (DELIM + var + ((regexReplace != null) ? EQUALS
+ + regexReplace + EQUALS + DELIM : DELIM)) : "")
+ + ((urlSuffix == null) ? "" : urlSuffix);
+ }
+
/**
* @return the regexReplace
*/
}
/**
+ * Set the target
+ *
+ * @param desc
+ */
+ public void setTarget(String desc)
+ {
+ target = desc;
+ }
+
+ /**
* return one or more URL strings by applying regex to the given idstring
*
* @param idstring
+ rg.stringMatched(s) + "'");
}
// try to collate subgroup matches
- Vector subs = new Vector();
+ Vector<String> subs = new Vector<String>();
// have to loop through submatches, collating them at top level
// match
int s = 0; // 1;
String[] res = new String[subs.size()];
for (int r = 0, rs = subs.size(); r < rs; r++)
{
- res[r] = (String) subs.elementAt(r);
+ res[r] = subs.elementAt(r);
}
subs.removeAllElements();
return res;
@Override
public String toString()
{
- String var = (usesDBaccession ? DB_ACCESSION : SEQUENCE_ID);
+ return label + SEP + getUrlWithToken();
+ }
- return label
- + SEP
- + urlPrefix
- + (dynamic ? (DELIM + var + ((regexReplace != null) ? "="
- + regexReplace + "=" + DELIM : DELIM)) : "")
- + ((urlSuffix == null) ? "" : urlSuffix);
+ /**
+ * @return delimited string containing label, url and target
+ */
+ public String toStringWithTarget()
+ {
+ return label + SEP + getUrlWithToken() + SEP + target;
}
/**
+ * Parse the label from the link string
*
* @param firstSep
* Location of first occurrence of separator in link string
* Link string containing database name and url
* @return Position of last separator symbol prior to any regex symbols
*/
- protected int parseTargetAndLabel(int firstSep, int psqid, String link)
+ protected int parseLabel(int firstSep, int psqid, String link)
{
int p = firstSep;
int sep = firstSep;
// Assuming that the URL itself does not contain any SEP symbols
// sep now contains last pipe symbol position prior to any regex symbols
label = link.substring(0, sep);
- if (label.indexOf(SEP) > -1)
- {
- // SEP terminated database name / www target at start of Label
- target = label.substring(0, label.indexOf(SEP));
- }
- else if (label.indexOf(" ") > 2)
+
+ return sep;
+ }
+
+ /**
+ * Parse the target from the link string
+ *
+ * @param link
+ * Link string containing database name and url
+ * @param sep
+ * Location of first separator symbol
+ * @param endOfRegex
+ * Location of end of any regular expression in link string
+ */
+ protected void parseTarget(String link, int sep, int endOfRegex)
+ {
+ int lastsep = link.lastIndexOf(SEP);
+
+ if ((lastsep != sep) && (lastsep > endOfRegex))
{
- // space separated Label - matches database name
- target = label.substring(0, label.indexOf(" "));
+ // final element in link string is the target
+ target = link.substring(lastsep + 1).trim();
}
else
{
target = label;
}
- return sep;
+
+ if (target.indexOf(SEP) > -1)
+ {
+ // SEP terminated database name / www target at start of Label
+ target = target.substring(0, target.indexOf(SEP));
+ }
+ else if (target.indexOf(SPACE) > 2)
+ {
+ // space separated label - first word matches database name
+ target = target.substring(0, target.indexOf(SPACE));
+ }
}
/**
* Position of id or name in link string
* @param sep
* Position of separator in link string
+ * @return Location of end of any regex in link string
*/
- protected void parseUrl(String link, String varName, int sqidPos, int sep)
+ protected int parseUrl(String link, String varName, int sqidPos, int sep)
{
urlPrefix = link.substring(sep + 1, sqidPos).trim();
// verify format is really correct.
if (link.indexOf(DELIM + varName + DELIM) == sqidPos)
{
- urlSuffix = link.substring(sqidPos + startLength - 1);
+ int lastsep = link.lastIndexOf(SEP);
+ if (lastsep < sqidPos + startLength - 1)
+ {
+ // the last SEP character was before the regex, ignore
+ lastsep = link.length();
+ }
+ urlSuffix = link.substring(sqidPos + startLength - 1, lastsep)
+ .trim();
regexReplace = null;
}
else
+ link;
}
}
+
+ return p;
}
/**
*/
protected void createStaticLink(Map<String, List<String>> linkset)
{
- if (!linkset.containsKey(label + SEP + getUrl_prefix()))
+ if (!linkset.containsKey(label + SEP + getUrlPrefix()))
{
// Add a non-dynamic link
- linkset.put(label + SEP + getUrl_prefix(),
- Arrays.asList(target, label, null, getUrl_prefix()));
+ linkset.put(label + SEP + getUrlPrefix(),
+ Arrays.asList(target, label, null, getUrlPrefix()));
}
}
}
}
}
-
- private static void testUrls(UrlLink ul, String idstring, String[] urls)
- {
-
- if (urls == null)
- {
- System.out.println("Created NO urls.");
- }
- else
- {
- System.out.println("Created " + (urls.length / 2) + " Urls.");
- for (int uls = 0; uls < urls.length; uls += 2)
- {
- System.out.println("URL Replacement text : " + urls[uls]
- + " : URL : " + urls[uls + 1]);
- }
- }
- }
-
- public static void main(String argv[])
- {
- String[] links = new String[] {
- /*
- * "AlinkT|Target|http://foo.foo.soo/",
- * "myUrl1|http://$SEQUENCE_ID=/[0-9]+/=$.someserver.org/foo",
- * "myUrl2|http://$SEQUENCE_ID=/(([0-9]+).+([A-Za-z]+))/=$.someserver.org/foo"
- * ,
- * "myUrl3|http://$SEQUENCE_ID=/([0-9]+).+([A-Za-z]+)/=$.someserver.org/foo"
- * , "myUrl4|target|http://$SEQUENCE_ID$.someserver.org/foo|too",
- * "PF1|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/(?:PFAM:)?(.+)/=$"
- * ,
- * "PF2|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/(PFAM:)?(.+)/=$"
- * ,
- * "PF3|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/PFAM:(.+)/=$"
- * , "NOTFER|http://notfer.org/$SEQUENCE_ID=/(?<!\\s)(.+)/=$",
- */
- "NESTED|http://nested/$" + DB_ACCESSION
- + "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
- String[] idstrings = new String[] {
- /*
- * //"LGUL_human", //"QWIQW_123123", "uniprot|why_do+_12313_foo",
- * //"123123312", "123123 ABCDE foo", "PFAM:PF23943",
- */
- "Label:gi|9234|pdb|102L|A" };
- // TODO: test the setLabel method.
- for (int i = 0; i < links.length; i++)
- {
- UrlLink ul = new UrlLink(links[i]);
- if (ul.isValid())
- {
- System.out.println("\n\n\n");
- System.out.println("Link " + i + " " + links[i] + " : "
- + ul.toString());
- System.out.println(" pref : "
- + ul.getUrl_prefix()
- + "\n suf : "
- + ul.getUrl_suffix()
- + "\n : "
- + ((ul.getRegexReplace() != null) ? ul.getRegexReplace()
- : ""));
- for (int ids = 0; ids < idstrings.length; ids++)
- {
- System.out.println("ID String : " + idstrings[ids]
- + "\nWithout onlyIfMatches:");
- String[] urls = ul.makeUrls(idstrings[ids], false);
- testUrls(ul, idstrings[ids], urls);
- System.out.println("With onlyIfMatches set.");
- urls = ul.makeUrls(idstrings[ids], true);
- testUrls(ul, idstrings[ids], urls);
- }
- }
- else
- {
- System.err.println("Invalid URLLink : " + links[i] + " : "
- + ul.getInvalidMessage());
- }
- }
- }
}
*/
package jalview.viewmodel;
+import java.awt.Color;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.analysis.Conservation;
import jalview.api.AlignCalcManagerI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.schemes.Blosum62ColourScheme;
+import jalview.renderer.ResidueShader;
+import jalview.renderer.ResidueShaderI;
import jalview.schemes.ColourSchemeI;
-import jalview.schemes.PIDColourScheme;
import jalview.structure.CommandListener;
import jalview.structure.StructureSelectionManager;
import jalview.structure.VamsasSource;
import jalview.workers.ConsensusThread;
import jalview.workers.StrucConsensusThread;
-import java.awt.Color;
-import java.beans.PropertyChangeSupport;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
/**
* base class holding visualization and analysis attributes and common logic for
* an active alignment view displayed in the GUI
protected boolean ignoreGapsInConsensusCalculation = false;
- protected ColourSchemeI globalColourScheme = null;
+ protected ResidueShaderI residueShading;
@Override
public void setGlobalColourScheme(ColourSchemeI cs)
// TODO: logic refactored from AlignFrame changeColour -
// TODO: autorecalc stuff should be changed to rely on the worker system
// check to see if we should implement a changeColour(cs) method rather than
- // put th logic in here
+ // put the logic in here
// - means that caller decides if they want to just modify state and defer
// calculation till later or to do all calculations in thread.
// via changecolour
- globalColourScheme = cs;
- boolean recalc = false;
+
+ /*
+ * only instantiate alignment colouring once, thereafter update it;
+ * this means that any conservation or PID threshold settings
+ * persist when the alignment colour scheme is changed
+ */
+ if (residueShading == null)
+ {
+ residueShading = new ResidueShader(viewStyle);
+ }
+ residueShading.setColourScheme(cs);
+
+ // TODO: do threshold and increment belong in ViewStyle or ResidueShader?
+ // ...problem: groups need these, but do not currently have a ViewStyle
+
if (cs != null)
{
- recalc = getConservationSelected();
- if (getAbovePIDThreshold() || cs instanceof PIDColourScheme
- || cs instanceof Blosum62ColourScheme)
+ if (getConservationSelected())
{
- recalc = true;
- cs.setThreshold(viewStyle.getThreshold(),
- ignoreGapsInConsensusCalculation);
+ residueShading.setConservation(hconservation);
}
- else
- {
- cs.setThreshold(0, ignoreGapsInConsensusCalculation);
- }
- if (recalc)
- {
- cs.setConsensus(hconsensus);
- cs.setConservation(hconservation);
- }
- cs.setConservationApplied(getConservationSelected());
- cs.alignmentChanged(alignment, hiddenRepSequences);
+ residueShading.alignmentChanged(alignment, hiddenRepSequences);
}
+
+ /*
+ * if 'apply colour to all groups' is selected... do so
+ * (but don't transfer any colour threshold settings to groups)
+ */
if (getColourAppliesToAllGroups())
{
for (SequenceGroup sg : getAlignment().getGroups())
{
- if (cs == null)
- {
- sg.cs = null;
- continue;
- }
- sg.cs = cs.applyTo(sg, getHiddenRepSequences());
- sg.setConsPercGaps(ConsPercGaps);
- if (getAbovePIDThreshold() || cs instanceof PIDColourScheme
- || cs instanceof Blosum62ColourScheme)
- {
- sg.cs.setThreshold(viewStyle.getThreshold(),
- isIgnoreGapsConsensus());
- recalc = true;
- }
- else
- {
- sg.cs.setThreshold(0, isIgnoreGapsConsensus());
- }
-
- if (getConservationSelected())
- {
- sg.cs.setConservationApplied(true);
- recalc = true;
- }
- else
- {
- sg.cs.setConservation(null);
- // sg.cs.setThreshold(0, getIgnoreGapsConsensus());
- }
- if (recalc)
- {
- sg.recalcConservation();
- }
- else
+ /*
+ * retain any colour thresholds per group while
+ * changing choice of colour scheme (JAL-2386)
+ */
+ sg.setColourScheme(cs);
+ if (cs != null)
{
- sg.cs.alignmentChanged(sg, hiddenRepSequences);
+ sg.getGroupColourScheme()
+ .alignmentChanged(sg, hiddenRepSequences);
}
}
}
@Override
public ColourSchemeI getGlobalColourScheme()
{
- return globalColourScheme;
+ return residueShading == null ? null : residueShading
+ .getColourScheme();
+ }
+
+ @Override
+ public ResidueShaderI getResidueShading()
+ {
+ return residueShading;
}
protected AlignmentAnnotation consensus;
protected AlignmentAnnotation complementConsensus;
+ protected AlignmentAnnotation gapcounts;
+
protected AlignmentAnnotation strucConsensus;
protected AlignmentAnnotation conservation;
}
@Override
+ public AlignmentAnnotation getAlignmentGapAnnotation()
+ {
+ return gapcounts;
+ }
+
+ @Override
public AlignmentAnnotation getComplementConsensusAnnotation()
{
return complementConsensus;
public void updateConsensus(final AlignmentViewPanel ap)
{
// see note in mantis : issue number 8585
- if (consensus == null || !autoCalculateConsensus)
+ if ((consensus == null || gapcounts == null) || !autoCalculateConsensus)
{
return;
}
hconsensus = null;
hcomplementConsensus = null;
// colour scheme may hold reference to consensus
- globalColourScheme = null;
+ residueShading = null;
// TODO remove listeners from changeSupport?
changeSupport = null;
setAlignment(null);
}
/**
- * Set the selection group for this window.
+ * Set the selection group for this window. Also sets the current alignment as
+ * the context for the group, if it does not already have one.
*
* @param sg
* - group holding references to sequences in this alignment view
public void setSelectionGroup(SequenceGroup sg)
{
selectionGroup = sg;
+ if (sg != null && sg.getContext() == null)
+ {
+ sg.setContext(alignment);
+ }
}
public void setHiddenColumns(ColumnSelection colsel)
if (ap != null)
{
updateConsensus(ap);
- if (globalColourScheme != null)
+ if (residueShading != null)
{
- globalColourScheme.setThreshold(globalColourScheme.getThreshold(),
+ residueShading.setThreshold(residueShading.getThreshold(),
ignoreGapsInConsensusCalculation);
}
}
selectionGroup.setEndRes(alWidth - 1);
}
- resetAllColourSchemes();
+ updateAllColourSchemes();
calculator.restartWorkers();
// alignment.adjustSequenceAnnotations();
}
/**
* reset scope and do calculations for all applied colourschemes on alignment
*/
- void resetAllColourSchemes()
+ void updateAllColourSchemes()
{
- ColourSchemeI cs = globalColourScheme;
- if (cs != null)
+ ResidueShaderI rs = residueShading;
+ if (rs != null)
{
- cs.alignmentChanged(alignment, hiddenRepSequences);
+ rs.alignmentChanged(alignment, hiddenRepSequences);
- cs.setConsensus(hconsensus);
- if (cs.conservationApplied())
+ rs.setConsensus(hconsensus);
+ if (rs.conservationApplied())
{
- cs.setConservation(Conservation.calculateConservation("All",
+ rs.setConservation(Conservation.calculateConservation("All",
alignment.getSequences(), 0, alignment.getWidth(), false,
getConsPercGaps(), false));
}
consensus = new AlignmentAnnotation("Consensus", "PID",
new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
initConsensus(consensus);
+ gapcounts = new AlignmentAnnotation("Occupancy",
+ "Number of aligned positions",
+ new Annotation[1], 0f, alignment.getHeight(),
+ AlignmentAnnotation.BAR_GRAPH);
+ initGapCounts(gapcounts);
initComplementConsensus();
}
}
}
+ // these should be extracted from the view model - style and settings for
+ // derived annotation
+ private void initGapCounts(AlignmentAnnotation counts)
+ {
+ counts.hasText = false;
+ counts.autoCalculated = true;
+ counts.graph = AlignmentAnnotation.BAR_GRAPH;
+
+ if (showConsensus)
+ {
+ alignment.addAnnotation(counts);
+ }
+ }
+
private void initConservation()
{
if (showConservation)
public void setViewStyle(ViewStyleI settingsForView)
{
viewStyle = new ViewStyle(settingsForView);
+ if (residueShading != null)
+ {
+ residueShading.setConservationApplied(settingsForView
+ .isConservationColourSelected());
+ }
}
@Override
*/
private boolean selectionIsDefinedGroup = false;
-
@Override
public boolean isSelectionDefinedGroup()
{
public class PCAModel
{
+ /*
+ * Jalview 2.10.1 treated gaps as X (peptide) or N (nucleotide)
+ * for pairwise scoring; 2.10.2 uses gap score (last column) in
+ * score matrix (JAL-2397)
+ * Set this flag to true (via Groovy) for 2.10.1 behaviour
+ */
+ private static boolean scoreGapAsAny = false;
public PCAModel(AlignmentView seqstrings2, SequenceI[] seqs2,
boolean nucleotide2)
public void run()
{
-
- pca = new PCA(seqstrings.getSequenceStrings(' '), nucleotide,
+ char gapChar = scoreGapAsAny ? (nucleotide ? 'N' : 'X') : ' ';
+ String[] sequenceStrings = seqstrings.getSequenceStrings(gapChar);
+ pca = new PCA(sequenceStrings, nucleotide,
score_matrix);
pca.setJvCalcMode(jvCalcMode);
pca.run();
ii++;
}
- double[][] comps = new double[ii][ii];
-
- for (int i = 0; i < ii; i++)
- {
- if (pca.getEigenvalue(i) > 1e-4)
- {
- comps[i] = pca.component(i);
- }
- }
-
- top = pca.getM().rows - 1;
+ int height = pca.getHeight();
+ // top = pca.getM().height() - 1;
+ top = height - 1;
points = new Vector<SequencePoint>();
float[][] scores = pca.getComponents(top - 1, top - 2, top - 3, 100);
- for (int i = 0; i < pca.getM().rows; i++)
+ for (int i = 0; i < height; i++)
{
SequencePoint sp = new SequencePoint(seqs[i], scores[i]);
points.addElement(sp);
}
-
}
public void updateRc(RotatableCanvasI rc)
{
- rc.setPoints(points, pca.getM().rows);
+ rc.setPoints(points, pca.getHeight());
}
public boolean isNucleotide()
// note: actual indices for components are dim1-1, etc (patch for JAL-1123)
float[][] scores = pca.getComponents(dim1 - 1, dim2 - 1, dim3 - 1, 100);
- for (int i = 0; i < pca.getM().rows; i++)
+ for (int i = 0; i < pca.getHeight(); i++)
{
- ((SequencePoint) points.elementAt(i)).coord = scores[i];
+ points.elementAt(i).coord = scores[i];
}
}
import jalview.datamodel.SequenceI;
import jalview.renderer.seqfeatures.FeatureRenderer;
import jalview.schemes.FeatureColour;
-import jalview.schemes.UserColourScheme;
+import jalview.util.ColorUtils;
import java.awt.Color;
import java.beans.PropertyChangeListener;
FeatureColourI fc = featureColours.get(featureType);
if (fc == null)
{
- Color col = UserColourScheme.createColourFromName(featureType);
+ Color col = ColorUtils.createColourFromName(featureType);
fc = new FeatureColour(col);
featureColours.put(featureType, fc);
}
import jalview.datamodel.Annotation;
import jalview.datamodel.ProfilesI;
import jalview.datamodel.SequenceI;
-import jalview.schemes.ColourSchemeI;
+import jalview.renderer.ResidueShaderI;
public class ConsensusThread extends AlignCalcWorker
{
try
{
AlignmentAnnotation consensus = getConsensusAnnotation();
- if (consensus == null || calcMan.isPending(this))
+ AlignmentAnnotation gap = getGapAnnotation();
+ if ((consensus == null && gap == null) || calcMan.isPending(this))
{
calcMan.workerComplete(this);
return;
{
AlignmentAnnotation consensus = getConsensusAnnotation();
consensus.annotations = new Annotation[aWidth];
+ AlignmentAnnotation gap = getGapAnnotation();
+ if (gap != null)
+ {
+ gap.annotations = new Annotation[aWidth];
+ }
}
/**
SequenceI[] aseqs = getSequences();
int width = alignment.getWidth();
- ProfilesI hconsensus = AAFrequency.calculate(aseqs, width, 0,
- width, true);
+ ProfilesI hconsensus = AAFrequency.calculate(aseqs, width, 0, width,
+ true);
alignViewport.setSequenceConsensusHash(hconsensus);
setColourSchemeConsensus(hconsensus);
*/
protected void setColourSchemeConsensus(ProfilesI hconsensus)
{
- ColourSchemeI globalColourScheme = alignViewport
- .getGlobalColourScheme();
- if (globalColourScheme != null)
+ ResidueShaderI cs = alignViewport.getResidueShading();
+ if (cs != null)
{
- globalColourScheme.setConsensus(hconsensus);
+ cs.setConsensus(hconsensus);
}
}
}
/**
+ * Get the Gap annotation for the alignment
+ *
+ * @return
+ */
+ protected AlignmentAnnotation getGapAnnotation()
+ {
+ return alignViewport.getAlignmentGapAnnotation();
+ }
+
+ /**
* update the consensus annotation from the sequence profile data using
* current visualization settings.
*/
&& hconsensus != null)
{
deriveConsensus(consensus, hconsensus);
+ AlignmentAnnotation gap = getGapAnnotation();
+ if (gap != null)
+ {
+ deriveGap(gap, hconsensus);
+ }
}
}
long nseq = getSequences().length;
AAFrequency.completeConsensus(consensusAnnotation, hconsensus,
- hconsensus.getStartColumn(),
- hconsensus.getEndColumn() + 1,
+ hconsensus.getStartColumn(), hconsensus.getEndColumn() + 1,
alignViewport.isIgnoreGapsConsensus(),
alignViewport.isShowSequenceLogo(), nseq);
}
/**
+ * Convert the computed consensus data into a gap annotation row for display.
+ *
+ * @param gapAnnotation
+ * the annotation to be populated
+ * @param hconsensus
+ * the computed consensus data
+ */
+ protected void deriveGap(AlignmentAnnotation gapAnnotation,
+ ProfilesI hconsensus)
+ {
+ long nseq = getSequences().length;
+ AAFrequency.completeGapAnnot(gapAnnotation, hconsensus,
+ hconsensus.getStartColumn(), hconsensus.getEndColumn() + 1,
+ nseq);
+ }
+
+ /**
* Get the consensus data stored on the viewport.
*
* @return
{
calcMan.notifyStart(this); // updatingConservation = true;
- while (!calcMan.notifyWorking(this))
+ while ((calcMan != null) && (!calcMan.notifyWorking(this)))
{
try
{
ex.printStackTrace();
}
}
- if (alignViewport.isClosed())
+ if ((alignViewport == null) || (calcMan == null)
+ || (alignViewport.isClosed()))
{
abortAndDestroy();
return;
}
calcMan.workerComplete(this);
+ if ((alignViewport == null) || (calcMan == null)
+ || (alignViewport.isClosed()))
+ {
+ abortAndDestroy();
+ return;
+ }
if (ap != null)
{
ap.paintAlignment(true);
else
{
throw (new Exception(MessageManager.formatMessage(
- "exception.unknown_format_for_file", new String[] {
- format.toString(), result.getAligfile() })));
+ "exception.unknown_format_for_file", new String[] { "",
+ result.getAligfile() })));
}
}
else
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.schemes.FeatureColour;
-import jalview.schemes.UserColourScheme;
+import jalview.util.ColorUtils;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.WsParamSetI;
annot.description += "<br/>" + threshNote;
}
annot.description += "</html>";
- Color col = UserColourScheme.createColourFromName(typeName
+ Color col = ColorUtils.createColourFromName(typeName
+ scr.getMethod());
for (int p = 0, ps = annot.annotations.length; p < ps; p++)
{
import jalview.datamodel.AlignmentI;
import jalview.io.FileFormat;
import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
import jalview.io.FormatAdapter;
import jalview.ws.params.OptionI;
import jalview.ws.params.simple.BooleanOption;
@Override
public List<String> getURLEncodedParameter()
{
- ArrayList<String> prms = new ArrayList<String>();
- prms.add("format='" + format + "'");
+ List<String> prms = new ArrayList<String>();
+ prms.add("format='" + format.getName() + "'");
if (type != null)
{
prms.add("type='" + type.toString() + "'");
if (tok.startsWith("format"))
{
- for (FileFormatI fmt : FileFormat.values())
+ for (FileFormatI fmt : FileFormats.getInstance().getFormats())
{
- if (fmt.isWritable() && val.equalsIgnoreCase(fmt.toString()))
+ if (fmt.isWritable() && val.equalsIgnoreCase(fmt.getName()))
{
format = fmt;
return true;
}
warnings.append("Invalid alignment format '" + val
+ "'. Must be one of (");
- for (FileFormatI fmt : FileFormat.values())
+ for (String fmt : FileFormats.getInstance().getWritableFormats(true))
{
- if (fmt.isWritable())
- {
- warnings.append(" " + fmt).toString();
- }
+ warnings.append(" ").append(fmt);
}
warnings.append(")\n");
}
"Append jalview style /start-end suffix to ID", false, false,
writeAsFile, null));
+ List<String> writable = FileFormats
+ .getInstance().getWritableFormats(true);
lst.add(new Option("format", "Alignment upload format", true,
- FileFormat.Fasta.toString(), format.toString(), getWritableFormats(),
+ FileFormat.Fasta.toString(), format.getName(), writable,
null));
lst.add(createMolTypeOption("type", "Sequence type", false, type, null));
return lst;
}
- /**
- * @return
- */
- protected List<String> getWritableFormats()
- {
- List<String> formats = new ArrayList<String>();
- for (FileFormatI ff : FileFormat.values())
- {
- if (ff.isWritable())
- {
- formats.add(ff.toString());
- }
- }
- return formats;
- }
-
}
public class SiftsClient extends StructureMappingClient implements
SiftsClientI
{
+ /*
+ * for use in mocking out file fetch for tests only
+ * - reset to null after testing!
+ */
+ private static File mockSiftsFile;
+
private Entry siftsEntry;
private String pdbId;
*/
public static File getSiftsFile(String pdbId) throws SiftsException
{
+ /*
+ * return mocked file if it has been set
+ */
+ if (mockSiftsFile != null)
+ {
+ return mockSiftsFile;
+ }
+
String siftsFileName = SiftsSettings.getSiftDownloadDirectory()
+ pdbId.toLowerCase() + ".xml.gz";
File siftsFile = new File(siftsFileName);
return siftsEntry.getDbVersion();
}
+ public static void setMockSiftsFile(File file)
+ {
+ mockSiftsFile = file;
+ }
+
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.ws.utils;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+public class UrlDownloadClient
+{
+ public UrlDownloadClient()
+ {
+
+ }
+
+ /**
+ * Download and save a file from a URL
+ *
+ * @param urlstring
+ * url to download from, as string
+ * @param outfile
+ * the name of file to save the URLs to
+ * @throws IOException
+ */
+ public void download(String urlstring, String outfile) throws IOException
+ {
+ FileOutputStream fos = null;
+ ReadableByteChannel rbc = null;
+ Path temp = null;
+ try
+ {
+ temp = Files.createTempFile(".jalview_", ".tmp");
+
+ URL url = new URL(urlstring);
+ rbc = Channels.newChannel(url.openStream());
+ fos = new FileOutputStream(temp.toString());
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+
+ // copy tempfile to outfile once our download completes
+ // incase something goes wrong
+ Files.copy(temp, Paths.get(outfile),
+ StandardCopyOption.REPLACE_EXISTING);
+ } catch (IOException e)
+ {
+ throw e;
+ } finally
+ {
+ try
+ {
+ if (fos != null)
+ {
+ fos.close();
+ }
+ } catch (IOException e)
+ {
+ System.out
+ .println("Exception while closing download file output stream: "
+ + e.getMessage());
+ }
+ try
+ {
+ if (rbc != null)
+ {
+ rbc.close();
+ }
+ } catch (IOException e)
+ {
+ System.out.println("Exception while closing download channel: "
+ + e.getMessage());
+ }
+ try
+ {
+ if (temp != null)
+ {
+ Files.deleteIfExists(temp);
+ }
+ } catch (IOException e)
+ {
+ System.out.println("Exception while deleting download temp file: "
+ + e.getMessage());
+ }
+ }
+ }
+}
* @author gmcarstairs
*
*/
-public class DnaAlignmentGenerator
+public class AlignmentGenerator
{
-
@BeforeClass(alwaysRun = true)
public void setUpJvOptionPane()
{
private static final char ZERO = '0';
- private static final char[] BASES = new char[] { 'G', 'T', 'C', 'A' };
+ private static final char[] NUCS = "GTCA".toCharArray();
+
+ private static final char[] PEPS = "MILVFYWHKRDEQNTCGASNP".toCharArray();
+
+ private static char[] BASES;
private Random random;
*/
public static void main(String[] args)
{
- if (args.length != 5)
+ if (args.length != 6)
{
usage();
return;
}
- int width = Integer.parseInt(args[0]);
- int height = Integer.parseInt(args[1]);
- long randomSeed = Long.valueOf(args[2]);
- int gapPercentage = Integer.valueOf(args[3]);
- int changePercentage = Integer.valueOf(args[4]);
- AlignmentI al = new DnaAlignmentGenerator().generate(width, height,
+ boolean nucleotide = args[0].toLowerCase().startsWith("n");
+ int width = Integer.parseInt(args[1]);
+ int height = Integer.parseInt(args[2]);
+ long randomSeed = Long.valueOf(args[3]);
+ int gapPercentage = Integer.valueOf(args[4]);
+ int changePercentage = Integer.valueOf(args[5]);
+ AlignmentI al = new AlignmentGenerator(nucleotide).generate(width,
+ height,
randomSeed, gapPercentage, changePercentage);
System.out.println("; " + height + " sequences of " + width
private static void usage()
{
System.out.println("Usage:");
- System.out.println("arg0: number of (non-gap) bases per sequence");
- System.out.println("arg1: number sequences");
+ System.out.println("arg0: n (for nucleotide) or p (for peptide)");
+ System.out.println("arg1: number of (non-gap) bases per sequence");
+ System.out.println("arg2: number sequences");
System.out
- .println("arg2: an integer as random seed (same seed = same results)");
- System.out.println("arg3: percentage of gaps to (randomly) generate");
+ .println("arg3: an integer as random seed (same seed = same results)");
+ System.out.println("arg4: percentage of gaps to (randomly) generate");
System.out
- .println("arg4: percentage of 'mutations' to (randomly) generate");
- System.out.println("Example: DnaAlignmentGenerator 12 15 387 10 5");
+ .println("arg5: percentage of 'mutations' to (randomly) generate");
+ System.out.println("Example: AlignmentGenerator n 12 15 387 10 5");
System.out
- .println("- 15 sequences of 12 bases each, approx 10% gaps and 5% mutations, random seed = 387");
+ .println("- 15 nucleotide sequences of 12 bases each, approx 10% gaps and 5% mutations, random seed = 387");
}
/**
- * Default constructor
+ * Constructor that sets nucleotide or peptide symbol set
*/
- public DnaAlignmentGenerator()
+ public AlignmentGenerator(boolean nuc)
{
-
+ BASES = nuc ? NUCS : PEPS;
}
/**
for (int count = 0; count < length;)
{
boolean addGap = random.nextInt(100) < gapPercentage;
- char c = addGap ? GAP : BASES[random.nextInt(Integer.MAX_VALUE) % 4];
+ char c = addGap ? GAP : BASES[random.nextInt(Integer.MAX_VALUE)
+ % BASES.length];
seq.append(c);
if (!addGap)
{
char newchar = c;
while (newchar == c)
{
- newchar = BASES[random.nextInt(Integer.MAX_VALUE) % 4];
+ newchar = BASES[random.nextInt(Integer.MAX_VALUE) % BASES.length];
}
return newchar;
}
/*
* Generate cDNA - 8 sequences of 12 bases each.
*/
- AlignmentI cdna = new DnaAlignmentGenerator().generate(12, 8, 97, 5, 5);
+ AlignmentI cdna = new AlignmentGenerator(true)
+ .generate(12, 8, 97, 5, 5);
ColumnSelection cs = new ColumnSelection();
AlignViewportI av = new AlignViewport(cdna, cs);
Dna dna = new Dna(av, new int[] { 0, cdna.getWidth() - 1 });
AlignmentAnnotation ann = iter.next();
assertEquals("D.melanogaster.2", ann.sequenceRef.getName());
assertFalse(iter.hasNext());
+
+ // invalid id
+ anns = al.findAnnotation("CalcIdForD.melanogaster.?");
+ assertFalse(iter.hasNext());
+ anns = al.findAnnotation(null);
+ assertFalse(iter.hasNext());
}
@Test(groups = { "Functional" })
assertSame(pep.getDatasetSequence(), cds.getDBRefs()[0].map.to);
}
+ @Test(groups = { "Functional" })
+ public void testFindGroup()
+ {
+ SequenceI seq1 = new Sequence("seq1", "ABCDEF---GHI");
+ SequenceI seq2 = new Sequence("seq2", "---JKLMNO---");
+ AlignmentI a = new Alignment(new SequenceI[] { seq1, seq2 });
+
+ assertNull(a.findGroup(null, 0));
+ assertNull(a.findGroup(seq1, 1));
+ assertNull(a.findGroup(seq1, -1));
+
+ /*
+ * add a group consisting of just "DEF"
+ */
+ SequenceGroup sg1 = new SequenceGroup();
+ sg1.addSequence(seq1, false);
+ sg1.setStartRes(3);
+ sg1.setEndRes(5);
+ a.addGroup(sg1);
+
+ assertNull(a.findGroup(seq1, 2)); // position not in group
+ assertNull(a.findGroup(seq1, 6)); // position not in group
+ assertNull(a.findGroup(seq2, 5)); // sequence not in group
+ assertSame(a.findGroup(seq1, 3), sg1); // yes
+ assertSame(a.findGroup(seq1, 4), sg1);
+ assertSame(a.findGroup(seq1, 5), sg1);
+
+ /*
+ * add a group consisting of
+ * EF--
+ * KLMN
+ */
+ SequenceGroup sg2 = new SequenceGroup();
+ sg2.addSequence(seq1, false);
+ sg2.addSequence(seq2, false);
+ sg2.setStartRes(4);
+ sg2.setEndRes(7);
+ a.addGroup(sg2);
+
+ assertNull(a.findGroup(seq1, 2)); // unchanged
+ assertSame(a.findGroup(seq1, 3), sg1); // unchanged
+ /*
+ * if a residue is in more than one group, method returns
+ * the first found (in order groups were added)
+ */
+ assertSame(a.findGroup(seq1, 4), sg1);
+ assertSame(a.findGroup(seq1, 5), sg1);
+
+ /*
+ * seq2 only belongs to the second group
+ */
+ assertSame(a.findGroup(seq2, 4), sg2);
+ assertSame(a.findGroup(seq2, 5), sg2);
+ assertSame(a.findGroup(seq2, 6), sg2);
+ assertSame(a.findGroup(seq2, 7), sg2);
+ assertNull(a.findGroup(seq2, 3));
+ assertNull(a.findGroup(seq2, 8));
+ }
+
}
assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
// hiding column 4 expands [3, 3] to [3, 4]
- // not fancy enough to coalesce this into [3, 5] though
+ // and merges to [5, 5] to make [3, 5]
cs.hideColumns(4);
hidden = cs.getHiddenColumns();
- assertEquals(2, hidden.size());
- assertEquals("[3, 4]", Arrays.toString(hidden.get(0)));
- assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
+ assertEquals(1, hidden.size());
+ assertEquals("[3, 5]", Arrays.toString(hidden.get(0)));
// clear hidden columns (note they are added to selected)
cs.revealAllHiddenColumns();
assertEquals("[5, 7]", Arrays.toString(cs2.getHiddenColumns().get(0)));
assertEquals("[10, 11]", Arrays.toString(cs2.getHiddenColumns().get(1)));
}
+
+ /**
+ * Test for the case when a hidden range encloses more one already hidden
+ * range
+ */
+ @Test(groups = { "Functional" })
+ public void testHideColumns_subsumingHidden()
+ {
+ /*
+ * JAL-2370 bug scenario:
+ * two hidden ranges subsumed by a third
+ */
+ ColumnSelection cs = new ColumnSelection();
+ cs.hideColumns(49, 59);
+ cs.hideColumns(69, 79);
+ List<int[]> hidden = cs.getHiddenColumns();
+ assertEquals(2, hidden.size());
+ assertEquals("[49, 59]", Arrays.toString(hidden.get(0)));
+ assertEquals("[69, 79]", Arrays.toString(hidden.get(1)));
+
+ cs.hideColumns(48, 80);
+ hidden = cs.getHiddenColumns();
+ assertEquals(1, hidden.size());
+ assertEquals("[48, 80]", Arrays.toString(hidden.get(0)));
+
+ /*
+ * another...joining hidden ranges
+ */
+ cs = new ColumnSelection();
+ cs.hideColumns(10, 20);
+ cs.hideColumns(30, 40);
+ cs.hideColumns(50, 60);
+ // hiding 21-49 should merge to one range
+ cs.hideColumns(21, 49);
+ hidden = cs.getHiddenColumns();
+ assertEquals(1, hidden.size());
+ assertEquals("[10, 60]", Arrays.toString(hidden.get(0)));
+
+ /*
+ * another...lef overlap, subsumption, right overlap,
+ * no overlap of existing hidden ranges
+ */
+ cs = new ColumnSelection();
+ cs.hideColumns(10, 20);
+ cs.hideColumns(10, 20);
+ cs.hideColumns(30, 35);
+ cs.hideColumns(40, 50);
+ cs.hideColumns(60, 70);
+
+ cs.hideColumns(15, 45);
+ hidden = cs.getHiddenColumns();
+ assertEquals(2, hidden.size());
+ assertEquals("[10, 50]", Arrays.toString(hidden.get(0)));
+ assertEquals("[60, 70]", Arrays.toString(hidden.get(1)));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testStretchGroup_expand()
+ {
+ /*
+ * test that emulates clicking column 4 (selected)
+ * and dragging right to column 5 (all base 0)
+ */
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(4);
+ SequenceGroup sg = new SequenceGroup();
+ sg.setStartRes(4);
+ sg.setEndRes(4);
+ cs.stretchGroup(5, sg, 4, 4);
+ assertEquals(cs.getSelected().size(), 2);
+ assertTrue(cs.contains(4));
+ assertTrue(cs.contains(5));
+ assertEquals(sg.getStartRes(), 4);
+ assertEquals(sg.getEndRes(), 5);
+
+ /*
+ * emulate drag right with columns 10-20 already selected
+ */
+ cs.clear();
+ for (int i = 10; i <= 20; i++)
+ {
+ cs.addElement(i);
+ }
+ assertEquals(cs.getSelected().size(), 11);
+ sg = new SequenceGroup();
+ sg.setStartRes(10);
+ sg.setEndRes(20);
+ cs.stretchGroup(21, sg, 10, 20);
+ assertEquals(cs.getSelected().size(), 12);
+ assertTrue(cs.contains(10));
+ assertTrue(cs.contains(21));
+ assertEquals(sg.getStartRes(), 10);
+ assertEquals(sg.getEndRes(), 21);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testStretchGroup_shrink()
+ {
+ /*
+ * emulate drag left to 19 with columns 10-20 already selected
+ */
+ ColumnSelection cs = new ColumnSelection();
+ for (int i = 10; i <= 20; i++)
+ {
+ cs.addElement(i);
+ }
+ assertEquals(cs.getSelected().size(), 11);
+ SequenceGroup sg = new SequenceGroup();
+ sg.setStartRes(10);
+ sg.setEndRes(20);
+ cs.stretchGroup(19, sg, 10, 20);
+ assertEquals(cs.getSelected().size(), 10);
+ assertTrue(cs.contains(10));
+ assertTrue(cs.contains(19));
+ assertFalse(cs.contains(20));
+ assertEquals(sg.getStartRes(), 10);
+ assertEquals(sg.getEndRes(), 19);
+ }
}
--- /dev/null
+package jalview.datamodel;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import jalview.schemes.NucleotideColourScheme;
+
+import org.testng.annotations.Test;
+
+public class SequenceGroupTest
+{
+ @Test(groups={"Functional"})
+ public void testAddSequence()
+ {
+ SequenceGroup sg = new SequenceGroup();
+ assertTrue(sg.getSequences().isEmpty());
+
+ SequenceI seq1 = new Sequence("seq1", "abc");
+ SequenceI seq2 = new Sequence("seq2", "abc");
+ SequenceI seq3 = new Sequence(seq1);
+
+ sg.addSequence(null, false);
+ assertTrue(sg.getSequences().isEmpty());
+ sg.addSequence(seq1, false);
+ assertEquals(sg.getSequences().size(), 1);
+ assertTrue(sg.getSequences().contains(seq1));
+ // adding the same sequence again does nothing
+ sg.addSequence(seq1, false);
+ assertEquals(sg.getSequences().size(), 1);
+ assertTrue(sg.getSequences().contains(seq1));
+ sg.addSequence(seq2, false);
+ sg.addSequence(seq2, false);
+ sg.addSequence(seq3, false);
+ assertEquals(sg.getSequences().size(), 3);
+ assertTrue(sg.getSequences().contains(seq1));
+ assertTrue(sg.getSequences().contains(seq2));
+ assertTrue(sg.getSequences().contains(seq3));
+ }
+
+ @Test(groups={"Functional"})
+ public void testAddOrRemove()
+ {
+ SequenceGroup sg = new SequenceGroup();
+ assertTrue(sg.getSequences().isEmpty());
+
+ SequenceI seq1 = new Sequence("seq1", "abc");
+ SequenceI seq2 = new Sequence("seq2", "abc");
+ SequenceI seq3 = new Sequence(seq1);
+
+ sg.addOrRemove(seq1, false);
+ assertEquals(sg.getSequences().size(), 1);
+ sg.addOrRemove(seq2, false);
+ assertEquals(sg.getSequences().size(), 2);
+ sg.addOrRemove(seq3, false);
+ assertEquals(sg.getSequences().size(), 3);
+ assertTrue(sg.getSequences().contains(seq1));
+ assertTrue(sg.getSequences().contains(seq2));
+ assertTrue(sg.getSequences().contains(seq3));
+ sg.addOrRemove(seq1, false);
+ assertEquals(sg.getSequences().size(), 2);
+ assertFalse(sg.getSequences().contains(seq1));
+ }
+
+ @Test(groups={"Functional"})
+ public void testGetColourScheme()
+ {
+ SequenceGroup sg = new SequenceGroup();
+ assertNotNull(sg.getGroupColourScheme());
+ assertNull(sg.getColourScheme());
+
+ sg.setGroupColourScheme(null);
+ assertNull(sg.getColourScheme());
+
+ NucleotideColourScheme scheme = new NucleotideColourScheme();
+ sg.setColourScheme(scheme);
+ assertSame(scheme, sg.getColourScheme());
+ }
+
+ @Test(groups={"Functional"})
+ public void testSetContext()
+ {
+ SequenceGroup sg1 = new SequenceGroup();
+ SequenceGroup sg2 = new SequenceGroup();
+ SequenceGroup sg3 = new SequenceGroup();
+ assertNull(sg1.getContext());
+ sg1.setContext(null);
+ assertNull(sg1.getContext());
+ try
+ {
+ sg1.setContext(sg1); // self-reference :-O
+ fail("Expected exception");
+ } catch (IllegalArgumentException e)
+ {
+ // expected
+ assertNull(sg1.getContext());
+ }
+ sg1.setContext(sg2);
+ assertSame(sg2, sg1.getContext());
+ sg2.setContext(sg3);
+ try
+ {
+ sg3.setContext(sg1); // circular reference :-O
+ fail("Expected exception");
+ } catch (IllegalArgumentException e)
+ {
+ // expected
+ assertNull(sg3.getContext());
+ }
+ }
+
+ @Test(groups = { "Functional" })
+ public void testContains()
+ {
+ /*
+ * essentially the same tests as AlignmentI.findGroup
+ * but from a particular group's perspective
+ */
+
+ SequenceI seq1 = new Sequence("seq1", "ABCDEF---GHI");
+ SequenceI seq2 = new Sequence("seq2", "---JKLMNO---");
+ AlignmentI a = new Alignment(new SequenceI[] { seq1, seq2 });
+ /*
+ * add a group consisting of just "DEF"
+ */
+ SequenceGroup sg1 = new SequenceGroup();
+ sg1.addSequence(seq1, false);
+ sg1.setStartRes(3);
+ sg1.setEndRes(5);
+
+ /*
+ * test sequence membership
+ */
+ assertTrue(sg1.contains(seq1));
+ assertFalse(sg1.contains(seq2));
+
+ /*
+ * test sequence+position
+ */
+
+ assertFalse(sg1.contains(seq1, 2)); // position not in group
+ assertFalse(sg1.contains(seq1, 6)); // position not in group
+ assertFalse(sg1.contains(seq2, 5)); // sequence not in group
+ assertTrue(sg1.contains(seq1, 3)); // yes
+ assertTrue(sg1.contains(seq1, 4));
+ assertTrue(sg1.contains(seq1, 5));
+
+ /*
+ * add a group consisting of
+ * EF--
+ * KLMN
+ */
+ SequenceGroup sg2 = new SequenceGroup();
+ sg2.addSequence(seq1, false);
+ sg2.addSequence(seq2, false);
+ sg2.setStartRes(4);
+ sg2.setEndRes(7);
+ a.addGroup(sg2);
+
+ /*
+ * if a residue is in more than one group, method returns
+ * the first found (in order groups were added)
+ */
+ assertTrue(sg2.contains(seq1, 4));
+ assertTrue(sg2.contains(seq1, 5));
+
+ /*
+ * seq2 only belongs to the second group
+ */
+ assertTrue(sg2.contains(seq2, 4));
+ assertTrue(sg2.contains(seq2, 5));
+ assertTrue(sg2.contains(seq2, 6));
+ assertTrue(sg2.contains(seq2, 7));
+ assertFalse(sg2.contains(seq2, 3));
+ assertFalse(sg2.contains(seq2, 8));
+ sg2.setEndRes(8);
+ assertTrue(sg2.contains(seq2, 8));
+ sg2.deleteSequence(seq2, false);
+ assertFalse(sg2.contains(seq2));
+
+ }
+}
--- /dev/null
+package jalview.ext.android;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+public class SparseDoubleArrayTest
+{
+
+ @Test
+ public void testConstructor()
+ {
+ double[] d = new double[] { 0d, 0d, 1.2d, 0d, 0d, 3.4d };
+ SparseDoubleArray s = new SparseDoubleArray(d);
+ for (int i = 0; i < d.length; i++)
+ {
+ assertEquals(s.get(i), d[i], "At [" + i + "]");
+ }
+ }
+
+ @Test
+ public void testAdd()
+ {
+ double[] d = new double[] { 0d, 0d, 1.2d, 0d, 0d, 3.4d };
+ SparseDoubleArray s = new SparseDoubleArray(d);
+ // add to zero (absent)
+ s.add(0, 3.2d);
+ assertEquals(s.get(0), 3.2d);
+ // add to non-zero
+ s.add(0, 2.5d);
+ assertEquals(s.get(0), 5.7d);
+ // add negative value
+ s.add(2, -5.3d);
+ assertEquals(s.get(2), -4.1d);
+ // add to unset value
+ s.add(12, 9.8d);
+ assertEquals(s.get(12), 9.8d);
+ }
+
+ @Test
+ public void testDivide()
+ {
+ double delta = 1.0e-10;
+ double[] d = new double[] { 0d, 2.4d, 1.2d, 0d, -4.8d, -3.6d };
+ SparseDoubleArray s = new SparseDoubleArray(d);
+ assertEquals(s.divide(0, 1d), 0d); // no such entry
+ assertEquals(s.divide(2, 0d), 0d); // zero divisor
+ assertEquals(s.divide(1, 2d), 1.2d, delta); // + / +
+ assertEquals(s.divide(2, -2d), -0.6d, delta); // + / -
+ assertEquals(s.divide(4, 3d), -1.6d, delta); // - / +
+ assertEquals(s.divide(5, -3d), 1.2d, delta); // - / -
+ }
+}
// need some mappings!
StructureMappingcommandSet[] commands = JmolCommands
- .getColourBySequenceCommand(ssm, files, seqs, sr, null, al);
+ .getColourBySequenceCommand(ssm, files, seqs, sr, null,
+ af.getViewport());
}
}
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
+import jalview.bin.Jalview;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.JvOptionPane;
@BeforeClass(alwaysRun = true)
public static void setUpBeforeClass() throws Exception
{
- jalview.bin.Jalview.main(new String[] {
- "-noquestionnaire -nonews -props",
+ Jalview.main(new String[] { "-noquestionnaire", "-nonews", "-props",
"test/jalview/ext/rbvi/chimera/testProps.jvprops" });
}
--- /dev/null
+HEADER ELECTRON TRANSPORT 26-APR-15 4ZHO
+TITLE THE CRYSTAL STRUCTURE OF ARABIDOPSIS FERREDOXIN 2 WITH 2FE-2S CLUSTER
+COMPND MOL_ID: 1;
+COMPND 2 MOLECULE: FERREDOXIN-2, CHLOROPLASTIC;
+COMPND 3 CHAIN: A, B;
+COMPND 4 SYNONYM: ATFD2;
+COMPND 5 ENGINEERED: YES
+SOURCE MOL_ID: 1;
+SOURCE 2 ORGANISM_SCIENTIFIC: ARABIDOPSIS THALIANA;
+SOURCE 3 ORGANISM_COMMON: MOUSE-EAR CRESS;
+SOURCE 4 ORGANISM_TAXID: 3702;
+SOURCE 5 GENE: FD2, PETF, PETF1, AT1G60950, T7P1.9;
+SOURCE 6 EXPRESSION_SYSTEM: ESCHERICHIA COLI BL21(DE3);
+SOURCE 7 EXPRESSION_SYSTEM_TAXID: 469008
+KEYWDS FERREDOXIN 2FE-2S CLUSTER ELECTRON TRANSFER CHLOROPLAST, ELECTRON
+KEYWDS 2 TRANSPORT
+EXPDTA X-RAY DIFFRACTION
+AUTHOR R.GRINTER,I.JOSTS,A.W.ROSZAK,R.J.COGDELL,D.WALKER
+REVDAT 2 09-NOV-16 4ZHO 1 JRNL
+REVDAT 1 31-AUG-16 4ZHO 0
+JRNL AUTH R.GRINTER,I.JOSTS,K.MOSBAHI,A.W.ROSZAK,R.J.COGDELL,
+JRNL AUTH 2 A.M.BONVIN,J.J.MILNER,S.M.KELLY,O.BYRON,B.O.SMITH,D.WALKER
+JRNL TITL STRUCTURE OF THE BACTERIAL PLANT-FERREDOXIN RECEPTOR FUSA.
+JRNL REF NAT COMMUN V. 7 13308 2016
+JRNL REFN ESSN 2041-1723
+JRNL PMID 27796364
+JRNL DOI 10.1038/NCOMMS13308
+REMARK 2
+REMARK 2 RESOLUTION. 2.34 ANGSTROMS.
+REMARK 3
+REMARK 3 REFINEMENT.
+REMARK 3 PROGRAM : REFMAC 5.8.0049
+REMARK 3 AUTHORS : MURSHUDOV,VAGIN,DODSON
+REMARK 3
+REMARK 3 REFINEMENT TARGET : MAXIMUM LIKELIHOOD
+REMARK 3
+REMARK 3 DATA USED IN REFINEMENT.
+REMARK 3 RESOLUTION RANGE HIGH (ANGSTROMS) : 2.34
+REMARK 3 RESOLUTION RANGE LOW (ANGSTROMS) : 60.73
+REMARK 3 DATA CUTOFF (SIGMA(F)) : NULL
+REMARK 3 COMPLETENESS FOR RANGE (%) : 99.5
+REMARK 3 NUMBER OF REFLECTIONS : 12221
+REMARK 3
+REMARK 3 FIT TO DATA USED IN REFINEMENT.
+REMARK 3 CROSS-VALIDATION METHOD : THROUGHOUT
+REMARK 3 FREE R VALUE TEST SET SELECTION : RANDOM
+REMARK 3 R VALUE (WORKING + TEST SET) : 0.198
+REMARK 3 R VALUE (WORKING SET) : 0.197
+REMARK 3 FREE R VALUE : 0.216
+REMARK 3 FREE R VALUE TEST SET SIZE (%) : 4.900
+REMARK 3 FREE R VALUE TEST SET COUNT : 627
+REMARK 3
+REMARK 3 FIT IN THE HIGHEST RESOLUTION BIN.
+REMARK 3 TOTAL NUMBER OF BINS USED : 20
+REMARK 3 BIN RESOLUTION RANGE HIGH (A) : 2.34
+REMARK 3 BIN RESOLUTION RANGE LOW (A) : 2.40
+REMARK 3 REFLECTION IN BIN (WORKING SET) : 864
+REMARK 3 BIN COMPLETENESS (WORKING+TEST) (%) : 98.58
+REMARK 3 BIN R VALUE (WORKING SET) : 0.2390
+REMARK 3 BIN FREE R VALUE SET COUNT : 39
+REMARK 3 BIN FREE R VALUE : 0.3090
+REMARK 3
+REMARK 3 NUMBER OF NON-HYDROGEN ATOMS USED IN REFINEMENT.
+REMARK 3 PROTEIN ATOMS : 1440
+REMARK 3 NUCLEIC ACID ATOMS : 0
+REMARK 3 HETEROGEN ATOMS : 10
+REMARK 3 SOLVENT ATOMS : 38
+REMARK 3
+REMARK 3 B VALUES.
+REMARK 3 FROM WILSON PLOT (A**2) : NULL
+REMARK 3 MEAN B VALUE (OVERALL, A**2) : 59.55
+REMARK 3 OVERALL ANISOTROPIC B VALUE.
+REMARK 3 B11 (A**2) : 2.75000
+REMARK 3 B22 (A**2) : 2.75000
+REMARK 3 B33 (A**2) : -5.50000
+REMARK 3 B12 (A**2) : 0.00000
+REMARK 3 B13 (A**2) : 0.00000
+REMARK 3 B23 (A**2) : 0.00000
+REMARK 3
+REMARK 3 ESTIMATED OVERALL COORDINATE ERROR.
+REMARK 3 ESU BASED ON R VALUE (A): 0.229
+REMARK 3 ESU BASED ON FREE R VALUE (A): 0.180
+REMARK 3 ESU BASED ON MAXIMUM LIKELIHOOD (A): 0.136
+REMARK 3 ESU FOR B VALUES BASED ON MAXIMUM LIKELIHOOD (A**2): 12.808
+REMARK 3
+REMARK 3 CORRELATION COEFFICIENTS.
+REMARK 3 CORRELATION COEFFICIENT FO-FC : 0.949
+REMARK 3 CORRELATION COEFFICIENT FO-FC FREE : 0.952
+REMARK 3
+REMARK 3 RMS DEVIATIONS FROM IDEAL VALUES COUNT RMS WEIGHT
+REMARK 3 BOND LENGTHS REFINED ATOMS (A): 1468 ; 0.017 ; 0.019
+REMARK 3 BOND LENGTHS OTHERS (A): 1296 ; 0.001 ; 0.020
+REMARK 3 BOND ANGLES REFINED ATOMS (DEGREES): 1990 ; 1.933 ; 1.975
+REMARK 3 BOND ANGLES OTHERS (DEGREES): 3026 ; 0.912 ; 3.000
+REMARK 3 TORSION ANGLES, PERIOD 1 (DEGREES): 192 ; 7.288 ; 5.000
+REMARK 3 TORSION ANGLES, PERIOD 2 (DEGREES): 66 ;34.298 ;26.970
+REMARK 3 TORSION ANGLES, PERIOD 3 (DEGREES): 234 ;14.918 ;15.000
+REMARK 3 TORSION ANGLES, PERIOD 4 (DEGREES): 2 ; 5.922 ;15.000
+REMARK 3 CHIRAL-CENTER RESTRAINTS (A**3): 230 ; 0.115 ; 0.200
+REMARK 3 GENERAL PLANES REFINED ATOMS (A): 1682 ; 0.007 ; 0.020
+REMARK 3 GENERAL PLANES OTHERS (A): 276 ; 0.001 ; 0.020
+REMARK 3 NON-BONDED CONTACTS REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 NON-BONDED CONTACTS OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 NON-BONDED TORSION REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 NON-BONDED TORSION OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 H-BOND (X...Y) REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 H-BOND (X...Y) OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 POTENTIAL METAL-ION REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 POTENTIAL METAL-ION OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY VDW REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY VDW OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY H-BOND REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY H-BOND OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY METAL-ION REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY METAL-ION OTHERS (A): NULL ; NULL ; NULL
+REMARK 3
+REMARK 3 ISOTROPIC THERMAL FACTOR RESTRAINTS. COUNT RMS WEIGHT
+REMARK 3 MAIN-CHAIN BOND REFINED ATOMS (A**2): 774 ; 3.602 ; 4.642
+REMARK 3 MAIN-CHAIN BOND OTHER ATOMS (A**2): 773 ; 3.584 ; 4.636
+REMARK 3 MAIN-CHAIN ANGLE REFINED ATOMS (A**2): 964 ; 4.741 ; 6.949
+REMARK 3 MAIN-CHAIN ANGLE OTHER ATOMS (A**2): 965 ; 4.738 ; 6.957
+REMARK 3 SIDE-CHAIN BOND REFINED ATOMS (A**2): 694 ; 5.685 ; 5.263
+REMARK 3 SIDE-CHAIN BOND OTHER ATOMS (A**2): 691 ; 5.624 ; 5.277
+REMARK 3 SIDE-CHAIN ANGLE REFINED ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3 SIDE-CHAIN ANGLE OTHER ATOMS (A**2): 1021 ; 8.298 ; 7.648
+REMARK 3 LONG RANGE B REFINED ATOMS (A**2): 1582 ; 9.824 ;37.488
+REMARK 3 LONG RANGE B OTHER ATOMS (A**2): 1580 ; 9.825 ;37.492
+REMARK 3
+REMARK 3 ANISOTROPIC THERMAL FACTOR RESTRAINTS. COUNT RMS WEIGHT
+REMARK 3 RIGID-BOND RESTRAINTS (A**2): NULL ; NULL ; NULL
+REMARK 3 SPHERICITY; FREE ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3 SPHERICITY; BONDED ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3
+REMARK 3 NCS RESTRAINTS STATISTICS
+REMARK 3 NUMBER OF DIFFERENT NCS GROUPS : NULL
+REMARK 3
+REMARK 3 TLS DETAILS
+REMARK 3 NUMBER OF TLS GROUPS : 2
+REMARK 3
+REMARK 3 TLS GROUP : 1
+REMARK 3 NUMBER OF COMPONENTS GROUP : 1
+REMARK 3 COMPONENTS C SSSEQI TO C SSSEQI
+REMARK 3 RESIDUE RANGE : A 2 A 118
+REMARK 3 ORIGIN FOR THE GROUP (A): -11.9068 -7.9134 -35.1151
+REMARK 3 T TENSOR
+REMARK 3 T11: 0.0724 T22: 0.0486
+REMARK 3 T33: 0.0466 T12: -0.0255
+REMARK 3 T13: 0.0362 T23: -0.0257
+REMARK 3 L TENSOR
+REMARK 3 L11: 3.9618 L22: 2.5662
+REMARK 3 L33: 3.5301 L12: -0.2237
+REMARK 3 L13: -2.4244 L23: -0.7777
+REMARK 3 S TENSOR
+REMARK 3 S11: -0.1452 S12: 0.2312 S13: 0.0678
+REMARK 3 S21: 0.1082 S22: 0.0201 S23: 0.1702
+REMARK 3 S31: 0.1983 S32: -0.3971 S33: 0.1251
+REMARK 3
+REMARK 3 TLS GROUP : 2
+REMARK 3 NUMBER OF COMPONENTS GROUP : 1
+REMARK 3 COMPONENTS C SSSEQI TO C SSSEQI
+REMARK 3 RESIDUE RANGE : B 2 B 122
+REMARK 3 ORIGIN FOR THE GROUP (A): -27.4515 -16.6414 -12.3927
+REMARK 3 T TENSOR
+REMARK 3 T11: 0.0153 T22: 0.0305
+REMARK 3 T33: 0.0110 T12: 0.0014
+REMARK 3 T13: 0.0124 T23: -0.0038
+REMARK 3 L TENSOR
+REMARK 3 L11: 2.2921 L22: 2.7795
+REMARK 3 L33: 6.4597 L12: 0.0122
+REMARK 3 L13: 0.2226 L23: -0.5396
+REMARK 3 S TENSOR
+REMARK 3 S11: 0.0678 S12: -0.2191 S13: 0.0982
+REMARK 3 S21: 0.1361 S22: 0.0490 S23: 0.0984
+REMARK 3 S31: -0.1717 S32: -0.0459 S33: -0.1168
+REMARK 3
+REMARK 3 BULK SOLVENT MODELLING.
+REMARK 3 METHOD USED : MASK
+REMARK 3 PARAMETERS FOR MASK CALCULATION
+REMARK 3 VDW PROBE RADIUS : 1.20
+REMARK 3 ION PROBE RADIUS : 0.80
+REMARK 3 SHRINKAGE RADIUS : 0.80
+REMARK 3
+REMARK 3 OTHER REFINEMENT REMARKS: HYDROGENS HAVE BEEN ADDED IN THE RIDING
+REMARK 3 POSITIONS
+REMARK 4
+REMARK 4 4ZHO COMPLIES WITH FORMAT V. 3.30, 13-JUL-11
+REMARK 100
+REMARK 100 THIS ENTRY HAS BEEN PROCESSED BY PDBE ON 27-APR-15.
+REMARK 100 THE DEPOSITION ID IS D_1000209256.
+REMARK 200
+REMARK 200 EXPERIMENTAL DETAILS
+REMARK 200 EXPERIMENT TYPE : X-RAY DIFFRACTION
+REMARK 200 DATE OF DATA COLLECTION : 21-JUL-14
+REMARK 200 TEMPERATURE (KELVIN) : 100
+REMARK 200 PH : 8.5
+REMARK 200 NUMBER OF CRYSTALS USED : NULL
+REMARK 200
+REMARK 200 SYNCHROTRON (Y/N) : Y
+REMARK 200 RADIATION SOURCE : DIAMOND
+REMARK 200 BEAMLINE : I02
+REMARK 200 X-RAY GENERATOR MODEL : NULL
+REMARK 200 MONOCHROMATIC OR LAUE (M/L) : M
+REMARK 200 WAVELENGTH OR RANGE (A) : 1.74
+REMARK 200 MONOCHROMATOR : SILICON CRYSTAL
+REMARK 200 OPTICS : NULL
+REMARK 200
+REMARK 200 DETECTOR TYPE : PIXEL
+REMARK 200 DETECTOR MANUFACTURER : PSI PILATUS 6M
+REMARK 200 INTENSITY-INTEGRATION SOFTWARE : XDS
+REMARK 200 DATA SCALING SOFTWARE : AIMLESS
+REMARK 200
+REMARK 200 NUMBER OF UNIQUE REFLECTIONS : 12894
+REMARK 200 RESOLUTION RANGE HIGH (A) : 2.340
+REMARK 200 RESOLUTION RANGE LOW (A) : 60.730
+REMARK 200 REJECTION CRITERIA (SIGMA(I)) : NULL
+REMARK 200
+REMARK 200 OVERALL.
+REMARK 200 COMPLETENESS FOR RANGE (%) : 99.4
+REMARK 200 DATA REDUNDANCY : 12.30
+REMARK 200 R MERGE (I) : 0.06600
+REMARK 200 R SYM (I) : NULL
+REMARK 200 <I/SIGMA(I)> FOR THE DATA SET : 23.2000
+REMARK 200
+REMARK 200 IN THE HIGHEST RESOLUTION SHELL.
+REMARK 200 HIGHEST RESOLUTION SHELL, RANGE HIGH (A) : 2.34
+REMARK 200 HIGHEST RESOLUTION SHELL, RANGE LOW (A) : 2.40
+REMARK 200 COMPLETENESS FOR SHELL (%) : 98.4
+REMARK 200 DATA REDUNDANCY IN SHELL : 11.80
+REMARK 200 R MERGE FOR SHELL (I) : 0.59800
+REMARK 200 R SYM FOR SHELL (I) : NULL
+REMARK 200 <I/SIGMA(I)> FOR SHELL : 4.200
+REMARK 200
+REMARK 200 DIFFRACTION PROTOCOL: SINGLE WAVELENGTH
+REMARK 200 METHOD USED TO DETERMINE THE STRUCTURE: NULL
+REMARK 200 SOFTWARE USED: PHASER
+REMARK 200 STARTING MODEL: NULL
+REMARK 200
+REMARK 200 REMARK: THIN PLATES, DEEP RED BROWN COLOUR DUE TO 2FE-2S IRON
+REMARK 200 SULPHUR CLUSTER
+REMARK 280
+REMARK 280 CRYSTAL
+REMARK 280 SOLVENT CONTENT, VS (%): 64.33
+REMARK 280 MATTHEWS COEFFICIENT, VM (ANGSTROMS**3/DA): 3.45
+REMARK 280
+REMARK 280 CRYSTALLIZATION CONDITIONS: 0.2 M MGCL2, 0.1 M TRIS, 20 % PEG
+REMARK 280 8000, PH 8.5, VAPOR DIFFUSION, SITTING DROP, TEMPERATURE 294K
+REMARK 290
+REMARK 290 CRYSTALLOGRAPHIC SYMMETRY
+REMARK 290 SYMMETRY OPERATORS FOR SPACE GROUP: P 42 21 2
+REMARK 290
+REMARK 290 SYMOP SYMMETRY
+REMARK 290 NNNMMM OPERATOR
+REMARK 290 1555 X,Y,Z
+REMARK 290 2555 -X,-Y,Z
+REMARK 290 3555 -Y+1/2,X+1/2,Z+1/2
+REMARK 290 4555 Y+1/2,-X+1/2,Z+1/2
+REMARK 290 5555 -X+1/2,Y+1/2,-Z+1/2
+REMARK 290 6555 X+1/2,-Y+1/2,-Z+1/2
+REMARK 290 7555 Y,X,-Z
+REMARK 290 8555 -Y,-X,-Z
+REMARK 290
+REMARK 290 WHERE NNN -> OPERATOR NUMBER
+REMARK 290 MMM -> TRANSLATION VECTOR
+REMARK 290
+REMARK 290 CRYSTALLOGRAPHIC SYMMETRY TRANSFORMATIONS
+REMARK 290 THE FOLLOWING TRANSFORMATIONS OPERATE ON THE ATOM/HETATM
+REMARK 290 RECORDS IN THIS ENTRY TO PRODUCE CRYSTALLOGRAPHICALLY
+REMARK 290 RELATED MOLECULES.
+REMARK 290 SMTRY1 1 1.000000 0.000000 0.000000 0.00000
+REMARK 290 SMTRY2 1 0.000000 1.000000 0.000000 0.00000
+REMARK 290 SMTRY3 1 0.000000 0.000000 1.000000 0.00000
+REMARK 290 SMTRY1 2 -1.000000 0.000000 0.000000 0.00000
+REMARK 290 SMTRY2 2 0.000000 -1.000000 0.000000 0.00000
+REMARK 290 SMTRY3 2 0.000000 0.000000 1.000000 0.00000
+REMARK 290 SMTRY1 3 0.000000 -1.000000 0.000000 30.36500
+REMARK 290 SMTRY2 3 1.000000 0.000000 0.000000 30.36500
+REMARK 290 SMTRY3 3 0.000000 0.000000 1.000000 77.36500
+REMARK 290 SMTRY1 4 0.000000 1.000000 0.000000 30.36500
+REMARK 290 SMTRY2 4 -1.000000 0.000000 0.000000 30.36500
+REMARK 290 SMTRY3 4 0.000000 0.000000 1.000000 77.36500
+REMARK 290 SMTRY1 5 -1.000000 0.000000 0.000000 30.36500
+REMARK 290 SMTRY2 5 0.000000 1.000000 0.000000 30.36500
+REMARK 290 SMTRY3 5 0.000000 0.000000 -1.000000 77.36500
+REMARK 290 SMTRY1 6 1.000000 0.000000 0.000000 30.36500
+REMARK 290 SMTRY2 6 0.000000 -1.000000 0.000000 30.36500
+REMARK 290 SMTRY3 6 0.000000 0.000000 -1.000000 77.36500
+REMARK 290 SMTRY1 7 0.000000 1.000000 0.000000 0.00000
+REMARK 290 SMTRY2 7 1.000000 0.000000 0.000000 0.00000
+REMARK 290 SMTRY3 7 0.000000 0.000000 -1.000000 0.00000
+REMARK 290 SMTRY1 8 0.000000 -1.000000 0.000000 0.00000
+REMARK 290 SMTRY2 8 -1.000000 0.000000 0.000000 0.00000
+REMARK 290 SMTRY3 8 0.000000 0.000000 -1.000000 0.00000
+REMARK 290
+REMARK 290 REMARK: NULL
+REMARK 300
+REMARK 300 BIOMOLECULE: 1, 2
+REMARK 300 SEE REMARK 350 FOR THE AUTHOR PROVIDED AND/OR PROGRAM
+REMARK 300 GENERATED ASSEMBLY INFORMATION FOR THE STRUCTURE IN
+REMARK 300 THIS ENTRY. THE REMARK MAY ALSO PROVIDE INFORMATION ON
+REMARK 300 BURIED SURFACE AREA.
+REMARK 350
+REMARK 350 COORDINATES FOR A COMPLETE MULTIMER REPRESENTING THE KNOWN
+REMARK 350 BIOLOGICALLY SIGNIFICANT OLIGOMERIZATION STATE OF THE
+REMARK 350 MOLECULE CAN BE GENERATED BY APPLYING BIOMT TRANSFORMATIONS
+REMARK 350 GIVEN BELOW. BOTH NON-CRYSTALLOGRAPHIC AND
+REMARK 350 CRYSTALLOGRAPHIC OPERATIONS ARE GIVEN.
+REMARK 350
+REMARK 350 BIOMOLECULE: 1
+REMARK 350 AUTHOR DETERMINED BIOLOGICAL UNIT: MONOMERIC
+REMARK 350 APPLY THE FOLLOWING TO CHAINS: A
+REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.00000
+REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.00000
+REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.00000
+REMARK 350
+REMARK 350 BIOMOLECULE: 2
+REMARK 350 AUTHOR DETERMINED BIOLOGICAL UNIT: MONOMERIC
+REMARK 350 APPLY THE FOLLOWING TO CHAINS: B
+REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.00000
+REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.00000
+REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.00000
+REMARK 375
+REMARK 375 SPECIAL POSITION
+REMARK 375 THE FOLLOWING ATOMS ARE FOUND TO BE WITHIN 0.15 ANGSTROMS
+REMARK 375 OF A SYMMETRY RELATED ATOM AND ARE ASSUMED TO BE ON SPECIAL
+REMARK 375 POSITIONS.
+REMARK 375
+REMARK 375 ATOM RES CSSEQI
+REMARK 375 HOH B 319 LIES ON A SPECIAL POSITION.
+REMARK 465
+REMARK 465 MISSING RESIDUES
+REMARK 465 THE FOLLOWING RESIDUES WERE NOT LOCATED IN THE
+REMARK 465 EXPERIMENT. (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN
+REMARK 465 IDENTIFIER; SSSEQ=SEQUENCE NUMBER; I=INSERTION CODE.)
+REMARK 465
+REMARK 465 M RES C SSSEQI
+REMARK 465 MET A 1
+REMARK 465 GLU A 99
+REMARK 465 HIS A 100
+REMARK 465 HIS A 101
+REMARK 465 HIS A 102
+REMARK 465 HIS A 103
+REMARK 465 HIS A 104
+REMARK 465 HIS A 105
+REMARK 465 MET B 1
+REMARK 465 GLU B 99
+REMARK 465 HIS B 100
+REMARK 465 HIS B 101
+REMARK 465 HIS B 102
+REMARK 465 HIS B 103
+REMARK 465 HIS B 104
+REMARK 465 HIS B 105
+REMARK 470
+REMARK 470 MISSING ATOM
+REMARK 470 THE FOLLOWING RESIDUES HAVE MISSING ATOMS (M=MODEL NUMBER;
+REMARK 470 RES=RESIDUE NAME; C=CHAIN IDENTIFIER; SSEQ=SEQUENCE NUMBER;
+REMARK 470 I=INSERTION CODE):
+REMARK 470 M RES CSSEQI ATOMS
+REMARK 470 LEU A 98 CG CD1 CD2
+REMARK 470 LEU B 98 CG CD1 CD2
+REMARK 500
+REMARK 500 GEOMETRY AND STEREOCHEMISTRY
+REMARK 500 SUBTOPIC: TORSION ANGLES
+REMARK 500
+REMARK 500 TORSION ANGLES OUTSIDE THE EXPECTED RAMACHANDRAN REGIONS:
+REMARK 500 (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN IDENTIFIER;
+REMARK 500 SSEQ=SEQUENCE NUMBER; I=INSERTION CODE).
+REMARK 500
+REMARK 500 STANDARD TABLE:
+REMARK 500 FORMAT:(10X,I3,1X,A3,1X,A1,I4,A1,4X,F7.2,3X,F7.2)
+REMARK 500
+REMARK 500 EXPECTED VALUES: GJ KLEYWEGT AND TA JONES (1996). PHI/PSI-
+REMARK 500 CHOLOGY: RAMACHANDRAN REVISITED. STRUCTURE 4, 1395 - 1400
+REMARK 500
+REMARK 500 M RES CSSEQI PSI PHI
+REMARK 500 SER A 39 -64.23 -146.55
+REMARK 500 MET A 97 -67.17 -99.01
+REMARK 500 SER B 39 -78.49 -140.11
+REMARK 500 SER B 63 -12.80 -148.10
+REMARK 500
+REMARK 500 REMARK: NULL
+REMARK 620
+REMARK 620 METAL COORDINATION
+REMARK 620 (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN IDENTIFIER;
+REMARK 620 SSEQ=SEQUENCE NUMBER; I=INSERTION CODE):
+REMARK 620
+REMARK 620 COORDINATION ANGLES FOR: M RES CSSEQI METAL
+REMARK 620 FES A 201 FE1
+REMARK 620 N RES CSSEQI ATOM
+REMARK 620 1 CYS A 40 SG
+REMARK 620 2 FES A 201 S1 124.8
+REMARK 620 3 FES A 201 S2 100.1 99.4
+REMARK 620 4 CYS A 45 SG 105.3 110.0 117.8
+REMARK 620 N 1 2 3
+REMARK 620
+REMARK 620 COORDINATION ANGLES FOR: M RES CSSEQI METAL
+REMARK 620 FES A 201 FE2
+REMARK 620 N RES CSSEQI ATOM
+REMARK 620 1 CYS A 48 SG
+REMARK 620 2 FES A 201 S1 114.4
+REMARK 620 3 FES A 201 S2 108.9 101.7
+REMARK 620 4 CYS A 78 SG 105.9 122.0 102.7
+REMARK 620 N 1 2 3
+REMARK 620
+REMARK 620 COORDINATION ANGLES FOR: M RES CSSEQI METAL
+REMARK 620 FES B 201 FE1
+REMARK 620 N RES CSSEQI ATOM
+REMARK 620 1 CYS B 40 SG
+REMARK 620 2 FES B 201 S1 119.9
+REMARK 620 3 FES B 201 S2 102.0 97.8
+REMARK 620 4 CYS B 45 SG 109.5 108.1 119.7
+REMARK 620 N 1 2 3
+REMARK 620
+REMARK 620 COORDINATION ANGLES FOR: M RES CSSEQI METAL
+REMARK 620 FES B 201 FE2
+REMARK 620 N RES CSSEQI ATOM
+REMARK 620 1 CYS B 48 SG
+REMARK 620 2 FES B 201 S1 111.1
+REMARK 620 3 FES B 201 S2 115.5 99.1
+REMARK 620 4 CYS B 78 SG 110.9 117.2 102.5
+REMARK 620 N 1 2 3
+REMARK 800
+REMARK 800 SITE
+REMARK 800 SITE_IDENTIFIER: AC1
+REMARK 800 EVIDENCE_CODE: SOFTWARE
+REMARK 800 SITE_DESCRIPTION: binding site for residue FES A 201
+REMARK 800
+REMARK 800 SITE_IDENTIFIER: AC2
+REMARK 800 EVIDENCE_CODE: SOFTWARE
+REMARK 800 SITE_DESCRIPTION: binding site for residue CL A 202
+REMARK 800
+REMARK 800 SITE_IDENTIFIER: AC3
+REMARK 800 EVIDENCE_CODE: SOFTWARE
+REMARK 800 SITE_DESCRIPTION: binding site for residue FES B 201
+REMARK 800
+REMARK 800 SITE_IDENTIFIER: AC4
+REMARK 800 EVIDENCE_CODE: SOFTWARE
+REMARK 800 SITE_DESCRIPTION: binding site for residue CL B 202
+DBREF 4ZHO A 1 94 UNP P16972 FER2_ARATH 52 145
+DBREF 4ZHO B 1 94 UNP P16972 FER2_ARATH 52 145
+SEQADV 4ZHO ALA A 95 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO ILE A 96 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO MET A 97 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO LEU A 98 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO GLU A 99 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS A 100 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS A 101 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS A 102 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS A 103 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS A 104 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS A 105 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO ALA B 95 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO ILE B 96 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO MET B 97 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO LEU B 98 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO GLU B 99 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS B 100 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS B 101 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS B 102 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS B 103 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS B 104 UNP P16972 EXPRESSION TAG
+SEQADV 4ZHO HIS B 105 UNP P16972 EXPRESSION TAG
+SEQRES 1 A 105 MET ALA THR TYR LYS VAL LYS PHE ILE THR PRO GLU GLY
+SEQRES 2 A 105 GLU LEU GLU VAL GLU CYS ASP ASP ASP VAL TYR VAL LEU
+SEQRES 3 A 105 ASP ALA ALA GLU GLU ALA GLY ILE ASP LEU PRO TYR SER
+SEQRES 4 A 105 CYS ARG ALA GLY SER CYS SER SER CYS ALA GLY LYS VAL
+SEQRES 5 A 105 VAL SER GLY SER VAL ASP GLN SER ASP GLN SER PHE LEU
+SEQRES 6 A 105 ASP ASP GLU GLN ILE GLY GLU GLY PHE VAL LEU THR CYS
+SEQRES 7 A 105 ALA ALA TYR PRO THR SER ASP VAL THR ILE GLU THR HIS
+SEQRES 8 A 105 LYS GLU GLU ALA ILE MET LEU GLU HIS HIS HIS HIS HIS
+SEQRES 9 A 105 HIS
+SEQRES 1 B 105 MET ALA THR TYR LYS VAL LYS PHE ILE THR PRO GLU GLY
+SEQRES 2 B 105 GLU LEU GLU VAL GLU CYS ASP ASP ASP VAL TYR VAL LEU
+SEQRES 3 B 105 ASP ALA ALA GLU GLU ALA GLY ILE ASP LEU PRO TYR SER
+SEQRES 4 B 105 CYS ARG ALA GLY SER CYS SER SER CYS ALA GLY LYS VAL
+SEQRES 5 B 105 VAL SER GLY SER VAL ASP GLN SER ASP GLN SER PHE LEU
+SEQRES 6 B 105 ASP ASP GLU GLN ILE GLY GLU GLY PHE VAL LEU THR CYS
+SEQRES 7 B 105 ALA ALA TYR PRO THR SER ASP VAL THR ILE GLU THR HIS
+SEQRES 8 B 105 LYS GLU GLU ALA ILE MET LEU GLU HIS HIS HIS HIS HIS
+SEQRES 9 B 105 HIS
+HET FES A 201 4
+HET CL A 202 1
+HET FES B 201 4
+HET CL B 202 1
+HETNAM FES FE2/S2 (INORGANIC) CLUSTER
+HETNAM CL CHLORIDE ION
+FORMUL 3 FES 2(FE2 S2)
+FORMUL 4 CL 2(CL 1-)
+FORMUL 7 HOH *38(H2 O)
+HELIX 1 AA1 TYR A 24 ALA A 32 1 9
+HELIX 2 AA2 ASP A 66 GLU A 72 1 7
+HELIX 3 AA3 CYS A 78 ALA A 80 5 3
+HELIX 4 AA5 TYR B 24 ALA B 32 1 9
+HELIX 5 AA6 ASP B 66 GLU B 72 1 7
+HELIX 6 AA7 CYS B 78 ALA B 80 5 3
+HELIX 7 AA8 LYS B 92 MET B 97 5 6
+SHEET 1 AA1 5 GLU A 14 ASP A 20 0
+SHEET 2 AA1 5 THR A 3 ILE A 9 -1 N PHE A 8 O LEU A 15
+SHEET 3 AA1 5 VAL A 86 GLU A 89 1 O ILE A 88 N LYS A 7
+SHEET 4 AA1 5 ALA A 49 SER A 54 -1 N SER A 54 O THR A 87
+SHEET 5 AA1 5 PHE A 74 LEU A 76 -1 O VAL A 75 N GLY A 50
+SHEET 1 AA2 2 VAL A 57 ASP A 58 0
+SHEET 2 AA2 2 TYR A 81 PRO A 82 -1 O TYR A 81 N ASP A 58
+SHEET 1 AA3 5 GLY B 13 ASP B 20 0
+SHEET 2 AA3 5 THR B 3 THR B 10 -1 N PHE B 8 O LEU B 15
+SHEET 3 AA3 5 VAL B 86 GLU B 89 1 O ILE B 88 N LYS B 7
+SHEET 4 AA3 5 ALA B 49 SER B 54 -1 N LYS B 51 O GLU B 89
+SHEET 5 AA3 5 PHE B 74 LEU B 76 -1 O VAL B 75 N GLY B 50
+SHEET 1 AA4 2 VAL B 57 ASP B 58 0
+SHEET 2 AA4 2 TYR B 81 PRO B 82 -1 O TYR B 81 N ASP B 58
+LINK SG CYS A 40 FE1 FES A 201 1555 1555 2.33
+LINK SG CYS A 45 FE1 FES A 201 1555 1555 2.28
+LINK SG CYS A 48 FE2 FES A 201 1555 1555 2.28
+LINK SG CYS A 78 FE2 FES A 201 1555 1555 2.34
+LINK SG CYS B 40 FE1 FES B 201 1555 1555 2.22
+LINK SG CYS B 45 FE1 FES B 201 1555 1555 2.25
+LINK SG CYS B 48 FE2 FES B 201 1555 1555 2.18
+LINK SG CYS B 78 FE2 FES B 201 1555 1555 2.36
+SITE 1 AC1 8 SER A 39 CYS A 40 ARG A 41 GLY A 43
+SITE 2 AC1 8 SER A 44 CYS A 45 CYS A 48 CYS A 78
+SITE 1 AC2 2 SER A 84 ASP A 85
+SITE 1 AC3 8 SER B 39 CYS B 40 ARG B 41 GLY B 43
+SITE 2 AC3 8 SER B 44 CYS B 45 CYS B 48 CYS B 78
+SITE 1 AC4 2 SER B 84 ASP B 85
+CRYST1 60.730 60.730 154.730 90.00 90.00 90.00 P 42 21 2 16
+ORIGX1 1.000000 0.000000 0.000000 0.00000
+ORIGX2 0.000000 1.000000 0.000000 0.00000
+ORIGX3 0.000000 0.000000 1.000000 0.00000
+SCALE1 0.016466 0.000000 0.000000 0.00000
+SCALE2 0.000000 0.016466 0.000000 0.00000
+SCALE3 0.000000 0.000000 0.006463 0.00000
+ATOM 1 N ALA A 2 -1.257 -15.807 -48.124 1.00 50.77 N
+ANISOU 1 N ALA A 2 7787 5804 5698 -219 1819 -481 N
+ATOM 2 CA ALA A 2 -1.523 -14.339 -48.197 1.00 50.70 C
+ANISOU 2 CA ALA A 2 7568 6034 5660 -183 1548 -344 C
+ATOM 3 C ALA A 2 -1.438 -13.722 -46.830 1.00 45.70 C
+ANISOU 3 C ALA A 2 6785 5347 5230 -97 1396 -189 C
+ATOM 4 O ALA A 2 -1.809 -14.345 -45.825 1.00 44.98 O
+ANISOU 4 O ALA A 2 6732 5134 5221 -136 1414 -240 O
+ATOM 5 CB ALA A 2 -2.903 -14.040 -48.848 1.00 48.96 C
+ANISOU 5 CB ALA A 2 7316 6077 5207 -370 1390 -508 C
+ATOM 6 N THR A 3 -1.069 -12.455 -46.833 1.00 45.54 N
+ANISOU 6 N THR A 3 6600 5431 5271 -1 1249 -16 N
+ATOM 7 CA THR A 3 -0.949 -11.641 -45.631 1.00 47.35 C
+ANISOU 7 CA THR A 3 6681 5636 5674 60 1092 109 C
+ATOM 8 C THR A 3 -1.689 -10.384 -45.941 1.00 43.11 C
+ANISOU 8 C THR A 3 6022 5274 5083 31 915 145 C
+ATOM 9 O THR A 3 -1.531 -9.803 -47.012 1.00 41.92 O
+ANISOU 9 O THR A 3 5843 5236 4848 63 924 210 O
+ATOM 10 CB THR A 3 0.543 -11.321 -45.328 1.00 50.05 C
+ANISOU 10 CB THR A 3 6935 5888 6195 216 1141 301 C
+ATOM 11 OG1 THR A 3 1.229 -12.551 -45.036 1.00 50.95 O
+ANISOU 11 OG1 THR A 3 7151 5846 6362 283 1328 306 O
+ATOM 12 CG2 THR A 3 0.673 -10.438 -44.115 1.00 54.46 C
+ANISOU 12 CG2 THR A 3 7341 6448 6902 242 968 390 C
+ATOM 13 N TYR A 4 -2.484 -9.944 -44.989 1.00 46.99 N
+ANISOU 13 N TYR A 4 6443 5784 5625 -9 776 123 N
+ATOM 14 CA TYR A 4 -3.347 -8.768 -45.177 1.00 48.43 C
+ANISOU 14 CA TYR A 4 6510 6116 5775 -19 632 167 C
+ATOM 15 C TYR A 4 -3.023 -7.694 -44.144 1.00 47.22 C
+ANISOU 15 C TYR A 4 6246 5881 5813 46 540 272 C
+ATOM 16 O TYR A 4 -2.521 -7.988 -43.069 1.00 48.33 O
+ANISOU 16 O TYR A 4 6396 5904 6063 58 537 263 O
+ATOM 17 CB TYR A 4 -4.801 -9.196 -45.059 1.00 47.01 C
+ANISOU 17 CB TYR A 4 6341 6049 5468 -146 570 20 C
+ATOM 18 CG TYR A 4 -5.208 -10.134 -46.157 1.00 43.84 C
+ANISOU 18 CG TYR A 4 6035 5763 4857 -258 645 -122 C
+ATOM 19 CD1 TYR A 4 -5.280 -9.700 -47.461 1.00 48.21 C
+ANISOU 19 CD1 TYR A 4 6559 6515 5243 -243 630 -80 C
+ATOM 20 CD2 TYR A 4 -5.473 -11.470 -45.898 1.00 48.38 C
+ANISOU 20 CD2 TYR A 4 6743 6241 5397 -383 752 -303 C
+ATOM 21 CE1 TYR A 4 -5.629 -10.561 -48.480 1.00 48.93 C
+ANISOU 21 CE1 TYR A 4 6746 6739 5104 -368 694 -244 C
+ATOM 22 CE2 TYR A 4 -5.802 -12.362 -46.923 1.00 48.52 C
+ANISOU 22 CE2 TYR A 4 6868 6342 5221 -522 844 -480 C
+ATOM 23 CZ TYR A 4 -5.914 -11.892 -48.199 1.00 48.26 C
+ANISOU 23 CZ TYR A 4 6798 6543 4992 -526 799 -466 C
+ATOM 24 OH TYR A 4 -6.226 -12.778 -49.220 1.00 52.35 O
+ANISOU 24 OH TYR A 4 7434 7172 5284 -686 885 -675 O
+ATOM 25 N LYS A 5 -3.307 -6.453 -44.489 1.00 47.90 N
+ANISOU 25 N LYS A 5 6234 6036 5930 90 478 373 N
+ATOM 26 CA LYS A 5 -3.126 -5.320 -43.582 1.00 49.46 C
+ANISOU 26 CA LYS A 5 6343 6138 6309 126 414 439 C
+ATOM 27 C LYS A 5 -4.415 -5.114 -42.819 1.00 44.72 C
+ANISOU 27 C LYS A 5 5725 5576 5688 87 334 362 C
+ATOM 28 O LYS A 5 -5.464 -4.904 -43.423 1.00 45.76 O
+ANISOU 28 O LYS A 5 5820 5852 5714 87 308 374 O
+ATOM 29 CB LYS A 5 -2.776 -4.038 -44.357 1.00 51.93 C
+ANISOU 29 CB LYS A 5 6573 6454 6702 205 443 602 C
+ATOM 30 CG LYS A 5 -1.497 -4.126 -45.113 1.00 62.94 C
+ANISOU 30 CG LYS A 5 7967 7811 8137 249 542 698 C
+ATOM 31 CD LYS A 5 -0.351 -4.665 -44.240 1.00 71.74 C
+ANISOU 31 CD LYS A 5 9078 8803 9377 228 553 662 C
+ATOM 32 CE LYS A 5 -0.083 -3.798 -43.025 1.00 78.38 C
+ANISOU 32 CE LYS A 5 9836 9541 10403 192 473 648 C
+ATOM 33 NZ LYS A 5 0.491 -2.513 -43.496 1.00 87.36 N
+ANISOU 33 NZ LYS A 5 10881 10609 11701 215 524 774 N
+ATOM 34 N VAL A 6 -4.356 -5.236 -41.505 1.00 40.33 N
+ANISOU 34 N VAL A 6 5186 4922 5213 58 297 290 N
+ATOM 35 CA VAL A 6 -5.506 -4.978 -40.686 1.00 43.48 C
+ANISOU 35 CA VAL A 6 5572 5340 5608 33 246 224 C
+ATOM 36 C VAL A 6 -5.286 -3.624 -40.015 1.00 44.26 C
+ANISOU 36 C VAL A 6 5616 5334 5865 73 225 265 C
+ATOM 37 O VAL A 6 -4.317 -3.413 -39.286 1.00 45.54 O
+ANISOU 37 O VAL A 6 5782 5395 6125 57 211 245 O
+ATOM 38 CB VAL A 6 -5.704 -6.072 -39.614 1.00 47.03 C
+ANISOU 38 CB VAL A 6 6100 5753 6016 -24 246 110 C
+ATOM 39 CG1 VAL A 6 -6.982 -5.808 -38.849 1.00 45.34 C
+ANISOU 39 CG1 VAL A 6 5866 5571 5789 -46 216 50 C
+ATOM 40 CG2 VAL A 6 -5.764 -7.451 -40.254 1.00 46.02 C
+ANISOU 40 CG2 VAL A 6 6052 5664 5769 -78 315 53 C
+ATOM 41 N LYS A 7 -6.163 -2.682 -40.330 1.00 45.38 N
+ANISOU 41 N LYS A 7 5700 5508 6034 123 235 327 N
+ATOM 42 CA LYS A 7 -6.143 -1.373 -39.740 1.00 45.98 C
+ANISOU 42 CA LYS A 7 5748 5450 6273 160 263 351 C
+ATOM 43 C LYS A 7 -7.143 -1.363 -38.592 1.00 47.81 C
+ANISOU 43 C LYS A 7 6003 5668 6491 143 248 245 C
+ATOM 44 O LYS A 7 -8.347 -1.536 -38.787 1.00 51.78 O
+ANISOU 44 O LYS A 7 6468 6287 6918 173 249 263 O
+ATOM 45 CB LYS A 7 -6.506 -0.347 -40.788 1.00 48.29 C
+ANISOU 45 CB LYS A 7 5968 5763 6617 264 329 520 C
+ATOM 46 CG LYS A 7 -6.637 1.070 -40.268 1.00 58.39 C
+ANISOU 46 CG LYS A 7 7234 6859 8090 316 413 556 C
+ATOM 47 CD LYS A 7 -6.631 2.026 -41.447 1.00 68.64 C
+ANISOU 47 CD LYS A 7 8467 8148 9461 441 515 776 C
+ATOM 48 CE LYS A 7 -6.930 3.448 -41.018 1.00 82.52 C
+ANISOU 48 CE LYS A 7 10225 9693 11435 515 651 833 C
+ATOM 49 NZ LYS A 7 -6.213 4.399 -41.926 1.00 90.34 N
+ANISOU 49 NZ LYS A 7 11188 10561 12575 587 785 1022 N
+ATOM 50 N PHE A 8 -6.640 -1.148 -37.392 1.00 43.94 N
+ANISOU 50 N PHE A 8 5567 5061 6068 93 233 136 N
+ATOM 51 CA PHE A 8 -7.513 -1.002 -36.238 1.00 50.30 C
+ANISOU 51 CA PHE A 8 6412 5840 6859 87 244 34 C
+ATOM 52 C PHE A 8 -7.808 0.440 -35.906 1.00 44.05 C
+ANISOU 52 C PHE A 8 5618 4900 6218 131 331 33 C
+ATOM 53 O PHE A 8 -6.905 1.228 -35.663 1.00 48.85 O
+ANISOU 53 O PHE A 8 6245 5366 6948 88 353 -5 O
+ATOM 54 CB PHE A 8 -6.843 -1.646 -35.018 1.00 45.89 C
+ANISOU 54 CB PHE A 8 5927 5267 6239 10 184 -93 C
+ATOM 55 CG PHE A 8 -6.679 -3.122 -35.144 1.00 46.40 C
+ANISOU 55 CG PHE A 8 6019 5437 6174 -10 148 -85 C
+ATOM 56 CD1 PHE A 8 -7.769 -3.967 -35.038 1.00 48.26 C
+ANISOU 56 CD1 PHE A 8 6277 5749 6311 -14 173 -106 C
+ATOM 57 CD2 PHE A 8 -5.438 -3.668 -35.354 1.00 44.91 C
+ANISOU 57 CD2 PHE A 8 5828 5253 5981 -27 113 -54 C
+ATOM 58 CE1 PHE A 8 -7.601 -5.339 -35.131 1.00 47.89 C
+ANISOU 58 CE1 PHE A 8 6276 5748 6170 -46 182 -111 C
+ATOM 59 CE2 PHE A 8 -5.279 -5.027 -35.445 1.00 45.32 C
+ANISOU 59 CE2 PHE A 8 5923 5360 5935 -28 125 -39 C
+ATOM 60 CZ PHE A 8 -6.356 -5.857 -35.342 1.00 47.01 C
+ANISOU 60 CZ PHE A 8 6184 5615 6059 -43 168 -74 C
+ATOM 61 N ILE A 9 -9.069 0.763 -35.795 1.00 45.19 N
+ANISOU 61 N ILE A 9 5739 5067 6363 208 395 63 N
+ATOM 62 CA ILE A 9 -9.459 2.100 -35.309 1.00 51.68 C
+ANISOU 62 CA ILE A 9 6584 5712 7339 270 525 51 C
+ATOM 63 C ILE A 9 -9.826 1.880 -33.879 1.00 50.92 C
+ANISOU 63 C ILE A 9 6580 5587 7179 217 529 -126 C
+ATOM 64 O ILE A 9 -10.824 1.229 -33.599 1.00 53.51 O
+ANISOU 64 O ILE A 9 6889 6036 7407 248 527 -124 O
+ATOM 65 CB ILE A 9 -10.635 2.697 -36.124 1.00 55.53 C
+ANISOU 65 CB ILE A 9 6967 6250 7879 433 624 240 C
+ATOM 66 CG1 ILE A 9 -10.204 2.918 -37.592 1.00 55.29 C
+ANISOU 66 CG1 ILE A 9 6852 6282 7873 497 619 438 C
+ATOM 67 CG2 ILE A 9 -11.137 4.018 -35.502 1.00 55.96 C
+ANISOU 67 CG2 ILE A 9 7065 6086 8109 523 808 232 C
+ATOM 68 CD1 ILE A 9 -11.385 2.981 -38.527 1.00 58.25 C
+ANISOU 68 CD1 ILE A 9 7085 6859 8188 645 639 641 C
+ATOM 69 N THR A 10 -8.967 2.329 -32.980 1.00 50.67 N
+ANISOU 69 N THR A 10 6641 5425 7186 121 526 -284 N
+ATOM 70 CA THR A 10 -9.185 2.107 -31.561 1.00 51.69 C
+ANISOU 70 CA THR A 10 6873 5558 7208 65 520 -464 C
+ATOM 71 C THR A 10 -9.612 3.432 -30.915 1.00 50.65 C
+ANISOU 71 C THR A 10 6822 5218 7204 89 689 -568 C
+ATOM 72 O THR A 10 -9.544 4.466 -31.525 1.00 57.26 O
+ANISOU 72 O THR A 10 7639 5887 8228 134 806 -501 O
+ATOM 73 CB THR A 10 -7.930 1.531 -30.864 1.00 50.80 C
+ANISOU 73 CB THR A 10 6804 5512 6986 -68 378 -588 C
+ATOM 74 OG1 THR A 10 -6.968 2.554 -30.671 1.00 53.43 O
+ANISOU 74 OG1 THR A 10 7157 5704 7440 -168 390 -696 O
+ATOM 75 CG2 THR A 10 -7.278 0.462 -31.693 1.00 50.38 C
+ANISOU 75 CG2 THR A 10 6674 5593 6874 -73 264 -466 C
+ATOM 76 N PRO A 11 -10.106 3.393 -29.679 1.00 56.03 N
+ANISOU 76 N PRO A 11 7607 5897 7785 72 733 -722 N
+ATOM 77 CA PRO A 11 -10.427 4.652 -28.979 1.00 58.93 C
+ANISOU 77 CA PRO A 11 8085 6039 8264 79 922 -863 C
+ATOM 78 C PRO A 11 -9.259 5.590 -28.772 1.00 63.22 C
+ANISOU 78 C PRO A 11 8697 6403 8918 -73 935 -1031 C
+ATOM 79 O PRO A 11 -9.508 6.756 -28.521 1.00 69.60 O
+ANISOU 79 O PRO A 11 9594 6966 9884 -65 1137 -1123 O
+ATOM 80 CB PRO A 11 -10.886 4.178 -27.593 1.00 59.38 C
+ANISOU 80 CB PRO A 11 8256 6185 8120 51 924 -1030 C
+ATOM 81 CG PRO A 11 -11.306 2.750 -27.777 1.00 55.35 C
+ANISOU 81 CG PRO A 11 7663 5915 7451 96 802 -896 C
+ATOM 82 CD PRO A 11 -10.443 2.207 -28.868 1.00 52.67 C
+ANISOU 82 CD PRO A 11 7215 5657 7140 56 649 -769 C
+ATOM 83 N GLU A 12 -8.030 5.041 -28.776 1.00 70.08 N
+ANISOU 83 N GLU A 12 9526 7398 9704 -217 738 -1080 N
+ATOM 84 CA GLU A 12 -6.732 5.771 -28.699 1.00 69.59 C
+ANISOU 84 CA GLU A 12 9470 7225 9747 -402 705 -1227 C
+ATOM 85 C GLU A 12 -6.252 6.249 -30.096 1.00 71.32 C
+ANISOU 85 C GLU A 12 9578 7319 10199 -369 757 -1033 C
+ATOM 86 O GLU A 12 -5.575 7.279 -30.200 1.00 82.47 O
+ANISOU 86 O GLU A 12 11009 8520 11805 -484 854 -1123 O
+ATOM 87 CB GLU A 12 -5.618 4.877 -28.105 1.00 80.51 C
+ANISOU 87 CB GLU A 12 10809 8855 10925 -546 460 -1320 C
+ATOM 88 CG GLU A 12 -5.569 4.624 -26.578 1.00 89.15 C
+ANISOU 88 CG GLU A 12 12010 10093 11769 -643 381 -1555 C
+ATOM 89 CD GLU A 12 -4.271 3.871 -26.137 1.00 96.47 C
+ANISOU 89 CD GLU A 12 12846 11289 12519 -771 133 -1597 C
+ATOM 90 OE1 GLU A 12 -3.440 4.458 -25.401 1.00 86.42 O
+ANISOU 90 OE1 GLU A 12 11584 10049 11202 -968 64 -1827 O
+ATOM 91 OE2 GLU A 12 -4.044 2.692 -26.542 1.00 87.89 O
+ANISOU 91 OE2 GLU A 12 11665 10388 11340 -678 12 -1398 O
+ATOM 92 N GLY A 13 -6.566 5.500 -31.160 1.00 63.49 N
+ANISOU 92 N GLY A 13 8479 6460 9184 -227 703 -780 N
+ATOM 93 CA GLY A 13 -6.219 5.913 -32.504 1.00 59.26 C
+ANISOU 93 CA GLY A 13 7850 5841 8826 -167 764 -575 C
+ATOM 94 C GLY A 13 -6.111 4.770 -33.479 1.00 56.21 C
+ANISOU 94 C GLY A 13 7353 5681 8322 -92 628 -378 C
+ATOM 95 O GLY A 13 -6.534 3.652 -33.197 1.00 53.58 O
+ANISOU 95 O GLY A 13 7018 5544 7795 -65 517 -379 O
+ATOM 96 N GLU A 14 -5.519 5.057 -34.631 1.00 54.33 N
+ANISOU 96 N GLU A 14 7036 5399 8206 -65 661 -215 N
+ATOM 97 CA GLU A 14 -5.492 4.115 -35.751 1.00 60.06 C
+ANISOU 97 CA GLU A 14 7674 6319 8826 19 577 -23 C
+ATOM 98 C GLU A 14 -4.126 3.540 -35.940 1.00 51.22 C
+ANISOU 98 C GLU A 14 6504 5271 7684 -88 464 -38 C
+ATOM 99 O GLU A 14 -3.198 4.277 -36.050 1.00 52.79 O
+ANISOU 99 O GLU A 14 6674 5338 8045 -172 512 -55 O
+ATOM 100 CB GLU A 14 -5.953 4.814 -37.053 1.00 67.15 C
+ANISOU 100 CB GLU A 14 8513 7162 9837 174 715 218 C
+ATOM 101 CG GLU A 14 -7.367 5.360 -36.842 1.00 82.24 C
+ANISOU 101 CG GLU A 14 10442 9031 11772 314 834 268 C
+ATOM 102 CD GLU A 14 -7.938 6.250 -37.944 1.00 92.51 C
+ANISOU 102 CD GLU A 14 11677 10275 13196 506 998 534 C
+ATOM 103 OE1 GLU A 14 -7.274 6.424 -38.992 1.00104.38 O
+ANISOU 103 OE1 GLU A 14 13129 11783 14748 536 1022 696 O
+ATOM 104 OE2 GLU A 14 -9.080 6.772 -37.742 1.00 86.19 O
+ANISOU 104 OE2 GLU A 14 10870 9437 12438 645 1116 601 O
+ATOM 105 N LEU A 15 -4.066 2.220 -36.076 1.00 51.18 N
+ANISOU 105 N LEU A 15 6481 5467 7497 -72 343 -11 N
+ATOM 106 CA LEU A 15 -2.856 1.402 -36.095 1.00 54.47 C
+ANISOU 106 CA LEU A 15 6850 5982 7861 -141 239 -15 C
+ATOM 107 C LEU A 15 -3.099 0.276 -37.078 1.00 53.30 C
+ANISOU 107 C LEU A 15 6690 5980 7581 -52 221 115 C
+ATOM 108 O LEU A 15 -4.183 -0.290 -37.098 1.00 48.80 O
+ANISOU 108 O LEU A 15 6160 5493 6889 1 217 115 O
+ATOM 109 CB LEU A 15 -2.708 0.632 -34.773 1.00 53.82 C
+ANISOU 109 CB LEU A 15 6808 6004 7634 -208 122 -164 C
+ATOM 110 CG LEU A 15 -2.570 1.415 -33.509 1.00 64.22 C
+ANISOU 110 CG LEU A 15 8165 7251 8981 -319 102 -355 C
+ATOM 111 CD1 LEU A 15 -2.755 0.471 -32.348 1.00 68.91 C
+ANISOU 111 CD1 LEU A 15 8813 8000 9367 -328 0 -448 C
+ATOM 112 CD2 LEU A 15 -1.203 2.057 -33.474 1.00 66.88 C
+ANISOU 112 CD2 LEU A 15 8412 7542 9455 -454 71 -403 C
+ATOM 113 N GLU A 16 -2.062 -0.144 -37.776 1.00 49.83 N
+ANISOU 113 N GLU A 16 6195 5579 7157 -55 214 200 N
+ATOM 114 CA GLU A 16 -2.191 -1.180 -38.784 1.00 52.00 C
+ANISOU 114 CA GLU A 16 6480 5971 7306 14 227 299 C
+ATOM 115 C GLU A 16 -1.165 -2.260 -38.528 1.00 44.99 C
+ANISOU 115 C GLU A 16 5581 5146 6365 -5 183 291 C
+ATOM 116 O GLU A 16 -0.027 -1.953 -38.247 1.00 41.15 O
+ANISOU 116 O GLU A 16 5017 4632 5983 -49 162 300 O
+ATOM 117 CB GLU A 16 -1.924 -0.519 -40.111 1.00 56.47 C
+ANISOU 117 CB GLU A 16 6996 6506 7952 73 320 454 C
+ATOM 118 CG GLU A 16 -2.598 -1.111 -41.299 1.00 64.79 C
+ANISOU 118 CG GLU A 16 8072 7693 8851 152 352 546 C
+ATOM 119 CD GLU A 16 -2.299 -0.276 -42.542 1.00 77.28 C
+ANISOU 119 CD GLU A 16 9604 9258 10500 229 453 725 C
+ATOM 120 OE1 GLU A 16 -1.932 -0.864 -43.609 1.00 78.06 O
+ANISOU 120 OE1 GLU A 16 9708 9456 10491 269 492 807 O
+ATOM 121 OE2 GLU A 16 -2.392 0.977 -42.427 1.00 67.17 O
+ANISOU 121 OE2 GLU A 16 8290 7846 9385 251 517 784 O
+ATOM 122 N VAL A 17 -1.538 -3.520 -38.672 1.00 44.95 N
+ANISOU 122 N VAL A 17 5642 5223 6212 27 187 284 N
+ATOM 123 CA VAL A 17 -0.578 -4.609 -38.466 1.00 43.94 C
+ANISOU 123 CA VAL A 17 5513 5132 6048 46 189 310 C
+ATOM 124 C VAL A 17 -0.754 -5.509 -39.643 1.00 44.55 C
+ANISOU 124 C VAL A 17 5652 5239 6033 92 285 360 C
+ATOM 125 O VAL A 17 -1.732 -5.387 -40.374 1.00 43.66 O
+ANISOU 125 O VAL A 17 5577 5162 5847 87 308 346 O
+ATOM 126 CB VAL A 17 -0.860 -5.372 -37.157 1.00 48.00 C
+ANISOU 126 CB VAL A 17 6081 5682 6472 37 134 232 C
+ATOM 127 CG1 VAL A 17 -0.799 -4.395 -35.985 1.00 48.79 C
+ANISOU 127 CG1 VAL A 17 6138 5776 6622 -25 37 146 C
+ATOM 128 CG2 VAL A 17 -2.229 -6.014 -37.217 1.00 46.07 C
+ANISOU 128 CG2 VAL A 17 5942 5449 6111 34 172 170 C
+ATOM 129 N GLU A 18 0.203 -6.379 -39.858 1.00 39.17 N
+ANISOU 129 N GLU A 18 4974 4558 5351 139 347 420 N
+ATOM 130 CA GLU A 18 0.027 -7.446 -40.834 1.00 45.65 C
+ANISOU 130 CA GLU A 18 5895 5385 6065 169 468 423 C
+ATOM 131 C GLU A 18 -0.549 -8.660 -40.120 1.00 42.91 C
+ANISOU 131 C GLU A 18 5658 5017 5628 157 500 342 C
+ATOM 132 O GLU A 18 -0.225 -8.908 -38.983 1.00 50.61 O
+ANISOU 132 O GLU A 18 6614 5981 6632 182 459 356 O
+ATOM 133 CB GLU A 18 1.373 -7.869 -41.404 1.00 49.05 C
+ANISOU 133 CB GLU A 18 6290 5791 6555 246 574 536 C
+ATOM 134 CG GLU A 18 1.849 -7.008 -42.535 1.00 63.96 C
+ANISOU 134 CG GLU A 18 8110 7691 8497 264 618 626 C
+ATOM 135 CD GLU A 18 3.316 -7.261 -42.867 1.00 75.06 C
+ANISOU 135 CD GLU A 18 9436 9075 10006 344 719 757 C
+ATOM 136 OE1 GLU A 18 3.833 -8.337 -42.508 1.00 68.87 O
+ANISOU 136 OE1 GLU A 18 8682 8270 9214 408 790 779 O
+ATOM 137 OE2 GLU A 18 3.953 -6.347 -43.437 1.00 86.26 O
+ANISOU 137 OE2 GLU A 18 10749 10492 11532 351 741 855 O
+ATOM 138 N CYS A 19 -1.403 -9.397 -40.824 1.00 42.18 N
+ANISOU 138 N CYS A 19 5675 4930 5420 110 580 258 N
+ATOM 139 CA CYS A 19 -2.100 -10.522 -40.319 1.00 42.40 C
+ANISOU 139 CA CYS A 19 5816 4913 5379 67 646 167 C
+ATOM 140 C CYS A 19 -2.196 -11.521 -41.439 1.00 43.87 C
+ANISOU 140 C CYS A 19 6123 5068 5477 29 804 99 C
+ATOM 141 O CYS A 19 -2.743 -11.212 -42.516 1.00 43.45 O
+ANISOU 141 O CYS A 19 6070 5112 5326 -37 790 39 O
+ATOM 142 CB CYS A 19 -3.524 -10.140 -39.826 1.00 45.74 C
+ANISOU 142 CB CYS A 19 6229 5397 5751 -23 551 67 C
+ATOM 143 SG CYS A 19 -4.342 -11.539 -39.028 1.00 48.02 S
+ANISOU 143 SG CYS A 19 6646 5607 5990 -86 658 -31 S
+ATOM 144 N ASP A 20 -1.642 -12.721 -41.204 1.00 45.23 N
+ANISOU 144 N ASP A 20 6401 5109 5674 79 970 112 N
+ATOM 145 CA ASP A 20 -1.719 -13.795 -42.164 1.00 47.07 C
+ANISOU 145 CA ASP A 20 6786 5262 5833 28 1168 13 C
+ATOM 146 C ASP A 20 -3.181 -14.220 -42.331 1.00 49.54 C
+ANISOU 146 C ASP A 20 7175 5613 6035 -157 1166 -185 C
+ATOM 147 O ASP A 20 -4.027 -14.046 -41.400 1.00 46.05 O
+ANISOU 147 O ASP A 20 6690 5197 5609 -209 1069 -212 O
+ATOM 148 CB ASP A 20 -0.895 -14.979 -41.694 1.00 49.71 C
+ANISOU 148 CB ASP A 20 7224 5411 6252 141 1380 87 C
+ATOM 149 CG ASP A 20 0.620 -14.723 -41.766 1.00 64.33 C
+ANISOU 149 CG ASP A 20 8980 7254 8207 325 1414 288 C
+ATOM 150 OD1 ASP A 20 1.122 -14.017 -42.690 1.00 70.08 O
+ANISOU 150 OD1 ASP A 20 9639 8062 8926 341 1382 324 O
+ATOM 151 OD2 ASP A 20 1.349 -15.271 -40.906 1.00 70.59 O
+ANISOU 151 OD2 ASP A 20 9755 7971 9092 465 1489 432 O
+ATOM 152 N ASP A 21 -3.481 -14.806 -43.487 1.00 48.95 N
+ANISOU 152 N ASP A 21 7206 5550 5840 -269 1280 -332 N
+ATOM 153 CA ASP A 21 -4.886 -15.213 -43.792 1.00 52.07 C
+ANISOU 153 CA ASP A 21 7641 6029 6111 -489 1264 -547 C
+ATOM 154 C ASP A 21 -5.466 -16.364 -42.961 1.00 52.45 C
+ANISOU 154 C ASP A 21 7805 5898 6224 -586 1412 -652 C
+ATOM 155 O ASP A 21 -6.664 -16.621 -43.076 1.00 52.58 O
+ANISOU 155 O ASP A 21 7815 5996 6165 -785 1384 -823 O
+ATOM 156 CB ASP A 21 -5.080 -15.591 -45.251 1.00 52.20 C
+ANISOU 156 CB ASP A 21 7744 6142 5948 -620 1342 -716 C
+ATOM 157 CG ASP A 21 -4.192 -16.744 -45.675 1.00 54.79 C
+ANISOU 157 CG ASP A 21 8277 6240 6300 -591 1630 -772 C
+ATOM 158 OD1 ASP A 21 -3.555 -17.399 -44.833 1.00 60.00 O
+ANISOU 158 OD1 ASP A 21 9012 6660 7124 -475 1787 -678 O
+ATOM 159 OD2 ASP A 21 -4.087 -16.978 -46.873 1.00 66.22 O
+ANISOU 159 OD2 ASP A 21 9812 7754 7595 -664 1713 -895 O
+ATOM 160 N ASP A 22 -4.630 -17.059 -42.198 1.00 51.20 N
+ANISOU 160 N ASP A 22 7738 5513 6200 -447 1580 -538 N
+ATOM 161 CA ASP A 22 -5.098 -18.073 -41.256 1.00 62.00 C
+ANISOU 161 CA ASP A 22 9213 6691 7651 -492 1741 -573 C
+ATOM 162 C ASP A 22 -4.625 -17.744 -39.835 1.00 59.08 C
+ANISOU 162 C ASP A 22 8764 6294 7388 -296 1668 -346 C
+ATOM 163 O ASP A 22 -4.377 -18.629 -39.062 1.00 56.04 O
+ANISOU 163 O ASP A 22 8478 5724 7088 -214 1851 -264 O
+ATOM 164 CB ASP A 22 -4.624 -19.475 -41.714 1.00 71.33 C
+ANISOU 164 CB ASP A 22 10621 7602 8879 -509 2084 -652 C
+ATOM 165 CG ASP A 22 -3.093 -19.576 -41.838 1.00 78.00 C
+ANISOU 165 CG ASP A 22 11493 8340 9802 -254 2204 -448 C
+ATOM 166 OD1 ASP A 22 -2.396 -18.536 -41.681 1.00 74.86 O
+ANISOU 166 OD1 ASP A 22 10926 8102 9414 -102 2002 -272 O
+ATOM 167 OD2 ASP A 22 -2.585 -20.697 -42.122 1.00 91.53 O
+ANISOU 167 OD2 ASP A 22 13392 9804 11580 -212 2520 -469 O
+ATOM 168 N VAL A 23 -4.476 -16.441 -39.535 1.00 58.45 N
+ANISOU 168 N VAL A 23 8509 6406 7294 -222 1411 -246 N
+ATOM 169 CA VAL A 23 -4.282 -15.937 -38.191 1.00 51.17 C
+ANISOU 169 CA VAL A 23 7497 5521 6421 -98 1292 -96 C
+ATOM 170 C VAL A 23 -5.446 -15.027 -37.852 1.00 51.90 C
+ANISOU 170 C VAL A 23 7486 5767 6465 -205 1102 -177 C
+ATOM 171 O VAL A 23 -5.900 -14.243 -38.695 1.00 52.44 O
+ANISOU 171 O VAL A 23 7471 5973 6479 -287 979 -252 O
+ATOM 172 CB VAL A 23 -2.914 -15.295 -38.008 1.00 53.75 C
+ANISOU 172 CB VAL A 23 7721 5902 6798 84 1203 86 C
+ATOM 173 CG1 VAL A 23 -2.782 -14.588 -36.643 1.00 51.64 C
+ANISOU 173 CG1 VAL A 23 7345 5733 6542 168 1034 192 C
+ATOM 174 CG2 VAL A 23 -1.872 -16.402 -38.166 1.00 52.89 C
+ANISOU 174 CG2 VAL A 23 7712 5629 6754 219 1438 196 C
+ATOM 175 N TYR A 24 -6.020 -15.271 -36.669 1.00 49.92 N
+ANISOU 175 N TYR A 24 7252 5485 6229 -201 1118 -157 N
+ATOM 176 CA TYR A 24 -7.105 -14.448 -36.120 1.00 49.53 C
+ANISOU 176 CA TYR A 24 7107 5561 6149 -269 973 -210 C
+ATOM 177 C TYR A 24 -6.598 -13.062 -35.859 1.00 47.90 C
+ANISOU 177 C TYR A 24 6775 5477 5946 -174 771 -133 C
+ATOM 178 O TYR A 24 -5.530 -12.835 -35.330 1.00 50.41 O
+ANISOU 178 O TYR A 24 7074 5788 6289 -48 730 -19 O
+ATOM 179 CB TYR A 24 -7.664 -14.995 -34.792 1.00 53.15 C
+ANISOU 179 CB TYR A 24 7622 5953 6617 -252 1058 -177 C
+ATOM 180 CG TYR A 24 -8.368 -16.349 -34.905 1.00 54.34 C
+ANISOU 180 CG TYR A 24 7898 5950 6796 -378 1291 -263 C
+ATOM 181 CD1 TYR A 24 -9.369 -16.572 -35.863 1.00 61.64 C
+ANISOU 181 CD1 TYR A 24 8804 6911 7703 -595 1316 -450 C
+ATOM 182 CD2 TYR A 24 -8.040 -17.385 -34.061 1.00 58.06 C
+ANISOU 182 CD2 TYR A 24 8497 6251 7312 -288 1491 -157 C
+ATOM 183 CE1 TYR A 24 -10.013 -17.808 -35.976 1.00 67.82 C
+ANISOU 183 CE1 TYR A 24 9699 7540 8526 -757 1542 -565 C
+ATOM 184 CE2 TYR A 24 -8.691 -18.634 -34.147 1.00 67.21 C
+ANISOU 184 CE2 TYR A 24 9786 7220 8531 -418 1749 -239 C
+ATOM 185 CZ TYR A 24 -9.672 -18.847 -35.099 1.00 67.30 C
+ANISOU 185 CZ TYR A 24 9783 7246 8539 -670 1777 -462 C
+ATOM 186 OH TYR A 24 -10.304 -20.070 -35.167 1.00 63.80 O
+ANISOU 186 OH TYR A 24 9466 6605 8170 -838 2041 -574 O
+ATOM 187 N VAL A 25 -7.413 -12.132 -36.241 1.00 46.10 N
+ANISOU 187 N VAL A 25 6451 5365 5699 -242 655 -197 N
+ATOM 188 CA VAL A 25 -7.117 -10.720 -36.104 1.00 50.13 C
+ANISOU 188 CA VAL A 25 6853 5957 6237 -176 500 -147 C
+ATOM 189 C VAL A 25 -6.622 -10.284 -34.725 1.00 49.08 C
+ANISOU 189 C VAL A 25 6716 5810 6120 -88 441 -91 C
+ATOM 190 O VAL A 25 -5.602 -9.548 -34.601 1.00 48.80 O
+ANISOU 190 O VAL A 25 6626 5791 6124 -25 355 -35 O
+ATOM 191 CB VAL A 25 -8.407 -10.000 -36.511 1.00 51.95 C
+ANISOU 191 CB VAL A 25 6992 6297 6447 -248 438 -209 C
+ATOM 192 CG1 VAL A 25 -8.482 -8.654 -35.889 1.00 65.37 C
+ANISOU 192 CG1 VAL A 25 8616 8025 8196 -180 340 -173 C
+ATOM 193 CG2 VAL A 25 -8.427 -9.935 -38.033 1.00 52.86 C
+ANISOU 193 CG2 VAL A 25 7066 6496 6519 -296 427 -223 C
+ATOM 194 N LEU A 26 -7.301 -10.753 -33.681 1.00 50.45 N
+ANISOU 194 N LEU A 26 6944 5968 6256 -94 493 -112 N
+ATOM 195 CA LEU A 26 -6.902 -10.450 -32.290 1.00 47.33 C
+ANISOU 195 CA LEU A 26 6562 5597 5822 -14 443 -70 C
+ATOM 196 C LEU A 26 -5.498 -10.894 -32.035 1.00 47.06 C
+ANISOU 196 C LEU A 26 6537 5561 5781 82 436 39 C
+ATOM 197 O LEU A 26 -4.721 -10.194 -31.377 1.00 55.96 O
+ANISOU 197 O LEU A 26 7607 6768 6888 128 318 66 O
+ATOM 198 CB LEU A 26 -7.807 -11.200 -31.306 1.00 53.55 C
+ANISOU 198 CB LEU A 26 7430 6361 6552 -20 551 -79 C
+ATOM 199 CG LEU A 26 -7.510 -11.161 -29.801 1.00 55.13 C
+ANISOU 199 CG LEU A 26 7674 6613 6658 70 531 -26 C
+ATOM 200 CD1 LEU A 26 -7.326 -9.720 -29.325 1.00 55.80 C
+ANISOU 200 CD1 LEU A 26 7695 6785 6722 71 376 -95 C
+ATOM 201 CD2 LEU A 26 -8.666 -11.852 -29.032 1.00 61.83 C
+ANISOU 201 CD2 LEU A 26 8600 7428 7463 52 674 -33 C
+ATOM 202 N ASP A 27 -5.136 -12.069 -32.524 1.00 48.10 N
+ANISOU 202 N ASP A 27 6734 5609 5931 111 571 103 N
+ATOM 203 CA ASP A 27 -3.762 -12.587 -32.305 1.00 48.67 C
+ANISOU 203 CA ASP A 27 6797 5686 6010 241 594 251 C
+ATOM 204 C ASP A 27 -2.701 -11.814 -33.061 1.00 52.00 C
+ANISOU 204 C ASP A 27 7102 6157 6495 255 488 280 C
+ATOM 205 O ASP A 27 -1.619 -11.648 -32.546 1.00 53.84 O
+ANISOU 205 O ASP A 27 7252 6477 6725 342 414 382 O
+ATOM 206 CB ASP A 27 -3.670 -14.036 -32.649 1.00 52.61 C
+ANISOU 206 CB ASP A 27 7412 6040 6537 286 816 319 C
+ATOM 207 CG ASP A 27 -4.541 -14.887 -31.735 1.00 63.74 C
+ANISOU 207 CG ASP A 27 8934 7380 7902 289 954 332 C
+ATOM 208 OD1 ASP A 27 -4.580 -14.630 -30.517 1.00 77.44 O
+ANISOU 208 OD1 ASP A 27 10653 9216 9555 357 885 392 O
+ATOM 209 OD2 ASP A 27 -5.228 -15.780 -32.232 1.00 66.17 O
+ANISOU 209 OD2 ASP A 27 9347 7539 8253 206 1139 268 O
+ATOM 210 N ALA A 28 -3.001 -11.313 -34.254 1.00 45.81 N
+ANISOU 210 N ALA A 28 6297 5346 5763 172 479 200 N
+ATOM 211 CA ALA A 28 -2.052 -10.414 -34.921 1.00 45.27 C
+ANISOU 211 CA ALA A 28 6113 5321 5765 182 389 237 C
+ATOM 212 C ALA A 28 -1.874 -9.098 -34.113 1.00 46.76 C
+ANISOU 212 C ALA A 28 6200 5596 5968 152 219 201 C
+ATOM 213 O ALA A 28 -0.782 -8.604 -33.981 1.00 48.55 O
+ANISOU 213 O ALA A 28 6321 5880 6246 174 142 256 O
+ATOM 214 CB ALA A 28 -2.542 -10.096 -36.327 1.00 48.41 C
+ANISOU 214 CB ALA A 28 6517 5691 6185 111 423 175 C
+ATOM 215 N ALA A 29 -2.956 -8.547 -33.566 1.00 46.59 N
+ANISOU 215 N ALA A 29 6211 5582 5908 92 177 97 N
+ATOM 216 CA ALA A 29 -2.882 -7.367 -32.726 1.00 45.37 C
+ANISOU 216 CA ALA A 29 6001 5476 5760 54 58 28 C
+ATOM 217 C ALA A 29 -2.026 -7.590 -31.506 1.00 45.22 C
+ANISOU 217 C ALA A 29 5953 5566 5662 94 -18 63 C
+ATOM 218 O ALA A 29 -1.157 -6.760 -31.212 1.00 50.70 O
+ANISOU 218 O ALA A 29 6546 6327 6390 54 -129 39 O
+ATOM 219 CB ALA A 29 -4.268 -6.959 -32.299 1.00 45.68 C
+ANISOU 219 CB ALA A 29 6100 5492 5763 13 76 -74 C
+ATOM 220 N GLU A 30 -2.244 -8.704 -30.827 1.00 46.60 N
+ANISOU 220 N GLU A 30 6205 5769 5730 169 45 128 N
+ATOM 221 CA GLU A 30 -1.476 -9.042 -29.636 1.00 54.76 C
+ANISOU 221 CA GLU A 30 7206 6952 6646 243 -23 204 C
+ATOM 222 C GLU A 30 -0.050 -9.331 -29.955 1.00 54.21 C
+ANISOU 222 C GLU A 30 7010 6960 6626 313 -60 346 C
+ATOM 223 O GLU A 30 0.832 -8.823 -29.288 1.00 59.88 O
+ANISOU 223 O GLU A 30 7604 7849 7298 302 -205 354 O
+ATOM 224 CB GLU A 30 -2.122 -10.183 -28.852 1.00 62.74 C
+ANISOU 224 CB GLU A 30 8340 7960 7538 332 92 277 C
+ATOM 225 CG GLU A 30 -3.470 -9.711 -28.236 1.00 72.73 C
+ANISOU 225 CG GLU A 30 9697 9198 8739 260 106 134 C
+ATOM 226 CD GLU A 30 -4.256 -10.812 -27.471 1.00 84.77 C
+ANISOU 226 CD GLU A 30 11347 10699 10163 332 254 206 C
+ATOM 227 OE1 GLU A 30 -4.358 -12.001 -27.950 1.00 80.99 O
+ANISOU 227 OE1 GLU A 30 10932 10104 9737 384 419 311 O
+ATOM 228 OE2 GLU A 30 -4.785 -10.463 -26.379 1.00 83.98 O
+ANISOU 228 OE2 GLU A 30 11293 10681 9934 331 227 148 O
+ATOM 229 N GLU A 31 0.205 -10.073 -31.022 1.00 59.74 N
+ANISOU 229 N GLU A 31 7727 7548 7422 373 72 443 N
+ATOM 230 CA GLU A 31 1.574 -10.229 -31.535 1.00 56.65 C
+ANISOU 230 CA GLU A 31 7199 7210 7113 445 65 582 C
+ATOM 231 C GLU A 31 2.251 -8.862 -31.829 1.00 60.42 C
+ANISOU 231 C GLU A 31 7517 7754 7685 328 -85 505 C
+ATOM 232 O GLU A 31 3.462 -8.797 -31.776 1.00 66.23 O
+ANISOU 232 O GLU A 31 8087 8613 8463 365 -148 610 O
+ATOM 233 CB GLU A 31 1.536 -11.120 -32.771 1.00 64.23 C
+ANISOU 233 CB GLU A 31 8243 7999 8160 503 266 648 C
+ATOM 234 CG GLU A 31 2.861 -11.443 -33.471 1.00 83.36 C
+ANISOU 234 CG GLU A 31 10552 10436 10682 606 328 807 C
+ATOM 235 CD GLU A 31 3.790 -12.366 -32.669 1.00102.53 C
+ANISOU 235 CD GLU A 31 12908 12976 13073 795 367 1027 C
+ATOM 236 OE1 GLU A 31 3.385 -12.888 -31.594 1.00113.60 O
+ANISOU 236 OE1 GLU A 31 14374 14434 14355 859 366 1071 O
+ATOM 237 OE2 GLU A 31 4.946 -12.569 -33.121 1.00102.50 O
+ANISOU 237 OE2 GLU A 31 12770 13016 13158 898 412 1182 O
+ATOM 238 N ALA A 32 1.502 -7.778 -32.127 1.00 57.02 N
+ANISOU 238 N ALA A 32 7120 7240 7301 193 -126 339 N
+ATOM 239 CA ALA A 32 2.120 -6.424 -32.410 1.00 59.13 C
+ANISOU 239 CA ALA A 32 7255 7519 7692 72 -224 265 C
+ATOM 240 C ALA A 32 2.224 -5.516 -31.195 1.00 56.89 C
+ANISOU 240 C ALA A 32 6920 7349 7346 -41 -378 124 C
+ATOM 241 O ALA A 32 2.754 -4.418 -31.279 1.00 65.02 O
+ANISOU 241 O ALA A 32 7847 8373 8484 -167 -445 38 O
+ATOM 242 CB ALA A 32 1.377 -5.676 -33.506 1.00 53.40 C
+ANISOU 242 CB ALA A 32 6588 6626 7076 11 -149 198 C
+ATOM 243 N GLY A 33 1.719 -5.987 -30.077 1.00 55.56 N
+ANISOU 243 N GLY A 33 6832 7274 7000 -3 -414 93 N
+ATOM 244 CA GLY A 33 1.778 -5.257 -28.849 1.00 58.15 C
+ANISOU 244 CA GLY A 33 7139 7738 7215 -106 -550 -56 C
+ATOM 245 C GLY A 33 0.546 -4.451 -28.568 1.00 60.01 C
+ANISOU 245 C GLY A 33 7520 7837 7440 -190 -508 -246 C
+ATOM 246 O GLY A 33 0.620 -3.573 -27.741 1.00 69.82 O
+ANISOU 246 O GLY A 33 8758 9139 8629 -310 -593 -418 O
+ATOM 247 N ILE A 34 -0.586 -4.759 -29.224 1.00 61.19 N
+ANISOU 247 N ILE A 34 7792 7820 7635 -130 -370 -221 N
+ATOM 248 CA ILE A 34 -1.840 -4.017 -29.038 1.00 58.99 C
+ANISOU 248 CA ILE A 34 7627 7418 7368 -177 -306 -363 C
+ATOM 249 C ILE A 34 -2.765 -4.786 -28.094 1.00 62.15 C
+ANISOU 249 C ILE A 34 8149 7876 7589 -107 -261 -367 C
+ATOM 250 O ILE A 34 -3.056 -5.947 -28.343 1.00 63.50 O
+ANISOU 250 O ILE A 34 8359 8045 7721 -13 -186 -239 O
+ATOM 251 CB ILE A 34 -2.577 -3.788 -30.390 1.00 61.05 C
+ANISOU 251 CB ILE A 34 7905 7506 7785 -156 -191 -318 C
+ATOM 252 CG1 ILE A 34 -1.701 -2.983 -31.385 1.00 65.68 C
+ANISOU 252 CG1 ILE A 34 8381 8020 8552 -209 -201 -287 C
+ATOM 253 CG2 ILE A 34 -3.890 -3.029 -30.184 1.00 63.01 C
+ANISOU 253 CG2 ILE A 34 8237 7650 8053 -172 -114 -425 C
+ATOM 254 CD1 ILE A 34 -2.244 -3.016 -32.822 1.00 63.49 C
+ANISOU 254 CD1 ILE A 34 8108 7640 8375 -155 -98 -187 C
+ATOM 255 N ASP A 35 -3.244 -4.141 -27.030 1.00 63.70 N
+ANISOU 255 N ASP A 35 8416 8102 7682 -158 -279 -520 N
+ATOM 256 CA ASP A 35 -4.088 -4.826 -26.025 1.00 71.88 C
+ANISOU 256 CA ASP A 35 9569 9207 8534 -87 -222 -516 C
+ATOM 257 C ASP A 35 -5.567 -4.529 -26.307 1.00 64.56 C
+ANISOU 257 C ASP A 35 8725 8121 7682 -77 -78 -569 C
+ATOM 258 O ASP A 35 -6.130 -3.476 -25.980 1.00 66.69 O
+ANISOU 258 O ASP A 35 9040 8315 7983 -127 -40 -715 O
+ATOM 259 CB ASP A 35 -3.667 -4.503 -24.557 1.00 81.85 C
+ANISOU 259 CB ASP A 35 10862 10660 9575 -127 -325 -633 C
+ATOM 260 CG ASP A 35 -2.375 -5.278 -24.107 1.00 93.06 C
+ANISOU 260 CG ASP A 35 12178 12327 10851 -75 -463 -497 C
+ATOM 261 OD1 ASP A 35 -2.081 -6.430 -24.567 1.00 87.57 O
+ANISOU 261 OD1 ASP A 35 11448 11645 10179 50 -418 -279 O
+ATOM 262 OD2 ASP A 35 -1.644 -4.712 -23.270 1.00100.07 O
+ANISOU 262 OD2 ASP A 35 13013 13406 11600 -161 -608 -613 O
+ATOM 263 N LEU A 36 -6.157 -5.471 -27.010 1.00 61.66 N
+ANISOU 263 N LEU A 36 8363 7702 7362 -15 12 -444 N
+ATOM 264 CA LEU A 36 -7.533 -5.410 -27.353 1.00 56.54 C
+ANISOU 264 CA LEU A 36 7746 6959 6776 -6 133 -460 C
+ATOM 265 C LEU A 36 -8.274 -6.365 -26.418 1.00 58.83 C
+ANISOU 265 C LEU A 36 8125 7301 6925 45 227 -424 C
+ATOM 266 O LEU A 36 -7.725 -7.349 -25.938 1.00 59.91 O
+ANISOU 266 O LEU A 36 8295 7514 6951 96 222 -330 O
+ATOM 267 CB LEU A 36 -7.736 -5.829 -28.796 1.00 54.45 C
+ANISOU 267 CB LEU A 36 7414 6631 6642 -9 169 -370 C
+ATOM 268 CG LEU A 36 -7.150 -4.979 -29.924 1.00 47.43 C
+ANISOU 268 CG LEU A 36 6437 5685 5896 -39 115 -362 C
+ATOM 269 CD1 LEU A 36 -7.661 -5.559 -31.235 1.00 51.84 C
+ANISOU 269 CD1 LEU A 36 6953 6228 6515 -36 168 -282 C
+ATOM 270 CD2 LEU A 36 -7.550 -3.538 -29.754 1.00 48.45 C
+ANISOU 270 CD2 LEU A 36 6559 5739 6109 -60 130 -458 C
+ATOM 271 N PRO A 37 -9.531 -6.066 -26.158 1.00 52.73 N
+ANISOU 271 N PRO A 37 7383 6483 6166 48 333 -477 N
+ATOM 272 CA PRO A 37 -10.189 -6.803 -25.130 1.00 48.70 C
+ANISOU 272 CA PRO A 37 6960 6021 5521 94 437 -451 C
+ATOM 273 C PRO A 37 -10.579 -8.210 -25.630 1.00 53.45 C
+ANISOU 273 C PRO A 37 7558 6591 6158 100 538 -324 C
+ATOM 274 O PRO A 37 -10.785 -8.477 -26.837 1.00 49.32 O
+ANISOU 274 O PRO A 37 6961 6008 5767 49 548 -299 O
+ATOM 275 CB PRO A 37 -11.382 -5.907 -24.791 1.00 51.49 C
+ANISOU 275 CB PRO A 37 7326 6326 5910 95 535 -549 C
+ATOM 276 CG PRO A 37 -11.712 -5.243 -26.095 1.00 57.15 C
+ANISOU 276 CG PRO A 37 7927 6960 6825 64 521 -547 C
+ATOM 277 CD PRO A 37 -10.372 -5.018 -26.760 1.00 53.71 C
+ANISOU 277 CD PRO A 37 7454 6520 6432 30 379 -538 C
+ATOM 278 N TYR A 38 -10.593 -9.140 -24.698 1.00 52.25 N
+ANISOU 278 N TYR A 38 7494 6481 5875 159 621 -244 N
+ATOM 279 CA TYR A 38 -11.096 -10.464 -24.975 1.00 58.41 C
+ANISOU 279 CA TYR A 38 8299 7189 6702 152 774 -141 C
+ATOM 280 C TYR A 38 -11.545 -11.071 -23.664 1.00 53.69 C
+ANISOU 280 C TYR A 38 7809 6629 5962 227 913 -70 C
+ATOM 281 O TYR A 38 -11.164 -10.607 -22.581 1.00 52.44 O
+ANISOU 281 O TYR A 38 7709 6589 5625 301 856 -82 O
+ATOM 282 CB TYR A 38 -9.996 -11.359 -25.594 1.00 54.60 C
+ANISOU 282 CB TYR A 38 7821 6673 6252 178 755 -32 C
+ATOM 283 CG TYR A 38 -8.783 -11.536 -24.706 1.00 57.28 C
+ANISOU 283 CG TYR A 38 8199 7128 6435 299 678 70 C
+ATOM 284 CD1 TYR A 38 -7.743 -10.603 -24.717 1.00 57.17 C
+ANISOU 284 CD1 TYR A 38 8115 7222 6383 300 480 19 C
+ATOM 285 CD2 TYR A 38 -8.679 -12.620 -23.830 1.00 58.87 C
+ANISOU 285 CD2 TYR A 38 8492 7349 6525 412 809 232 C
+ATOM 286 CE1 TYR A 38 -6.629 -10.752 -23.885 1.00 58.64 C
+ANISOU 286 CE1 TYR A 38 8295 7574 6409 396 383 113 C
+ATOM 287 CE2 TYR A 38 -7.565 -12.768 -22.985 1.00 62.26 C
+ANISOU 287 CE2 TYR A 38 8928 7946 6781 545 722 358 C
+ATOM 288 CZ TYR A 38 -6.548 -11.837 -23.032 1.00 65.34 C
+ANISOU 288 CZ TYR A 38 9221 8482 7122 529 494 291 C
+ATOM 289 OH TYR A 38 -5.464 -11.963 -22.208 1.00 72.76 O
+ANISOU 289 OH TYR A 38 10126 9640 7877 642 383 410 O
+ATOM 290 N SER A 39 -12.264 -12.176 -23.765 1.00 51.04 N
+ANISOU 290 N SER A 39 7503 6198 5691 202 1102 6 N
+ATOM 291 CA SER A 39 -12.527 -12.977 -22.556 1.00 52.70 C
+ANISOU 291 CA SER A 39 7828 6422 5770 296 1272 129 C
+ATOM 292 C SER A 39 -12.586 -14.475 -22.933 1.00 54.61 C
+ANISOU 292 C SER A 39 8121 6509 6118 281 1473 260 C
+ATOM 293 O SER A 39 -11.697 -15.196 -22.537 1.00 53.05 O
+ANISOU 293 O SER A 39 8000 6314 5842 404 1512 419 O
+ATOM 294 CB SER A 39 -13.752 -12.480 -21.786 1.00 50.63 C
+ANISOU 294 CB SER A 39 7578 6193 5466 287 1376 64 C
+ATOM 295 OG SER A 39 -14.134 -13.447 -20.804 1.00 57.92 O
+ANISOU 295 OG SER A 39 8608 7099 6297 364 1590 207 O
+ATOM 296 N CYS A 40 -13.549 -14.932 -23.748 1.00 56.78 N
+ANISOU 296 N CYS A 40 8345 6653 6573 127 1599 192 N
+ATOM 297 CA CYS A 40 -13.634 -16.380 -24.053 1.00 57.29 C
+ANISOU 297 CA CYS A 40 8484 6532 6749 80 1830 281 C
+ATOM 298 C CYS A 40 -12.645 -16.882 -25.075 1.00 62.77 C
+ANISOU 298 C CYS A 40 9192 7133 7523 67 1795 293 C
+ATOM 299 O CYS A 40 -12.278 -18.037 -25.022 1.00 51.88 O
+ANISOU 299 O CYS A 40 7920 5599 6191 114 1993 416 O
+ATOM 300 CB CYS A 40 -15.040 -16.831 -24.469 1.00 62.61 C
+ANISOU 300 CB CYS A 40 9100 7107 7580 -117 2004 185 C
+ATOM 301 SG CYS A 40 -15.521 -16.463 -26.163 1.00 58.56 S
+ANISOU 301 SG CYS A 40 8420 6610 7220 -350 1871 -25 S
+ATOM 302 N ARG A 41 -12.233 -16.028 -26.016 1.00 58.00 N
+ANISOU 302 N ARG A 41 8486 6605 6943 14 1575 175 N
+ATOM 303 CA ARG A 41 -11.317 -16.429 -27.087 1.00 58.21 C
+ANISOU 303 CA ARG A 41 8521 6552 7044 -1 1548 175 C
+ATOM 304 C ARG A 41 -11.821 -17.585 -27.916 1.00 57.79 C
+ANISOU 304 C ARG A 41 8520 6302 7133 -157 1766 115 C
+ATOM 305 O ARG A 41 -10.986 -18.264 -28.554 1.00 62.26 O
+ANISOU 305 O ARG A 41 9155 6747 7753 -132 1841 152 O
+ATOM 306 CB ARG A 41 -9.896 -16.763 -26.569 1.00 63.76 C
+ANISOU 306 CB ARG A 41 9289 7271 7664 206 1533 363 C
+ATOM 307 CG ARG A 41 -9.186 -15.605 -25.856 1.00 71.18 C
+ANISOU 307 CG ARG A 41 10160 8433 8450 322 1286 387 C
+ATOM 308 CD ARG A 41 -7.710 -15.932 -25.568 1.00 80.04 C
+ANISOU 308 CD ARG A 41 11287 9622 9501 504 1238 570 C
+ATOM 309 NE ARG A 41 -6.866 -15.741 -26.762 1.00 74.82 N
+ANISOU 309 NE ARG A 41 10554 8929 8944 472 1145 532 N
+ATOM 310 CZ ARG A 41 -6.356 -14.582 -27.159 1.00 78.00 C
+ANISOU 310 CZ ARG A 41 10841 9455 9338 432 915 438 C
+ATOM 311 NH1 ARG A 41 -6.552 -13.467 -26.465 1.00 81.90 N
+ANISOU 311 NH1 ARG A 41 11285 10102 9732 410 749 350 N
+ATOM 312 NH2 ARG A 41 -5.644 -14.532 -28.265 1.00 86.15 N
+ANISOU 312 NH2 ARG A 41 11819 10442 10471 411 877 426 N
+ATOM 313 N ALA A 42 -13.150 -17.769 -27.971 1.00 49.81 N
+ANISOU 313 N ALA A 42 7468 5266 6189 -330 1868 7 N
+ATOM 314 CA ALA A 42 -13.768 -18.969 -28.558 1.00 57.96 C
+ANISOU 314 CA ALA A 42 8557 6104 7358 -524 2112 -75 C
+ATOM 315 C ALA A 42 -14.982 -18.639 -29.396 1.00 57.37 C
+ANISOU 315 C ALA A 42 8326 6129 7343 -777 2047 -282 C
+ATOM 316 O ALA A 42 -15.740 -19.526 -29.769 1.00 64.20 O
+ANISOU 316 O ALA A 42 9200 6877 8312 -990 2234 -389 O
+ATOM 317 CB ALA A 42 -14.200 -19.960 -27.458 1.00 56.47 C
+ANISOU 317 CB ALA A 42 8492 5754 7210 -482 2407 58 C
+ATOM 318 N GLY A 43 -15.231 -17.380 -29.635 1.00 52.54 N
+ANISOU 318 N GLY A 43 7557 5735 6668 -759 1799 -332 N
+ATOM 319 CA GLY A 43 -16.309 -17.040 -30.539 1.00 57.00 C
+ANISOU 319 CA GLY A 43 7941 6441 7273 -969 1718 -492 C
+ATOM 320 C GLY A 43 -17.684 -17.010 -29.934 1.00 58.47 C
+ANISOU 320 C GLY A 43 8011 6695 7510 -1063 1807 -511 C
+ATOM 321 O GLY A 43 -18.693 -16.858 -30.667 1.00 64.87 O
+ANISOU 321 O GLY A 43 8633 7651 8361 -1255 1754 -633 O
+ATOM 322 N SER A 44 -17.753 -17.088 -28.605 1.00 57.15 N
+ANISOU 322 N SER A 44 7930 6459 7323 -922 1931 -379 N
+ATOM 323 CA SER A 44 -19.057 -17.205 -27.927 1.00 59.58 C
+ANISOU 323 CA SER A 44 8144 6800 7692 -1003 2076 -376 C
+ATOM 324 C SER A 44 -19.354 -16.159 -26.851 1.00 51.98 C
+ANISOU 324 C SER A 44 7145 5959 6646 -810 2021 -281 C
+ATOM 325 O SER A 44 -20.144 -16.385 -25.952 1.00 58.60 O
+ANISOU 325 O SER A 44 7978 6778 7507 -803 2197 -224 O
+ATOM 326 CB SER A 44 -19.181 -18.630 -27.398 1.00 63.12 C
+ANISOU 326 CB SER A 44 8744 7008 8228 -1080 2393 -327 C
+ATOM 327 OG SER A 44 -17.989 -18.942 -26.691 1.00 75.47 O
+ANISOU 327 OG SER A 44 10522 8441 9708 -852 2451 -164 O
+ATOM 328 N CYS A 45 -18.785 -14.973 -26.981 1.00 51.65 N
+ANISOU 328 N CYS A 45 7072 6035 6515 -668 1796 -279 N
+ATOM 329 CA CYS A 45 -19.057 -13.886 -26.059 1.00 48.70 C
+ANISOU 329 CA CYS A 45 6677 5758 6066 -505 1753 -233 C
+ATOM 330 C CYS A 45 -18.893 -12.526 -26.780 1.00 51.12 C
+ANISOU 330 C CYS A 45 6860 6197 6366 -453 1521 -288 C
+ATOM 331 O CYS A 45 -18.542 -12.469 -27.980 1.00 50.80 O
+ANISOU 331 O CYS A 45 6749 6191 6360 -532 1388 -341 O
+ATOM 332 CB CYS A 45 -18.171 -13.989 -24.805 1.00 50.90 C
+ANISOU 332 CB CYS A 45 7166 5974 6198 -316 1803 -126 C
+ATOM 333 SG CYS A 45 -16.566 -13.180 -24.911 1.00 53.21 S
+ANISOU 333 SG CYS A 45 7542 6307 6366 -170 1556 -124 S
+ATOM 334 N SER A 46 -19.167 -11.439 -26.041 1.00 49.49 N
+ANISOU 334 N SER A 46 6640 6051 6114 -315 1503 -272 N
+ATOM 335 CA SER A 46 -19.261 -10.117 -26.614 1.00 49.31 C
+ANISOU 335 CA SER A 46 6494 6118 6122 -255 1356 -304 C
+ATOM 336 C SER A 46 -17.941 -9.369 -26.532 1.00 51.44 C
+ANISOU 336 C SER A 46 6888 6345 6311 -146 1208 -320 C
+ATOM 337 O SER A 46 -17.854 -8.268 -27.057 1.00 46.10 O
+ANISOU 337 O SER A 46 6135 5703 5678 -96 1103 -340 O
+ATOM 338 CB SER A 46 -20.298 -9.307 -25.871 1.00 50.14 C
+ANISOU 338 CB SER A 46 6525 6274 6249 -163 1462 -287 C
+ATOM 339 OG SER A 46 -19.973 -9.287 -24.483 1.00 49.91 O
+ANISOU 339 OG SER A 46 6691 6179 6094 -53 1563 -278 O
+ATOM 340 N SER A 47 -16.939 -9.950 -25.880 1.00 47.00 N
+ANISOU 340 N SER A 47 6498 5716 5641 -106 1210 -297 N
+ATOM 341 CA SER A 47 -15.839 -9.148 -25.341 1.00 48.40 C
+ANISOU 341 CA SER A 47 6782 5891 5713 -1 1093 -321 C
+ATOM 342 C SER A 47 -14.884 -8.548 -26.378 1.00 50.48 C
+ANISOU 342 C SER A 47 6998 6152 6030 -15 913 -348 C
+ATOM 343 O SER A 47 -14.433 -7.391 -26.220 1.00 42.86 O
+ANISOU 343 O SER A 47 6043 5186 5055 37 827 -403 O
+ATOM 344 CB SER A 47 -15.052 -9.964 -24.335 1.00 48.69 C
+ANISOU 344 CB SER A 47 6981 5919 5599 58 1134 -259 C
+ATOM 345 OG SER A 47 -14.042 -9.148 -23.822 1.00 52.57 O
+ANISOU 345 OG SER A 47 7538 6457 5976 130 999 -303 O
+ATOM 346 N CYS A 48 -14.586 -9.312 -27.432 1.00 46.30 N
+ANISOU 346 N CYS A 48 6426 5606 5560 -94 881 -320 N
+ATOM 347 CA CYS A 48 -13.615 -8.899 -28.445 1.00 43.55 C
+ANISOU 347 CA CYS A 48 6042 5255 5251 -102 736 -325 C
+ATOM 348 C CYS A 48 -14.282 -8.264 -29.667 1.00 48.19 C
+ANISOU 348 C CYS A 48 6472 5897 5938 -148 687 -339 C
+ATOM 349 O CYS A 48 -13.664 -8.163 -30.727 1.00 52.68 O
+ANISOU 349 O CYS A 48 7001 6475 6538 -171 598 -328 O
+ATOM 350 CB CYS A 48 -12.855 -10.140 -28.938 1.00 45.20 C
+ANISOU 350 CB CYS A 48 6309 5413 5450 -145 755 -280 C
+ATOM 351 SG CYS A 48 -13.936 -11.252 -29.869 1.00 49.74 S
+ANISOU 351 SG CYS A 48 6821 5979 6098 -304 875 -312 S
+ATOM 352 N ALA A 49 -15.536 -7.842 -29.543 1.00 49.80 N
+ANISOU 352 N ALA A 49 6575 6158 6186 -145 751 -344 N
+ATOM 353 CA ALA A 49 -16.294 -7.449 -30.708 1.00 48.00 C
+ANISOU 353 CA ALA A 49 6167 6039 6032 -181 710 -321 C
+ATOM 354 C ALA A 49 -15.698 -6.209 -31.365 1.00 47.62 C
+ANISOU 354 C ALA A 49 6079 5983 6030 -94 608 -287 C
+ATOM 355 O ALA A 49 -15.183 -5.313 -30.693 1.00 45.45 O
+ANISOU 355 O ALA A 49 5885 5614 5769 -6 608 -304 O
+ATOM 356 CB ALA A 49 -17.720 -7.170 -30.327 1.00 44.89 C
+ANISOU 356 CB ALA A 49 5646 5725 5684 -164 808 -302 C
+ATOM 357 N GLY A 50 -15.818 -6.151 -32.678 1.00 48.69 N
+ANISOU 357 N GLY A 50 6091 6224 6184 -128 536 -244 N
+ATOM 358 CA GLY A 50 -15.449 -4.952 -33.442 1.00 49.68 C
+ANISOU 358 CA GLY A 50 6154 6355 6367 -31 471 -170 C
+ATOM 359 C GLY A 50 -16.413 -4.732 -34.592 1.00 50.54 C
+ANISOU 359 C GLY A 50 6054 6667 6481 -27 438 -81 C
+ATOM 360 O GLY A 50 -17.402 -5.446 -34.760 1.00 51.08 O
+ANISOU 360 O GLY A 50 6008 6888 6512 -119 451 -99 O
+ATOM 361 N LYS A 51 -16.125 -3.748 -35.412 1.00 53.55 N
+ANISOU 361 N LYS A 51 6371 7070 6904 74 397 23 N
+ATOM 362 CA LYS A 51 -16.949 -3.502 -36.568 1.00 53.87 C
+ANISOU 362 CA LYS A 51 6201 7352 6915 104 349 142 C
+ATOM 363 C LYS A 51 -16.099 -3.324 -37.812 1.00 52.01 C
+ANISOU 363 C LYS A 51 5967 7166 6626 116 266 208 C
+ATOM 364 O LYS A 51 -15.259 -2.429 -37.884 1.00 49.83 O
+ANISOU 364 O LYS A 51 5763 6736 6431 222 288 275 O
+ATOM 365 CB LYS A 51 -17.819 -2.272 -36.354 1.00 55.11 C
+ANISOU 365 CB LYS A 51 6228 7529 7182 289 432 285 C
+ATOM 366 CG LYS A 51 -19.060 -2.302 -37.241 1.00 69.25 C
+ANISOU 366 CG LYS A 51 7743 9649 8918 311 386 414 C
+ATOM 367 CD LYS A 51 -19.994 -1.116 -37.036 1.00 78.14 C
+ANISOU 367 CD LYS A 51 8713 10807 10169 534 496 599 C
+ATOM 368 CE LYS A 51 -19.697 -0.098 -38.130 1.00 91.14 C
+ANISOU 368 CE LYS A 51 10279 12512 11835 709 478 813 C
+ATOM 369 NZ LYS A 51 -20.322 1.238 -37.924 1.00 98.12 N
+ANISOU 369 NZ LYS A 51 11067 13328 12884 974 639 1022 N
+ATOM 370 N VAL A 52 -16.371 -4.149 -38.805 1.00 56.50 N
+ANISOU 370 N VAL A 52 6451 7958 7057 -1 184 184 N
+ATOM 371 CA VAL A 52 -15.743 -4.044 -40.096 1.00 53.02 C
+ANISOU 371 CA VAL A 52 5995 7623 6524 10 113 251 C
+ATOM 372 C VAL A 52 -16.271 -2.823 -40.812 1.00 55.66 C
+ANISOU 372 C VAL A 52 6153 8116 6878 198 104 478 C
+ATOM 373 O VAL A 52 -17.446 -2.763 -41.107 1.00 57.54 O
+ANISOU 373 O VAL A 52 6184 8614 7061 218 71 553 O
+ATOM 374 CB VAL A 52 -16.050 -5.263 -40.957 1.00 52.46 C
+ANISOU 374 CB VAL A 52 5882 7779 6271 -184 41 135 C
+ATOM 375 CG1 VAL A 52 -15.519 -5.033 -42.382 1.00 54.82 C
+ANISOU 375 CG1 VAL A 52 6153 8239 6436 -149 -26 221 C
+ATOM 376 CG2 VAL A 52 -15.383 -6.462 -40.332 1.00 50.36 C
+ANISOU 376 CG2 VAL A 52 5817 7306 6010 -339 95 -55 C
+ATOM 377 N VAL A 53 -15.394 -1.848 -41.054 1.00 54.66 N
+ANISOU 377 N VAL A 53 6097 7828 6843 341 150 599 N
+ATOM 378 CA VAL A 53 -15.763 -0.629 -41.772 1.00 62.36 C
+ANISOU 378 CA VAL A 53 6930 8905 7859 554 184 855 C
+ATOM 379 C VAL A 53 -15.275 -0.645 -43.240 1.00 58.73 C
+ANISOU 379 C VAL A 53 6429 8643 7241 577 116 972 C
+ATOM 380 O VAL A 53 -15.785 0.085 -44.048 1.00 58.59 O
+ANISOU 380 O VAL A 53 6253 8828 7179 741 116 1203 O
+ATOM 381 CB VAL A 53 -15.351 0.680 -41.005 1.00 65.49 C
+ANISOU 381 CB VAL A 53 7415 8968 8500 719 338 940 C
+ATOM 382 CG1 VAL A 53 -15.576 0.504 -39.522 1.00 72.86 C
+ANISOU 382 CG1 VAL A 53 8446 9701 9533 655 398 764 C
+ATOM 383 CG2 VAL A 53 -13.917 1.090 -41.248 1.00 68.64 C
+ANISOU 383 CG2 VAL A 53 7968 9134 8977 721 376 943 C
+ATOM 384 N SER A 54 -14.348 -1.525 -43.591 1.00 53.74 N
+ANISOU 384 N SER A 54 5935 7975 6509 426 68 825 N
+ATOM 385 CA SER A 54 -13.884 -1.675 -44.972 1.00 55.87 C
+ANISOU 385 CA SER A 54 6190 8441 6597 431 18 904 C
+ATOM 386 C SER A 54 -13.173 -3.046 -45.081 1.00 56.25 C
+ANISOU 386 C SER A 54 6394 8450 6527 213 -15 660 C
+ATOM 387 O SER A 54 -12.486 -3.512 -44.129 1.00 49.66 O
+ANISOU 387 O SER A 54 5714 7335 5817 133 33 511 O
+ATOM 388 CB SER A 54 -12.991 -0.455 -45.367 1.00 56.61 C
+ANISOU 388 CB SER A 54 6326 8357 6824 625 121 1123 C
+ATOM 389 OG SER A 54 -12.138 -0.710 -46.445 1.00 63.73 O
+ANISOU 389 OG SER A 54 7288 9336 7589 611 112 1159 O
+ATOM 390 N GLY A 55 -13.389 -3.710 -46.217 1.00 53.71 N
+ANISOU 390 N GLY A 55 6028 8423 5956 121 -89 620 N
+ATOM 391 CA GLY A 55 -12.890 -5.055 -46.464 1.00 54.03 C
+ANISOU 391 CA GLY A 55 6214 8444 5869 -87 -89 381 C
+ATOM 392 C GLY A 55 -13.780 -6.179 -45.936 1.00 56.10 C
+ANISOU 392 C GLY A 55 6459 8774 6082 -306 -121 151 C
+ATOM 393 O GLY A 55 -14.982 -5.983 -45.681 1.00 60.55 O
+ANISOU 393 O GLY A 55 6840 9527 6637 -318 -183 180 O
+ATOM 394 N SER A 56 -13.181 -7.362 -45.781 1.00 52.30 N
+ANISOU 394 N SER A 56 6161 8128 5583 -472 -54 -60 N
+ATOM 395 CA SER A 56 -13.909 -8.555 -45.414 1.00 56.19 C
+ANISOU 395 CA SER A 56 6669 8647 6032 -704 -41 -291 C
+ATOM 396 C SER A 56 -13.104 -9.443 -44.480 1.00 53.82 C
+ANISOU 396 C SER A 56 6589 7981 5876 -764 94 -420 C
+ATOM 397 O SER A 56 -11.877 -9.347 -44.370 1.00 54.78 O
+ANISOU 397 O SER A 56 6852 7882 6078 -658 162 -364 O
+ATOM 398 CB SER A 56 -14.330 -9.330 -46.692 1.00 60.27 C
+ANISOU 398 CB SER A 56 7153 9473 6272 -904 -92 -449 C
+ATOM 399 OG SER A 56 -13.185 -9.640 -47.492 1.00 64.49 O
+ANISOU 399 OG SER A 56 7867 9923 6713 -890 -21 -484 O
+ATOM 400 N VAL A 57 -13.818 -10.317 -43.788 1.00 57.62 N
+ANISOU 400 N VAL A 57 7081 8413 6396 -929 142 -574 N
+ATOM 401 CA VAL A 57 -13.221 -11.309 -42.892 1.00 53.60 C
+ANISOU 401 CA VAL A 57 6773 7581 6008 -986 293 -680 C
+ATOM 402 C VAL A 57 -13.972 -12.587 -43.112 1.00 55.21 C
+ANISOU 402 C VAL A 57 7008 7830 6138 -1256 368 -912 C
+ATOM 403 O VAL A 57 -15.069 -12.588 -43.684 1.00 53.95 O
+ANISOU 403 O VAL A 57 6676 7964 5858 -1404 275 -989 O
+ATOM 404 CB VAL A 57 -13.373 -10.956 -41.381 1.00 57.18 C
+ANISOU 404 CB VAL A 57 7224 7857 6644 -880 320 -596 C
+ATOM 405 CG1 VAL A 57 -12.463 -9.803 -41.015 1.00 52.19 C
+ANISOU 405 CG1 VAL A 57 6602 7118 6107 -653 277 -417 C
+ATOM 406 CG2 VAL A 57 -14.834 -10.627 -41.047 1.00 53.61 C
+ANISOU 406 CG2 VAL A 57 6573 7599 6197 -936 258 -594 C
+ATOM 407 N ASP A 58 -13.366 -13.666 -42.641 1.00 55.82 N
+ANISOU 407 N ASP A 58 7294 7617 6296 -1318 547 -1013 N
+ATOM 408 CA ASP A 58 -13.996 -14.957 -42.561 1.00 58.46 C
+ANISOU 408 CA ASP A 58 7701 7878 6631 -1574 687 -1233 C
+ATOM 409 C ASP A 58 -14.136 -15.223 -41.085 1.00 55.65 C
+ANISOU 409 C ASP A 58 7395 7287 6461 -1515 794 -1166 C
+ATOM 410 O ASP A 58 -13.156 -15.457 -40.418 1.00 55.05 O
+ANISOU 410 O ASP A 58 7478 6953 6484 -1367 903 -1074 O
+ATOM 411 CB ASP A 58 -13.103 -16.016 -43.188 1.00 65.76 C
+ANISOU 411 CB ASP A 58 8862 8605 7518 -1656 869 -1374 C
+ATOM 412 CG ASP A 58 -13.609 -17.451 -42.970 1.00 72.39 C
+ANISOU 412 CG ASP A 58 9833 9259 8413 -1919 1088 -1606 C
+ATOM 413 OD1 ASP A 58 -14.654 -17.719 -42.304 1.00 72.82 O
+ANISOU 413 OD1 ASP A 58 9792 9332 8542 -2058 1107 -1663 O
+ATOM 414 OD2 ASP A 58 -12.932 -18.339 -43.523 1.00 80.41 O
+ANISOU 414 OD2 ASP A 58 11056 10090 9406 -1990 1274 -1737 O
+ATOM 415 N GLN A 59 -15.358 -15.182 -40.586 1.00 59.22 N
+ANISOU 415 N GLN A 59 7695 7858 6947 -1623 763 -1198 N
+ATOM 416 CA GLN A 59 -15.612 -15.422 -39.174 1.00 62.73 C
+ANISOU 416 CA GLN A 59 8181 8107 7544 -1569 878 -1130 C
+ATOM 417 C GLN A 59 -16.694 -16.457 -38.993 1.00 65.10 C
+ANISOU 417 C GLN A 59 8454 8390 7889 -1842 1015 -1303 C
+ATOM 418 O GLN A 59 -17.576 -16.295 -38.154 1.00 66.15 O
+ANISOU 418 O GLN A 59 8471 8562 8101 -1853 1028 -1256 O
+ATOM 419 CB GLN A 59 -16.011 -14.137 -38.463 1.00 57.25 C
+ANISOU 419 CB GLN A 59 7325 7538 6889 -1378 738 -953 C
+ATOM 420 CG GLN A 59 -17.246 -13.434 -39.016 1.00 55.97 C
+ANISOU 420 CG GLN A 59 6886 7717 6661 -1449 585 -955 C
+ATOM 421 CD GLN A 59 -17.652 -12.296 -38.096 1.00 62.04 C
+ANISOU 421 CD GLN A 59 7537 8522 7511 -1245 528 -780 C
+ATOM 422 OE1 GLN A 59 -18.210 -11.269 -38.534 1.00 66.81 O
+ANISOU 422 OE1 GLN A 59 7938 9366 8079 -1159 394 -682 O
+ATOM 423 NE2 GLN A 59 -17.359 -12.461 -36.800 1.00 56.51 N
+ANISOU 423 NE2 GLN A 59 6972 7583 6913 -1150 646 -731 N
+ATOM 424 N SER A 60 -16.585 -17.512 -39.786 1.00 64.01 N
+ANISOU 424 N SER A 60 8432 8180 7707 -2067 1137 -1510 N
+ATOM 425 CA SER A 60 -17.358 -18.738 -39.660 1.00 71.88 C
+ANISOU 425 CA SER A 60 9472 9060 8776 -2367 1339 -1715 C
+ATOM 426 C SER A 60 -17.042 -19.592 -38.399 1.00 69.57 C
+ANISOU 426 C SER A 60 9386 8371 8673 -2297 1620 -1638 C
+ATOM 427 O SER A 60 -17.817 -20.492 -38.073 1.00 71.72 O
+ANISOU 427 O SER A 60 9674 8528 9048 -2526 1809 -1764 O
+ATOM 428 CB SER A 60 -17.104 -19.609 -40.916 1.00 74.82 C
+ANISOU 428 CB SER A 60 9970 9417 9042 -2615 1424 -1979 C
+ATOM 429 OG SER A 60 -15.720 -19.921 -40.981 1.00 69.57 O
+ANISOU 429 OG SER A 60 9563 8467 8400 -2430 1560 -1910 O
+ATOM 430 N ASP A 61 -15.919 -19.358 -37.720 1.00 66.51 N
+ANISOU 430 N ASP A 61 9149 7790 8330 -1996 1657 -1429 N
+ATOM 431 CA ASP A 61 -15.690 -19.995 -36.412 1.00 71.53 C
+ANISOU 431 CA ASP A 61 9937 8131 9109 -1878 1886 -1294 C
+ATOM 432 C ASP A 61 -16.401 -19.243 -35.270 1.00 70.72 C
+ANISOU 432 C ASP A 61 9687 8145 9037 -1762 1797 -1144 C
+ATOM 433 O ASP A 61 -16.415 -19.738 -34.176 1.00 76.22 O
+ANISOU 433 O ASP A 61 10486 8652 9822 -1683 1980 -1036 O
+ATOM 434 CB ASP A 61 -14.215 -20.094 -36.049 1.00 71.97 C
+ANISOU 434 CB ASP A 61 10185 7978 9182 -1596 1957 -1113 C
+ATOM 435 CG ASP A 61 -13.386 -20.780 -37.089 1.00 73.12 C
+ANISOU 435 CG ASP A 61 10490 7983 9309 -1651 2076 -1223 C
+ATOM 436 OD1 ASP A 61 -13.929 -21.468 -37.992 1.00 83.53 O
+ANISOU 436 OD1 ASP A 61 11838 9288 10611 -1938 2174 -1474 O
+ATOM 437 OD2 ASP A 61 -12.154 -20.643 -36.976 1.00 81.02 O
+ANISOU 437 OD2 ASP A 61 11586 8889 10308 -1407 2081 -1062 O
+ATOM 438 N GLN A 62 -16.979 -18.058 -35.515 1.00 72.21 N
+ANISOU 438 N GLN A 62 9647 8639 9149 -1733 1544 -1123 N
+ATOM 439 CA GLN A 62 -17.756 -17.359 -34.476 1.00 67.75 C
+ANISOU 439 CA GLN A 62 8946 8173 8619 -1633 1498 -1004 C
+ATOM 440 C GLN A 62 -19.164 -17.942 -34.377 1.00 73.09 C
+ANISOU 440 C GLN A 62 9484 8914 9371 -1894 1611 -1123 C
+ATOM 441 O GLN A 62 -19.705 -18.425 -35.366 1.00 70.89 O
+ANISOU 441 O GLN A 62 9116 8743 9073 -2166 1602 -1315 O
+ATOM 442 CB GLN A 62 -17.867 -15.838 -34.717 1.00 66.80 C
+ANISOU 442 CB GLN A 62 8639 8319 8422 -1477 1233 -915 C
+ATOM 443 CG GLN A 62 -19.034 -15.338 -35.614 1.00 67.21 C
+ANISOU 443 CG GLN A 62 8412 8696 8428 -1635 1083 -998 C
+ATOM 444 CD GLN A 62 -20.329 -14.964 -34.874 1.00 64.99 C
+ANISOU 444 CD GLN A 62 7928 8548 8214 -1649 1104 -947 C
+ATOM 445 OE1 GLN A 62 -20.304 -14.340 -33.806 1.00 71.34 O
+ANISOU 445 OE1 GLN A 62 8759 9285 9059 -1444 1131 -808 O
+ATOM 446 NE2 GLN A 62 -21.471 -15.281 -35.476 1.00 63.47 N
+ANISOU 446 NE2 GLN A 62 7516 8576 8024 -1892 1085 -1063 N
+ATOM 447 N SER A 63 -19.742 -17.884 -33.174 1.00 72.66 N
+ANISOU 447 N SER A 63 9406 8808 9392 -1819 1719 -1013 N
+ATOM 448 CA SER A 63 -21.142 -18.244 -32.958 1.00 72.40 C
+ANISOU 448 CA SER A 63 9193 8866 9449 -2039 1821 -1088 C
+ATOM 449 C SER A 63 -21.984 -17.121 -32.341 1.00 66.69 C
+ANISOU 449 C SER A 63 8251 8365 8723 -1899 1711 -963 C
+ATOM 450 O SER A 63 -23.178 -17.067 -32.599 1.00 77.64 O
+ANISOU 450 O SER A 63 9385 9960 10154 -2074 1693 -1026 O
+ATOM 451 CB SER A 63 -21.277 -19.527 -32.118 1.00 70.17 C
+ANISOU 451 CB SER A 63 9088 8272 9301 -2138 2157 -1089 C
+ATOM 452 OG SER A 63 -20.352 -19.523 -31.051 1.00 76.40 O
+ANISOU 452 OG SER A 63 10101 8853 10075 -1847 2253 -890 O
+ATOM 453 N PHE A 64 -21.393 -16.238 -31.540 1.00 58.38 N
+ANISOU 453 N PHE A 64 7282 7276 7622 -1597 1650 -796 N
+ATOM 454 CA PHE A 64 -22.194 -15.361 -30.713 1.00 54.39 C
+ANISOU 454 CA PHE A 64 6633 6895 7136 -1461 1643 -686 C
+ATOM 455 C PHE A 64 -23.087 -14.381 -31.501 1.00 58.70 C
+ANISOU 455 C PHE A 64 6865 7765 7673 -1486 1455 -693 C
+ATOM 456 O PHE A 64 -24.182 -14.086 -31.039 1.00 57.54 O
+ANISOU 456 O PHE A 64 6527 7742 7591 -1488 1516 -644 O
+ATOM 457 CB PHE A 64 -21.262 -14.595 -29.755 1.00 55.93 C
+ANISOU 457 CB PHE A 64 7010 6983 7257 -1156 1611 -549 C
+ATOM 458 CG PHE A 64 -21.972 -13.594 -28.871 1.00 56.33 C
+ANISOU 458 CG PHE A 64 6960 7132 7311 -994 1624 -455 C
+ATOM 459 CD1 PHE A 64 -22.478 -13.970 -27.623 1.00 51.74 C
+ANISOU 459 CD1 PHE A 64 6445 6457 6754 -951 1839 -390 C
+ATOM 460 CD2 PHE A 64 -22.149 -12.275 -29.292 1.00 59.73 C
+ANISOU 460 CD2 PHE A 64 7237 7734 7723 -872 1452 -423 C
+ATOM 461 CE1 PHE A 64 -23.090 -13.031 -26.810 1.00 57.92 C
+ANISOU 461 CE1 PHE A 64 7159 7319 7527 -791 1874 -316 C
+ATOM 462 CE2 PHE A 64 -22.810 -11.337 -28.484 1.00 60.57 C
+ANISOU 462 CE2 PHE A 64 7268 7898 7848 -710 1505 -344 C
+ATOM 463 CZ PHE A 64 -23.289 -11.715 -27.242 1.00 54.75 C
+ANISOU 463 CZ PHE A 64 6607 7070 7122 -674 1715 -302 C
+ATOM 464 N LEU A 65 -22.629 -13.842 -32.646 1.00 59.31 N
+ANISOU 464 N LEU A 65 6879 7987 7667 -1474 1243 -724 N
+ATOM 465 CA LEU A 65 -23.379 -12.775 -33.374 1.00 63.23 C
+ANISOU 465 CA LEU A 65 7079 8808 8137 -1426 1064 -668 C
+ATOM 466 C LEU A 65 -24.616 -13.283 -34.188 1.00 65.16 C
+ANISOU 466 C LEU A 65 7020 9342 8393 -1708 1030 -770 C
+ATOM 467 O LEU A 65 -24.516 -14.329 -34.834 1.00 64.66 O
+ANISOU 467 O LEU A 65 7003 9259 8302 -1976 1052 -946 O
+ATOM 468 CB LEU A 65 -22.421 -11.920 -34.276 1.00 63.03 C
+ANISOU 468 CB LEU A 65 7095 8842 8010 -1279 864 -623 C
+ATOM 469 CG LEU A 65 -21.294 -11.083 -33.600 1.00 62.01 C
+ANISOU 469 CG LEU A 65 7179 8506 7874 -1004 852 -518 C
+ATOM 470 CD1 LEU A 65 -20.274 -10.486 -34.575 1.00 60.47 C
+ANISOU 470 CD1 LEU A 65 7035 8338 7604 -917 691 -493 C
+ATOM 471 CD2 LEU A 65 -21.842 -9.965 -32.731 1.00 60.62 C
+ANISOU 471 CD2 LEU A 65 6923 8352 7758 -795 888 -391 C
+ATOM 472 N ASP A 66 -25.764 -12.554 -34.051 1.00 69.31 N
+ANISOU 472 N ASP A 66 7243 10123 8968 -1644 999 -661 N
+ATOM 473 CA ASP A 66 -27.047 -12.615 -34.848 1.00 72.82 C
+ANISOU 473 CA ASP A 66 7291 10968 9408 -1843 905 -692 C
+ATOM 474 C ASP A 66 -26.639 -12.271 -36.317 1.00 77.46 C
+ANISOU 474 C ASP A 66 7794 11812 9825 -1871 656 -723 C
+ATOM 475 O ASP A 66 -25.716 -11.438 -36.541 1.00 65.69 O
+ANISOU 475 O ASP A 66 6447 10241 8269 -1624 566 -617 O
+ATOM 476 CB ASP A 66 -28.090 -11.511 -34.364 1.00 77.64 C
+ANISOU 476 CB ASP A 66 7609 11789 10101 -1619 914 -476 C
+ATOM 477 CG ASP A 66 -29.226 -12.030 -33.407 1.00 93.62 C
+ANISOU 477 CG ASP A 66 9481 13808 12279 -1733 1126 -471 C
+ATOM 478 OD1 ASP A 66 -29.080 -13.108 -32.793 1.00106.10 O
+ANISOU 478 OD1 ASP A 66 11255 15134 13923 -1914 1308 -596 O
+ATOM 479 OD2 ASP A 66 -30.299 -11.343 -33.266 1.00 93.76 O
+ANISOU 479 OD2 ASP A 66 9173 14081 12368 -1624 1134 -319 O
+ATOM 480 N ASP A 67 -27.292 -12.872 -37.323 1.00 79.83 N
+ANISOU 480 N ASP A 67 7864 12428 10039 -2173 549 -870 N
+ATOM 481 CA ASP A 67 -26.991 -12.525 -38.711 1.00 83.48 C
+ANISOU 481 CA ASP A 67 8232 13188 10299 -2190 314 -888 C
+ATOM 482 C ASP A 67 -27.305 -11.060 -38.958 1.00 81.61 C
+ANISOU 482 C ASP A 67 7760 13217 10028 -1857 174 -603 C
+ATOM 483 O ASP A 67 -26.634 -10.428 -39.777 1.00 81.48 O
+ANISOU 483 O ASP A 67 7791 13288 9878 -1705 34 -521 O
+ATOM 484 CB ASP A 67 -27.780 -13.356 -39.743 1.00 99.82 C
+ANISOU 484 CB ASP A 67 10050 15632 12243 -2589 204 -1107 C
+ATOM 485 CG ASP A 67 -27.453 -14.842 -39.701 1.00102.82 C
+ANISOU 485 CG ASP A 67 10677 15732 12655 -2952 367 -1422 C
+ATOM 486 OD1 ASP A 67 -26.299 -15.215 -39.353 1.00102.93 O
+ANISOU 486 OD1 ASP A 67 11082 15321 12706 -2872 499 -1465 O
+ATOM 487 OD2 ASP A 67 -28.380 -15.622 -40.029 1.00 94.69 O
+ANISOU 487 OD2 ASP A 67 9430 14922 11623 -3321 370 -1619 O
+ATOM 488 N GLU A 68 -28.313 -10.508 -38.287 1.00 76.33 N
+ANISOU 488 N GLU A 68 6842 12669 9490 -1729 236 -436 N
+ATOM 489 CA GLU A 68 -28.488 -9.053 -38.331 1.00 87.60 C
+ANISOU 489 CA GLU A 68 8114 14233 10935 -1350 179 -137 C
+ATOM 490 C GLU A 68 -27.140 -8.357 -37.951 1.00 89.20 C
+ANISOU 490 C GLU A 68 8695 14033 11161 -1073 233 -65 C
+ATOM 491 O GLU A 68 -26.669 -7.443 -38.628 1.00 88.13 O
+ANISOU 491 O GLU A 68 8554 13978 10954 -862 128 85 O
+ATOM 492 CB GLU A 68 -29.608 -8.602 -37.395 1.00 95.60 C
+ANISOU 492 CB GLU A 68 8892 15305 12126 -1215 319 23 C
+ATOM 493 CG GLU A 68 -29.735 -7.087 -37.282 1.00104.83 C
+ANISOU 493 CG GLU A 68 9958 16515 13354 -793 334 332 C
+ATOM 494 CD GLU A 68 -30.926 -6.636 -36.439 1.00115.12 C
+ANISOU 494 CD GLU A 68 11001 17904 14832 -647 495 501 C
+ATOM 495 OE1 GLU A 68 -31.956 -7.348 -36.393 1.00115.20 O
+ANISOU 495 OE1 GLU A 68 10727 18166 14878 -878 505 440 O
+ATOM 496 OE2 GLU A 68 -30.828 -5.546 -35.827 1.00115.96 O
+ANISOU 496 OE2 GLU A 68 11189 17821 15050 -303 630 690 O
+ATOM 497 N GLN A 69 -26.519 -8.821 -36.871 1.00 84.99 N
+ANISOU 497 N GLN A 69 8479 13084 10727 -1087 401 -169 N
+ATOM 498 CA GLN A 69 -25.278 -8.246 -36.383 1.00 74.41 C
+ANISOU 498 CA GLN A 69 7470 11389 9412 -867 450 -126 C
+ATOM 499 C GLN A 69 -24.113 -8.417 -37.351 1.00 73.31 C
+ANISOU 499 C GLN A 69 7506 11209 9139 -912 323 -199 C
+ATOM 500 O GLN A 69 -23.352 -7.485 -37.533 1.00 68.06 O
+ANISOU 500 O GLN A 69 6940 10450 8469 -692 283 -80 O
+ATOM 501 CB GLN A 69 -24.929 -8.815 -34.993 1.00 71.55 C
+ANISOU 501 CB GLN A 69 7378 10660 9148 -886 645 -216 C
+ATOM 502 CG GLN A 69 -25.865 -8.310 -33.913 1.00 72.95 C
+ANISOU 502 CG GLN A 69 7442 10823 9452 -746 799 -105 C
+ATOM 503 CD GLN A 69 -25.579 -8.891 -32.535 1.00 72.43 C
+ANISOU 503 CD GLN A 69 7636 10439 9442 -758 996 -178 C
+ATOM 504 OE1 GLN A 69 -25.227 -10.079 -32.369 1.00 64.31 O
+ANISOU 504 OE1 GLN A 69 6765 9275 8394 -961 1053 -316 O
+ATOM 505 NE2 GLN A 69 -25.737 -8.050 -31.530 1.00 72.76 N
+ANISOU 505 NE2 GLN A 69 7734 10360 9548 -530 1119 -79 N
+ATOM 506 N ILE A 70 -23.969 -9.589 -37.964 1.00 78.29 N
+ANISOU 506 N ILE A 70 8181 11890 9673 -1199 285 -397 N
+ATOM 507 CA ILE A 70 -22.959 -9.783 -39.017 1.00 75.81 C
+ANISOU 507 CA ILE A 70 8009 11579 9215 -1247 178 -469 C
+ATOM 508 C ILE A 70 -23.247 -8.950 -40.279 1.00 80.31 C
+ANISOU 508 C ILE A 70 8337 12536 9640 -1154 -9 -332 C
+ATOM 509 O ILE A 70 -22.334 -8.336 -40.829 1.00 79.77 O
+ANISOU 509 O ILE A 70 8384 12414 9511 -993 -67 -242 O
+ATOM 510 CB ILE A 70 -22.818 -11.250 -39.409 1.00 73.74 C
+ANISOU 510 CB ILE A 70 7859 11274 8884 -1583 218 -732 C
+ATOM 511 CG1 ILE A 70 -22.302 -12.031 -38.193 1.00 70.17 C
+ANISOU 511 CG1 ILE A 70 7687 10403 8571 -1612 426 -812 C
+ATOM 512 CG2 ILE A 70 -21.890 -11.368 -40.629 1.00 69.89 C
+ANISOU 512 CG2 ILE A 70 7488 10843 8223 -1620 113 -800 C
+ATOM 513 CD1 ILE A 70 -22.178 -13.529 -38.421 1.00 73.86 C
+ANISOU 513 CD1 ILE A 70 8298 10742 9024 -1925 541 -1055 C
+ATOM 514 N GLY A 71 -24.501 -8.934 -40.720 1.00 80.29 N
+ANISOU 514 N GLY A 71 7989 12934 9582 -1249 -96 -298 N
+ATOM 515 CA GLY A 71 -24.945 -8.065 -41.782 1.00 84.25 C
+ANISOU 515 CA GLY A 71 8211 13855 9944 -1113 -267 -106 C
+ATOM 516 C GLY A 71 -24.627 -6.587 -41.543 1.00 90.55 C
+ANISOU 516 C GLY A 71 9018 14542 10843 -709 -231 194 C
+ATOM 517 O GLY A 71 -24.287 -5.858 -42.499 1.00 81.85 O
+ANISOU 517 O GLY A 71 7861 13613 9622 -547 -332 358 O
+ATOM 518 N GLU A 72 -24.732 -6.122 -40.290 1.00 85.84 N
+ANISOU 518 N GLU A 72 8502 13652 10461 -547 -67 267 N
+ATOM 519 CA GLU A 72 -24.363 -4.720 -39.956 1.00 84.90 C
+ANISOU 519 CA GLU A 72 8443 13349 10466 -189 11 507 C
+ATOM 520 C GLU A 72 -22.834 -4.496 -39.871 1.00 78.13 C
+ANISOU 520 C GLU A 72 7942 12117 9627 -119 45 456 C
+ATOM 521 O GLU A 72 -22.372 -3.347 -39.798 1.00 75.56 O
+ANISOU 521 O GLU A 72 7680 11635 9392 134 104 627 O
+ATOM 522 CB GLU A 72 -25.091 -4.227 -38.684 1.00 90.04 C
+ANISOU 522 CB GLU A 72 9044 13847 11319 -41 188 589 C
+ATOM 523 CG GLU A 72 -26.571 -3.883 -38.951 1.00104.52 C
+ANISOU 523 CG GLU A 72 10456 16088 13168 32 166 776 C
+ATOM 524 CD GLU A 72 -27.484 -3.868 -37.708 1.00115.41 C
+ANISOU 524 CD GLU A 72 11754 17371 14724 75 350 790 C
+ATOM 525 OE1 GLU A 72 -27.080 -4.369 -36.632 1.00119.16 O
+ANISOU 525 OE1 GLU A 72 12496 17503 15276 -13 480 617 O
+ATOM 526 OE2 GLU A 72 -28.638 -3.366 -37.807 1.00117.96 O
+ANISOU 526 OE2 GLU A 72 11730 17986 15102 210 373 993 O
+ATOM 527 N GLY A 73 -22.058 -5.585 -39.875 1.00 67.33 N
+ANISOU 527 N GLY A 73 6793 10600 8189 -345 28 226 N
+ATOM 528 CA GLY A 73 -20.599 -5.498 -39.918 1.00 67.28 C
+ANISOU 528 CA GLY A 73 7077 10299 8185 -298 44 183 C
+ATOM 529 C GLY A 73 -19.821 -5.908 -38.667 1.00 62.16 C
+ANISOU 529 C GLY A 73 6708 9260 7648 -326 164 53 C
+ATOM 530 O GLY A 73 -18.585 -5.771 -38.638 1.00 63.30 O
+ANISOU 530 O GLY A 73 7062 9181 7806 -276 171 35 O
+ATOM 531 N PHE A 74 -20.506 -6.407 -37.635 1.00 54.21 N
+ANISOU 531 N PHE A 74 5695 8188 6714 -400 259 -21 N
+ATOM 532 CA PHE A 74 -19.813 -6.733 -36.379 1.00 50.47 C
+ANISOU 532 CA PHE A 74 5476 7384 6317 -394 373 -110 C
+ATOM 533 C PHE A 74 -19.017 -7.976 -36.610 1.00 48.37 C
+ANISOU 533 C PHE A 74 5385 7015 5978 -577 371 -263 C
+ATOM 534 O PHE A 74 -19.389 -8.786 -37.447 1.00 48.97 O
+ANISOU 534 O PHE A 74 5379 7259 5968 -764 327 -353 O
+ATOM 535 CB PHE A 74 -20.762 -6.849 -35.179 1.00 51.93 C
+ANISOU 535 CB PHE A 74 5616 7527 6587 -388 503 -119 C
+ATOM 536 CG PHE A 74 -21.382 -5.561 -34.825 1.00 54.65 C
+ANISOU 536 CG PHE A 74 5836 7903 7023 -170 553 31 C
+ATOM 537 CD1 PHE A 74 -20.611 -4.556 -34.263 1.00 59.00 C
+ANISOU 537 CD1 PHE A 74 6552 8226 7638 12 602 74 C
+ATOM 538 CD2 PHE A 74 -22.705 -5.309 -35.097 1.00 62.03 C
+ANISOU 538 CD2 PHE A 74 6482 9097 7988 -145 562 133 C
+ATOM 539 CE1 PHE A 74 -21.141 -3.312 -33.970 1.00 61.30 C
+ANISOU 539 CE1 PHE A 74 6759 8497 8034 221 689 205 C
+ATOM 540 CE2 PHE A 74 -23.278 -4.074 -34.762 1.00 65.97 C
+ANISOU 540 CE2 PHE A 74 6870 9599 8593 96 649 300 C
+ATOM 541 CZ PHE A 74 -22.481 -3.064 -34.213 1.00 69.36 C
+ANISOU 541 CZ PHE A 74 7503 9751 9097 283 726 331 C
+ATOM 542 N VAL A 75 -17.889 -8.074 -35.901 1.00 48.27 N
+ANISOU 542 N VAL A 75 5608 6737 5995 -517 420 -290 N
+ATOM 543 CA VAL A 75 -16.947 -9.203 -35.999 1.00 47.38 C
+ANISOU 543 CA VAL A 75 5685 6480 5837 -632 453 -395 C
+ATOM 544 C VAL A 75 -16.430 -9.520 -34.615 1.00 49.15 C
+ANISOU 544 C VAL A 75 6091 6473 6108 -575 558 -404 C
+ATOM 545 O VAL A 75 -16.248 -8.629 -33.798 1.00 47.13 O
+ANISOU 545 O VAL A 75 5866 6148 5892 -428 559 -343 O
+ATOM 546 CB VAL A 75 -15.775 -8.834 -36.956 1.00 48.33 C
+ANISOU 546 CB VAL A 75 5867 6583 5911 -571 365 -359 C
+ATOM 547 CG1 VAL A 75 -15.079 -7.549 -36.507 1.00 49.98 C
+ANISOU 547 CG1 VAL A 75 6112 6686 6192 -372 333 -248 C
+ATOM 548 CG2 VAL A 75 -14.782 -9.929 -37.088 1.00 49.25 C
+ANISOU 548 CG2 VAL A 75 6167 6549 5995 -653 422 -442 C
+ATOM 549 N LEU A 76 -16.184 -10.794 -34.355 1.00 49.57 N
+ANISOU 549 N LEU A 76 6273 6411 6149 -688 660 -479 N
+ATOM 550 CA LEU A 76 -15.521 -11.198 -33.153 1.00 47.93 C
+ANISOU 550 CA LEU A 76 6243 6013 5953 -611 755 -452 C
+ATOM 551 C LEU A 76 -14.098 -11.431 -33.507 1.00 45.41 C
+ANISOU 551 C LEU A 76 6054 5590 5609 -559 721 -432 C
+ATOM 552 O LEU A 76 -13.751 -12.422 -34.211 1.00 46.04 O
+ANISOU 552 O LEU A 76 6200 5615 5676 -659 783 -486 O
+ATOM 553 CB LEU A 76 -16.177 -12.472 -32.551 1.00 49.85 C
+ANISOU 553 CB LEU A 76 6545 6174 6220 -737 935 -501 C
+ATOM 554 CG LEU A 76 -17.619 -12.228 -32.105 1.00 52.45 C
+ANISOU 554 CG LEU A 76 6721 6616 6591 -787 985 -507 C
+ATOM 555 CD1 LEU A 76 -18.258 -13.483 -31.561 1.00 56.78 C
+ANISOU 555 CD1 LEU A 76 7318 7068 7185 -930 1185 -551 C
+ATOM 556 CD2 LEU A 76 -17.640 -11.190 -31.039 1.00 52.12 C
+ANISOU 556 CD2 LEU A 76 6691 6565 6545 -599 972 -426 C
+ATOM 557 N THR A 77 -13.248 -10.565 -32.967 1.00 46.19 N
+ANISOU 557 N THR A 77 6193 5650 5705 -409 646 -365 N
+ATOM 558 CA THR A 77 -11.875 -10.505 -33.442 1.00 42.15 C
+ANISOU 558 CA THR A 77 5743 5084 5186 -350 586 -327 C
+ATOM 559 C THR A 77 -11.098 -11.716 -33.100 1.00 45.26 C
+ANISOU 559 C THR A 77 6277 5354 5565 -343 692 -303 C
+ATOM 560 O THR A 77 -10.095 -11.997 -33.772 1.00 50.56 O
+ANISOU 560 O THR A 77 6987 5982 6241 -320 686 -277 O
+ATOM 561 CB THR A 77 -11.139 -9.239 -32.928 1.00 47.57 C
+ANISOU 561 CB THR A 77 6417 5768 5889 -225 479 -279 C
+ATOM 562 OG1 THR A 77 -11.277 -9.041 -31.498 1.00 46.78 O
+ANISOU 562 OG1 THR A 77 6374 5641 5757 -165 507 -279 O
+ATOM 563 CG2 THR A 77 -11.677 -8.033 -33.637 1.00 44.69 C
+ANISOU 563 CG2 THR A 77 5923 5486 5568 -210 405 -272 C
+ATOM 564 N CYS A 78 -11.496 -12.435 -32.033 1.00 50.28 N
+ANISOU 564 N CYS A 78 6990 5924 6188 -338 814 -286 N
+ATOM 565 CA CYS A 78 -10.739 -13.646 -31.587 1.00 46.96 C
+ANISOU 565 CA CYS A 78 6711 5367 5761 -289 955 -214 C
+ATOM 566 C CYS A 78 -11.053 -14.787 -32.559 1.00 49.46 C
+ANISOU 566 C CYS A 78 7079 5587 6126 -435 1104 -293 C
+ATOM 567 O CYS A 78 -10.411 -15.828 -32.559 1.00 51.48 O
+ANISOU 567 O CYS A 78 7458 5693 6407 -405 1257 -244 O
+ATOM 568 CB CYS A 78 -11.178 -14.092 -30.182 1.00 53.40 C
+ANISOU 568 CB CYS A 78 7600 6145 6541 -234 1071 -151 C
+ATOM 569 SG CYS A 78 -12.881 -14.758 -30.242 1.00 51.94 S
+ANISOU 569 SG CYS A 78 7387 5928 6417 -420 1238 -249 S
+ATOM 570 N ALA A 79 -12.058 -14.598 -33.405 1.00 53.34 N
+ANISOU 570 N ALA A 79 7469 6170 6626 -598 1068 -418 N
+ATOM 571 CA ALA A 79 -12.515 -15.685 -34.236 1.00 55.83 C
+ANISOU 571 CA ALA A 79 7829 6416 6967 -787 1210 -543 C
+ATOM 572 C ALA A 79 -12.550 -15.316 -35.744 1.00 59.35 C
+ANISOU 572 C ALA A 79 8188 7002 7360 -894 1092 -650 C
+ATOM 573 O ALA A 79 -13.139 -16.061 -36.535 1.00 55.41 O
+ANISOU 573 O ALA A 79 7693 6513 6847 -1099 1172 -802 O
+ATOM 574 CB ALA A 79 -13.912 -16.109 -33.759 1.00 59.21 C
+ANISOU 574 CB ALA A 79 8205 6858 7433 -940 1313 -616 C
+ATOM 575 N ALA A 80 -11.913 -14.208 -36.131 1.00 51.54 N
+ANISOU 575 N ALA A 80 7126 6121 6335 -767 917 -576 N
+ATOM 576 CA ALA A 80 -12.025 -13.689 -37.496 1.00 52.60 C
+ANISOU 576 CA ALA A 80 7161 6426 6398 -833 799 -635 C
+ATOM 577 C ALA A 80 -10.641 -13.659 -38.187 1.00 52.00 C
+ANISOU 577 C ALA A 80 7168 6282 6305 -734 797 -581 C
+ATOM 578 O ALA A 80 -9.618 -13.161 -37.620 1.00 49.22 O
+ANISOU 578 O ALA A 80 6840 5858 6002 -561 760 -450 O
+ATOM 579 CB ALA A 80 -12.672 -12.314 -37.499 1.00 53.13 C
+ANISOU 579 CB ALA A 80 7044 6690 6453 -769 627 -571 C
+ATOM 580 N TYR A 81 -10.617 -14.269 -39.382 1.00 50.25 N
+ANISOU 580 N TYR A 81 6991 6091 6011 -860 853 -698 N
+ATOM 581 CA TYR A 81 -9.473 -14.232 -40.301 1.00 47.17 C
+ANISOU 581 CA TYR A 81 6664 5673 5582 -786 868 -665 C
+ATOM 582 C TYR A 81 -9.695 -13.111 -41.287 1.00 50.29 C
+ANISOU 582 C TYR A 81 6913 6311 5882 -771 694 -634 C
+ATOM 583 O TYR A 81 -10.787 -12.986 -41.832 1.00 51.07 O
+ANISOU 583 O TYR A 81 6906 6613 5885 -903 620 -722 O
+ATOM 584 CB TYR A 81 -9.426 -15.493 -41.146 1.00 51.08 C
+ANISOU 584 CB TYR A 81 7306 6080 6021 -943 1048 -833 C
+ATOM 585 CG TYR A 81 -9.189 -16.735 -40.354 1.00 58.36 C
+ANISOU 585 CG TYR A 81 8398 6724 7050 -954 1282 -854 C
+ATOM 586 CD1 TYR A 81 -8.089 -16.833 -39.537 1.00 55.81 C
+ANISOU 586 CD1 TYR A 81 8143 6231 6829 -740 1353 -672 C
+ATOM 587 CD2 TYR A 81 -10.088 -17.800 -40.389 1.00 63.94 C
+ANISOU 587 CD2 TYR A 81 9183 7347 7763 -1179 1441 -1042 C
+ATOM 588 CE1 TYR A 81 -7.853 -17.958 -38.801 1.00 58.92 C
+ANISOU 588 CE1 TYR A 81 8687 6381 7317 -708 1583 -641 C
+ATOM 589 CE2 TYR A 81 -9.854 -18.945 -39.642 1.00 66.35 C
+ANISOU 589 CE2 TYR A 81 9659 7359 8190 -1168 1700 -1029 C
+ATOM 590 CZ TYR A 81 -8.713 -19.009 -38.869 1.00 60.72 C
+ANISOU 590 CZ TYR A 81 9018 6485 7566 -910 1772 -810 C
+ATOM 591 OH TYR A 81 -8.409 -20.106 -38.119 1.00 67.42 O
+ANISOU 591 OH TYR A 81 10026 7058 8530 -846 2038 -740 O
+ATOM 592 N PRO A 82 -8.665 -12.297 -41.547 1.00 49.08 N
+ANISOU 592 N PRO A 82 6740 6152 5756 -609 636 -494 N
+ATOM 593 CA PRO A 82 -8.810 -11.345 -42.651 1.00 47.57 C
+ANISOU 593 CA PRO A 82 6433 6172 5466 -585 518 -444 C
+ATOM 594 C PRO A 82 -8.910 -12.091 -43.994 1.00 51.19 C
+ANISOU 594 C PRO A 82 6956 6741 5751 -719 580 -581 C
+ATOM 595 O PRO A 82 -8.241 -13.098 -44.143 1.00 50.40 O
+ANISOU 595 O PRO A 82 7018 6474 5657 -755 739 -662 O
+ATOM 596 CB PRO A 82 -7.518 -10.563 -42.588 1.00 45.77 C
+ANISOU 596 CB PRO A 82 6205 5851 5335 -407 504 -279 C
+ATOM 597 CG PRO A 82 -6.511 -11.495 -41.974 1.00 47.02 C
+ANISOU 597 CG PRO A 82 6497 5788 5579 -368 638 -280 C
+ATOM 598 CD PRO A 82 -7.288 -12.383 -41.033 1.00 48.95 C
+ANISOU 598 CD PRO A 82 6803 5951 5844 -460 702 -380 C
+ATOM 599 N THR A 83 -9.757 -11.627 -44.924 1.00 48.49 N
+ANISOU 599 N THR A 83 6489 6685 5247 -788 466 -606 N
+ATOM 600 CA THR A 83 -9.762 -12.153 -46.307 1.00 51.50 C
+ANISOU 600 CA THR A 83 6925 7231 5411 -907 499 -734 C
+ATOM 601 C THR A 83 -9.429 -11.095 -47.342 1.00 49.00 C
+ANISOU 601 C THR A 83 6517 7124 4975 -771 406 -571 C
+ATOM 602 O THR A 83 -9.557 -11.323 -48.533 1.00 50.94 O
+ANISOU 602 O THR A 83 6777 7584 4992 -851 400 -650 O
+ATOM 603 CB THR A 83 -11.157 -12.749 -46.647 1.00 56.46 C
+ANISOU 603 CB THR A 83 7475 8093 5884 -1158 444 -940 C
+ATOM 604 OG1 THR A 83 -12.178 -11.809 -46.291 1.00 57.08 O
+ANISOU 604 OG1 THR A 83 7322 8384 5979 -1111 275 -821 O
+ATOM 605 CG2 THR A 83 -11.377 -14.007 -45.846 1.00 57.41 C
+ANISOU 605 CG2 THR A 83 7729 7967 6115 -1324 602 -1126 C
+ATOM 606 N SER A 84 -9.123 -9.892 -46.868 1.00 49.80 N
+ANISOU 606 N SER A 84 6516 7183 5220 -575 335 -345 N
+ATOM 607 CA SER A 84 -8.642 -8.809 -47.689 1.00 51.09 C
+ANISOU 607 CA SER A 84 6609 7464 5339 -413 295 -145 C
+ATOM 608 C SER A 84 -8.017 -7.870 -46.668 1.00 49.54 C
+ANISOU 608 C SER A 84 6376 7040 5405 -251 294 24 C
+ATOM 609 O SER A 84 -8.128 -8.093 -45.490 1.00 47.99 O
+ANISOU 609 O SER A 84 6201 6679 5354 -276 298 -28 O
+ATOM 610 CB SER A 84 -9.795 -8.069 -48.389 1.00 56.08 C
+ANISOU 610 CB SER A 84 7050 8454 5800 -400 154 -60 C
+ATOM 611 OG SER A 84 -10.589 -7.330 -47.413 1.00 52.75 O
+ANISOU 611 OG SER A 84 6487 8017 5536 -337 76 32 O
+ATOM 612 N ASP A 85 -7.382 -6.806 -47.126 1.00 46.38 N
+ANISOU 612 N ASP A 85 5924 6639 5057 -96 299 222 N
+ATOM 613 CA ASP A 85 -6.983 -5.755 -46.253 1.00 49.05 C
+ANISOU 613 CA ASP A 85 6206 6797 5631 21 291 358 C
+ATOM 614 C ASP A 85 -8.286 -5.304 -45.638 1.00 50.62 C
+ANISOU 614 C ASP A 85 6295 7088 5849 14 202 357 C
+ATOM 615 O ASP A 85 -9.334 -5.212 -46.322 1.00 54.44 O
+ANISOU 615 O ASP A 85 6675 7839 6170 0 136 381 O
+ATOM 616 CB ASP A 85 -6.341 -4.609 -47.058 1.00 47.60 C
+ANISOU 616 CB ASP A 85 5967 6628 5489 170 330 579 C
+ATOM 617 CG ASP A 85 -4.900 -4.925 -47.559 1.00 52.73 C
+ANISOU 617 CG ASP A 85 6707 7157 6169 197 442 609 C
+ATOM 618 OD1 ASP A 85 -4.277 -5.936 -47.150 1.00 52.35 O
+ANISOU 618 OD1 ASP A 85 6760 6983 6148 128 494 481 O
+ATOM 619 OD2 ASP A 85 -4.368 -4.108 -48.369 1.00 56.01 O
+ANISOU 619 OD2 ASP A 85 7082 7598 6598 307 501 791 O
+ATOM 620 N VAL A 86 -8.255 -4.968 -44.377 1.00 45.98 N
+ANISOU 620 N VAL A 86 5710 6311 5446 32 200 343 N
+ATOM 621 CA VAL A 86 -9.522 -4.737 -43.682 1.00 45.59 C
+ANISOU 621 CA VAL A 86 5573 6331 5415 18 147 316 C
+ATOM 622 C VAL A 86 -9.338 -3.725 -42.597 1.00 43.07 C
+ANISOU 622 C VAL A 86 5245 5812 5305 107 169 375 C
+ATOM 623 O VAL A 86 -8.275 -3.619 -42.020 1.00 44.22 O
+ANISOU 623 O VAL A 86 5470 5760 5572 112 201 355 O
+ATOM 624 CB VAL A 86 -10.078 -6.072 -43.148 1.00 48.01 C
+ANISOU 624 CB VAL A 86 5939 6654 5647 -143 144 117 C
+ATOM 625 CG1 VAL A 86 -9.082 -6.710 -42.219 1.00 49.95 C
+ANISOU 625 CG1 VAL A 86 6328 6652 5997 -170 206 38 C
+ATOM 626 CG2 VAL A 86 -11.442 -5.939 -42.465 1.00 50.17 C
+ANISOU 626 CG2 VAL A 86 6107 7020 5936 -171 105 89 C
+ATOM 627 N THR A 87 -10.371 -2.925 -42.367 1.00 45.19 N
+ANISOU 627 N THR A 87 5406 6148 5615 181 159 451 N
+ATOM 628 CA THR A 87 -10.350 -1.923 -41.352 1.00 45.50 C
+ANISOU 628 CA THR A 87 5452 5991 5845 259 209 481 C
+ATOM 629 C THR A 87 -11.421 -2.288 -40.351 1.00 47.74 C
+ANISOU 629 C THR A 87 5716 6302 6122 213 199 378 C
+ATOM 630 O THR A 87 -12.526 -2.582 -40.730 1.00 47.10 O
+ANISOU 630 O THR A 87 5523 6431 5940 201 166 397 O
+ATOM 631 CB THR A 87 -10.656 -0.544 -41.917 1.00 50.80 C
+ANISOU 631 CB THR A 87 6025 6671 6605 425 268 690 C
+ATOM 632 OG1 THR A 87 -9.617 -0.209 -42.839 1.00 51.07 O
+ANISOU 632 OG1 THR A 87 6082 6667 6653 467 301 799 O
+ATOM 633 CG2 THR A 87 -10.675 0.502 -40.782 1.00 50.21 C
+ANISOU 633 CG2 THR A 87 5986 6346 6744 486 359 679 C
+ATOM 634 N ILE A 88 -11.062 -2.273 -39.075 1.00 47.12 N
+ANISOU 634 N ILE A 88 5735 6028 6137 183 227 271 N
+ATOM 635 CA ILE A 88 -11.915 -2.724 -38.016 1.00 47.67 C
+ANISOU 635 CA ILE A 88 5818 6102 6192 138 240 168 C
+ATOM 636 C ILE A 88 -11.927 -1.719 -36.867 1.00 42.11 C
+ANISOU 636 C ILE A 88 5161 5214 5622 206 309 145 C
+ATOM 637 O ILE A 88 -10.907 -1.494 -36.286 1.00 43.07 O
+ANISOU 637 O ILE A 88 5383 5181 5801 181 309 80 O
+ATOM 638 CB ILE A 88 -11.395 -4.068 -37.512 1.00 49.90 C
+ANISOU 638 CB ILE A 88 6214 6349 6396 13 220 34 C
+ATOM 639 CG1 ILE A 88 -11.587 -5.112 -38.628 1.00 49.65 C
+ANISOU 639 CG1 ILE A 88 6153 6480 6231 -76 191 16 C
+ATOM 640 CG2 ILE A 88 -12.108 -4.473 -36.212 1.00 51.61 C
+ANISOU 640 CG2 ILE A 88 6470 6528 6608 -19 261 -58 C
+ATOM 641 CD1 ILE A 88 -10.896 -6.432 -38.386 1.00 49.71 C
+ANISOU 641 CD1 ILE A 88 6291 6410 6186 -176 218 -87 C
+ATOM 642 N GLU A 89 -13.099 -1.193 -36.519 1.00 43.90 N
+ANISOU 642 N GLU A 89 5312 5478 5890 282 372 184 N
+ATOM 643 CA GLU A 89 -13.278 -0.421 -35.290 1.00 47.43 C
+ANISOU 643 CA GLU A 89 5831 5749 6437 331 467 118 C
+ATOM 644 C GLU A 89 -13.369 -1.368 -34.118 1.00 48.10 C
+ANISOU 644 C GLU A 89 6014 5828 6434 235 456 -33 C
+ATOM 645 O GLU A 89 -14.208 -2.238 -34.131 1.00 46.09 O
+ANISOU 645 O GLU A 89 5699 5711 6099 192 450 -38 O
+ATOM 646 CB GLU A 89 -14.570 0.378 -35.316 1.00 52.55 C
+ANISOU 646 CB GLU A 89 6361 6442 7161 470 572 230 C
+ATOM 647 CG GLU A 89 -14.633 1.492 -36.347 1.00 63.41 C
+ANISOU 647 CG GLU A 89 7637 7813 8643 621 629 431 C
+ATOM 648 CD GLU A 89 -15.842 2.407 -36.147 1.00 73.77 C
+ANISOU 648 CD GLU A 89 8843 9123 10063 800 777 562 C
+ATOM 649 OE1 GLU A 89 -16.733 2.070 -35.336 1.00 80.53 O
+ANISOU 649 OE1 GLU A 89 9673 10027 10895 795 819 497 O
+ATOM 650 OE2 GLU A 89 -15.887 3.472 -36.793 1.00 76.86 O
+ANISOU 650 OE2 GLU A 89 9175 9453 10575 962 875 747 O
+ATOM 651 N THR A 90 -12.531 -1.166 -33.102 1.00 44.70 N
+ANISOU 651 N THR A 90 5722 5248 6013 199 462 -150 N
+ATOM 652 CA THR A 90 -12.427 -2.084 -32.002 1.00 43.34 C
+ANISOU 652 CA THR A 90 5650 5087 5727 129 448 -262 C
+ATOM 653 C THR A 90 -13.337 -1.652 -30.827 1.00 47.39 C
+ANISOU 653 C THR A 90 6210 5556 6240 178 561 -329 C
+ATOM 654 O THR A 90 -13.940 -0.586 -30.855 1.00 46.89 O
+ANISOU 654 O THR A 90 6109 5423 6283 268 659 -299 O
+ATOM 655 CB THR A 90 -10.937 -2.167 -31.551 1.00 42.54 C
+ANISOU 655 CB THR A 90 5651 4917 5596 69 368 -337 C
+ATOM 656 OG1 THR A 90 -10.480 -0.884 -31.081 1.00 46.16 O
+ANISOU 656 OG1 THR A 90 6155 5238 6145 78 400 -410 O
+ATOM 657 CG2 THR A 90 -10.008 -2.601 -32.693 1.00 42.77 C
+ANISOU 657 CG2 THR A 90 5633 4980 5636 38 287 -260 C
+ATOM 658 N HIS A 91 -13.394 -2.452 -29.757 1.00 47.53 N
+ANISOU 658 N HIS A 91 6321 5601 6138 136 573 -409 N
+ATOM 659 CA HIS A 91 -14.121 -2.027 -28.523 1.00 50.54 C
+ANISOU 659 CA HIS A 91 6775 5936 6488 184 696 -488 C
+ATOM 660 C HIS A 91 -15.577 -1.689 -28.823 1.00 48.63 C
+ANISOU 660 C HIS A 91 6407 5732 6336 269 818 -403 C
+ATOM 661 O HIS A 91 -16.087 -0.683 -28.370 1.00 47.55 O
+ANISOU 661 O HIS A 91 6289 5503 6273 358 945 -426 O
+ATOM 662 CB HIS A 91 -13.449 -0.819 -27.839 1.00 53.09 C
+ANISOU 662 CB HIS A 91 7212 6116 6841 192 723 -613 C
+ATOM 663 CG HIS A 91 -12.037 -1.062 -27.377 1.00 53.84 C
+ANISOU 663 CG HIS A 91 7400 6222 6835 99 592 -706 C
+ATOM 664 ND1 HIS A 91 -10.998 -1.282 -28.245 1.00 52.95 N
+ANISOU 664 ND1 HIS A 91 7230 6124 6762 50 467 -650 N
+ATOM 665 CD2 HIS A 91 -11.494 -1.106 -26.132 1.00 56.62 C
+ANISOU 665 CD2 HIS A 91 7877 6601 7033 54 565 -841 C
+ATOM 666 CE1 HIS A 91 -9.869 -1.434 -27.568 1.00 52.38 C
+ANISOU 666 CE1 HIS A 91 7223 6088 6589 -18 367 -735 C
+ATOM 667 NE2 HIS A 91 -10.149 -1.348 -26.282 1.00 55.87 N
+ANISOU 667 NE2 HIS A 91 7774 6556 6899 -20 411 -852 N
+ATOM 668 N LYS A 92 -16.228 -2.521 -29.624 1.00 49.04 N
+ANISOU 668 N LYS A 92 6318 5927 6386 236 787 -308 N
+ATOM 669 CA LYS A 92 -17.650 -2.390 -29.844 1.00 50.58 C
+ANISOU 669 CA LYS A 92 6348 6224 6644 297 884 -219 C
+ATOM 670 C LYS A 92 -18.507 -3.326 -28.988 1.00 47.54 C
+ANISOU 670 C LYS A 92 5964 5904 6193 250 976 -250 C
+ATOM 671 O LYS A 92 -19.654 -3.503 -29.328 1.00 46.77 O
+ANISOU 671 O LYS A 92 5686 5937 6144 257 1030 -172 O
+ATOM 672 CB LYS A 92 -17.947 -2.701 -31.306 1.00 53.04 C
+ANISOU 672 CB LYS A 92 6468 6705 6979 263 785 -107 C
+ATOM 673 CG LYS A 92 -17.183 -1.817 -32.271 1.00 56.58 C
+ANISOU 673 CG LYS A 92 6898 7107 7489 325 715 -36 C
+ATOM 674 CD LYS A 92 -17.486 -0.352 -32.061 1.00 58.78 C
+ANISOU 674 CD LYS A 92 7167 7262 7905 494 841 28 C
+ATOM 675 CE LYS A 92 -18.585 0.113 -32.975 1.00 67.73 C
+ANISOU 675 CE LYS A 92 8061 8564 9107 618 876 223 C
+ATOM 676 NZ LYS A 92 -18.423 1.591 -33.141 1.00 70.69 N
+ANISOU 676 NZ LYS A 92 8453 8766 9637 795 997 324 N
+ATOM 677 N GLU A 93 -17.977 -3.940 -27.920 1.00 48.14 N
+ANISOU 677 N GLU A 93 6220 5912 6155 204 998 -342 N
+ATOM 678 CA GLU A 93 -18.834 -4.744 -26.990 1.00 51.58 C
+ANISOU 678 CA GLU A 93 6674 6388 6535 183 1133 -348 C
+ATOM 679 C GLU A 93 -20.133 -4.043 -26.630 1.00 53.52 C
+ANISOU 679 C GLU A 93 6808 6660 6864 287 1296 -305 C
+ATOM 680 O GLU A 93 -21.165 -4.650 -26.637 1.00 58.70 O
+ANISOU 680 O GLU A 93 7330 7419 7554 250 1380 -249 O
+ATOM 681 CB GLU A 93 -18.112 -5.078 -25.684 1.00 53.98 C
+ANISOU 681 CB GLU A 93 7203 6619 6686 189 1166 -429 C
+ATOM 682 CG GLU A 93 -18.999 -5.656 -24.586 1.00 58.34 C
+ANISOU 682 CG GLU A 93 7798 7194 7171 208 1345 -418 C
+ATOM 683 CD GLU A 93 -18.194 -6.346 -23.498 1.00 59.78 C
+ANISOU 683 CD GLU A 93 8187 7360 7166 207 1352 -449 C
+ATOM 684 OE1 GLU A 93 -17.556 -5.652 -22.668 1.00 64.37 O
+ANISOU 684 OE1 GLU A 93 8915 7917 7626 267 1330 -538 O
+ATOM 685 OE2 GLU A 93 -18.184 -7.597 -23.528 1.00 52.88 O
+ANISOU 685 OE2 GLU A 93 7321 6504 6265 142 1381 -382 O
+ATOM 686 N GLU A 94 -20.084 -2.768 -26.311 1.00 59.72 N
+ANISOU 686 N GLU A 94 7647 7342 7699 413 1362 -331 N
+ATOM 687 CA GLU A 94 -21.265 -2.097 -25.790 1.00 66.89 C
+ANISOU 687 CA GLU A 94 8483 8242 8687 544 1565 -289 C
+ATOM 688 C GLU A 94 -22.389 -2.061 -26.822 1.00 70.98 C
+ANISOU 688 C GLU A 94 8697 8926 9344 581 1575 -124 C
+ATOM 689 O GLU A 94 -23.572 -2.215 -26.481 1.00 76.40 O
+ANISOU 689 O GLU A 94 9243 9704 10081 626 1721 -54 O
+ATOM 690 CB GLU A 94 -20.887 -0.700 -25.315 1.00 74.24 C
+ANISOU 690 CB GLU A 94 9560 8986 9660 665 1660 -370 C
+ATOM 691 CG GLU A 94 -20.302 -0.701 -23.891 1.00 88.53 C
+ANISOU 691 CG GLU A 94 11642 10696 11297 640 1723 -551 C
+ATOM 692 CD GLU A 94 -21.356 -0.505 -22.760 1.00104.83 C
+ANISOU 692 CD GLU A 94 13759 12740 13331 745 1979 -573 C
+ATOM 693 OE1 GLU A 94 -20.982 0.024 -21.666 1.00102.89 O
+ANISOU 693 OE1 GLU A 94 13744 12388 12962 767 2076 -740 O
+ATOM 694 OE2 GLU A 94 -22.562 -0.867 -22.947 1.00106.29 O
+ANISOU 694 OE2 GLU A 94 13749 13029 13605 797 2092 -434 O
+ATOM 695 N ALA A 95 -22.007 -1.909 -28.091 1.00 68.41 N
+ANISOU 695 N ALA A 95 8255 8672 9065 556 1414 -53 N
+ATOM 696 CA ALA A 95 -22.956 -1.709 -29.182 1.00 66.09 C
+ANISOU 696 CA ALA A 95 7658 8583 8869 608 1388 116 C
+ATOM 697 C ALA A 95 -23.662 -2.996 -29.528 1.00 66.44 C
+ANISOU 697 C ALA A 95 7523 8851 8867 435 1328 127 C
+ATOM 698 O ALA A 95 -24.779 -2.940 -30.017 1.00 70.13 O
+ANISOU 698 O ALA A 95 7710 9533 9402 465 1352 251 O
+ATOM 699 CB ALA A 95 -22.245 -1.163 -30.422 1.00 66.10 C
+ANISOU 699 CB ALA A 95 7613 8606 8896 636 1238 189 C
+ATOM 700 N ILE A 96 -23.008 -4.142 -29.324 1.00 64.35 N
+ANISOU 700 N ILE A 96 7407 8544 8498 253 1257 4 N
+ATOM 701 CA ILE A 96 -23.650 -5.436 -29.582 1.00 69.19 C
+ANISOU 701 CA ILE A 96 7886 9314 9088 56 1244 -17 C
+ATOM 702 C ILE A 96 -24.290 -6.032 -28.311 1.00 75.00 C
+ANISOU 702 C ILE A 96 8682 9987 9825 30 1440 -50 C
+ATOM 703 O ILE A 96 -24.815 -7.127 -28.332 1.00 68.54 O
+ANISOU 703 O ILE A 96 7782 9246 9011 -142 1479 -77 O
+ATOM 704 CB ILE A 96 -22.743 -6.492 -30.279 1.00 69.26 C
+ANISOU 704 CB ILE A 96 7991 9314 9009 -136 1099 -110 C
+ATOM 705 CG1 ILE A 96 -21.443 -6.740 -29.528 1.00 72.23 C
+ANISOU 705 CG1 ILE A 96 8677 9458 9305 -123 1101 -195 C
+ATOM 706 CG2 ILE A 96 -22.463 -6.154 -31.716 1.00 67.05 C
+ANISOU 706 CG2 ILE A 96 7581 9181 8715 -151 922 -66 C
+ATOM 707 CD1 ILE A 96 -21.463 -8.031 -28.757 1.00 71.63 C
+ANISOU 707 CD1 ILE A 96 8723 9309 9184 -245 1210 -253 C
+ATOM 708 N MET A 97 -24.258 -5.310 -27.201 1.00 82.61 N
+ANISOU 708 N MET A 97 9796 10805 10784 194 1584 -55 N
+ATOM 709 CA MET A 97 -25.147 -5.636 -26.099 1.00 87.11 C
+ANISOU 709 CA MET A 97 10364 11365 11366 215 1801 -42 C
+ATOM 710 C MET A 97 -26.325 -4.668 -26.205 1.00 95.61 C
+ANISOU 710 C MET A 97 11196 12551 12577 376 1919 80 C
+ATOM 711 O MET A 97 -27.410 -5.101 -26.587 1.00 94.92 O
+ANISOU 711 O MET A 97 10826 12664 12575 303 1954 163 O
+ATOM 712 CB MET A 97 -24.435 -5.516 -24.761 1.00 78.92 C
+ANISOU 712 CB MET A 97 9648 10134 10203 296 1904 -129 C
+ATOM 713 CG MET A 97 -23.264 -6.468 -24.547 1.00 69.75 C
+ANISOU 713 CG MET A 97 8709 8888 8904 181 1804 -207 C
+ATOM 714 SD MET A 97 -22.432 -5.914 -23.038 1.00 73.23 S
+ANISOU 714 SD MET A 97 9478 9183 9162 316 1882 -298 S
+ATOM 715 CE MET A 97 -21.484 -7.324 -22.587 1.00 70.81 C
+ANISOU 715 CE MET A 97 9359 8848 8698 213 1836 -305 C
+ATOM 716 N LEU A 98 -26.060 -3.361 -25.977 1.00101.64 N
+ANISOU 716 N LEU A 98 12055 13191 13371 583 1974 95 N
+ATOM 717 CA LEU A 98 -27.090 -2.306 -25.727 1.00104.44 C
+ANISOU 717 CA LEU A 98 12260 13563 13858 803 2175 216 C
+ATOM 718 C LEU A 98 -27.843 -1.768 -26.965 1.00 99.32 C
+ANISOU 718 C LEU A 98 11253 13135 13349 890 2107 411 C
+ATOM 719 O LEU A 98 -27.308 -1.714 -28.071 1.00 91.78 O
+ANISOU 719 O LEU A 98 10232 12263 12378 839 1898 441 O
+ATOM 720 CB LEU A 98 -26.469 -1.140 -24.941 1.00 98.56 C
+ANISOU 720 CB LEU A 98 11797 12554 13097 977 2303 129 C
+TER 721 LEU A 98
+ATOM 722 N ALA B 2 -32.420 -24.500 -28.343 1.00 55.40 N
+ANISOU 722 N ALA B 2 8165 6777 6106 -670 -1057 -125 N
+ATOM 723 CA ALA B 2 -32.280 -23.018 -28.309 1.00 49.74 C
+ANISOU 723 CA ALA B 2 7221 6215 5463 -512 -965 -28 C
+ATOM 724 C ALA B 2 -30.968 -22.594 -27.656 1.00 49.10 C
+ANISOU 724 C ALA B 2 7123 6073 5460 -324 -756 -44 C
+ATOM 725 O ALA B 2 -30.475 -23.240 -26.699 1.00 48.76 O
+ANISOU 725 O ALA B 2 7101 5932 5490 -308 -687 -81 O
+ATOM 726 CB ALA B 2 -33.452 -22.398 -27.562 1.00 46.79 C
+ANISOU 726 CB ALA B 2 6548 6005 5225 -580 -1026 92 C
+ATOM 727 N THR B 3 -30.475 -21.450 -28.119 1.00 46.70 N
+ANISOU 727 N THR B 3 6765 5842 5136 -203 -668 1 N
+ATOM 728 CA THR B 3 -29.337 -20.783 -27.525 1.00 45.09 C
+ANISOU 728 CA THR B 3 6493 5632 5006 -79 -488 8 C
+ATOM 729 C THR B 3 -29.711 -19.332 -27.227 1.00 42.65 C
+ANISOU 729 C THR B 3 6022 5395 4786 -46 -461 119 C
+ATOM 730 O THR B 3 -30.163 -18.603 -28.102 1.00 49.78 O
+ANISOU 730 O THR B 3 6948 6349 5617 -31 -515 186 O
+ATOM 731 CB THR B 3 -28.152 -20.886 -28.525 1.00 48.51 C
+ANISOU 731 CB THR B 3 7083 6061 5285 14 -383 -53 C
+ATOM 732 OG1 THR B 3 -27.960 -22.272 -28.848 1.00 53.59 O
+ANISOU 732 OG1 THR B 3 7925 6609 5827 21 -421 -170 O
+ATOM 733 CG2 THR B 3 -26.865 -20.283 -27.959 1.00 46.16 C
+ANISOU 733 CG2 THR B 3 6683 5804 5049 105 -200 -45 C
+ATOM 734 N TYR B 4 -29.515 -18.935 -25.980 1.00 41.02 N
+ANISOU 734 N TYR B 4 5685 5178 4720 -22 -381 136 N
+ATOM 735 CA TYR B 4 -29.849 -17.616 -25.484 1.00 41.59 C
+ANISOU 735 CA TYR B 4 5649 5273 4878 26 -345 216 C
+ATOM 736 C TYR B 4 -28.595 -16.874 -25.182 1.00 37.08 C
+ANISOU 736 C TYR B 4 5099 4664 4323 55 -200 205 C
+ATOM 737 O TYR B 4 -27.552 -17.444 -25.084 1.00 42.67 O
+ANISOU 737 O TYR B 4 5829 5376 5007 49 -128 142 O
+ATOM 738 CB TYR B 4 -30.686 -17.729 -24.208 1.00 37.93 C
+ANISOU 738 CB TYR B 4 5032 4839 4538 12 -366 231 C
+ATOM 739 CG TYR B 4 -31.986 -18.470 -24.482 1.00 40.65 C
+ANISOU 739 CG TYR B 4 5310 5268 4864 -68 -514 257 C
+ATOM 740 CD1 TYR B 4 -32.953 -17.916 -25.304 1.00 41.09 C
+ANISOU 740 CD1 TYR B 4 5314 5421 4875 -38 -621 333 C
+ATOM 741 CD2 TYR B 4 -32.253 -19.691 -23.893 1.00 39.18 C
+ANISOU 741 CD2 TYR B 4 5113 5074 4699 -188 -554 219 C
+ATOM 742 CE1 TYR B 4 -34.139 -18.580 -25.546 1.00 44.88 C
+ANISOU 742 CE1 TYR B 4 5690 6029 5332 -146 -773 362 C
+ATOM 743 CE2 TYR B 4 -33.429 -20.383 -24.132 1.00 44.73 C
+ANISOU 743 CE2 TYR B 4 5750 5865 5377 -328 -695 249 C
+ATOM 744 CZ TYR B 4 -34.369 -19.827 -24.951 1.00 49.31 C
+ANISOU 744 CZ TYR B 4 6235 6582 5915 -317 -807 316 C
+ATOM 745 OH TYR B 4 -35.506 -20.526 -25.188 1.00 53.31 O
+ANISOU 745 OH TYR B 4 6643 7219 6390 -490 -962 347 O
+ATOM 746 N LYS B 5 -28.735 -15.589 -25.005 1.00 42.61 N
+ANISOU 746 N LYS B 5 5794 5333 5063 87 -164 270 N
+ATOM 747 CA LYS B 5 -27.647 -14.685 -24.656 1.00 46.72 C
+ANISOU 747 CA LYS B 5 6346 5805 5598 57 -42 270 C
+ATOM 748 C LYS B 5 -27.871 -14.311 -23.218 1.00 44.65 C
+ANISOU 748 C LYS B 5 6004 5508 5453 71 -18 246 C
+ATOM 749 O LYS B 5 -28.949 -13.910 -22.869 1.00 45.52 O
+ANISOU 749 O LYS B 5 6085 5600 5610 146 -64 281 O
+ATOM 750 CB LYS B 5 -27.735 -13.411 -25.451 1.00 51.37 C
+ANISOU 750 CB LYS B 5 7063 6323 6130 68 -27 364 C
+ATOM 751 CG LYS B 5 -27.674 -13.596 -26.941 1.00 58.63 C
+ANISOU 751 CG LYS B 5 8089 7285 6902 63 -56 410 C
+ATOM 752 CD LYS B 5 -26.289 -13.986 -27.387 1.00 70.28 C
+ANISOU 752 CD LYS B 5 9582 8829 8291 -17 60 365 C
+ATOM 753 CE LYS B 5 -26.281 -14.277 -28.899 1.00 79.59 C
+ANISOU 753 CE LYS B 5 10887 10066 9288 -6 42 396 C
+ATOM 754 NZ LYS B 5 -26.107 -13.052 -29.737 1.00 78.80 N
+ANISOU 754 NZ LYS B 5 10935 9919 9086 -50 88 523 N
+ATOM 755 N VAL B 6 -26.848 -14.482 -22.400 1.00 44.73 N
+ANISOU 755 N VAL B 6 5968 5536 5490 12 52 185 N
+ATOM 756 CA VAL B 6 -26.898 -14.160 -21.017 1.00 43.45 C
+ANISOU 756 CA VAL B 6 5755 5350 5403 9 75 149 C
+ATOM 757 C VAL B 6 -25.875 -13.071 -20.817 1.00 41.71 C
+ANISOU 757 C VAL B 6 5600 5078 5168 -88 150 141 C
+ATOM 758 O VAL B 6 -24.703 -13.264 -21.100 1.00 40.03 O
+ANISOU 758 O VAL B 6 5351 4944 4913 -178 196 125 O
+ATOM 759 CB VAL B 6 -26.496 -15.357 -20.132 1.00 43.61 C
+ANISOU 759 CB VAL B 6 5675 5449 5445 0 68 89 C
+ATOM 760 CG1 VAL B 6 -26.579 -14.975 -18.662 1.00 45.36 C
+ANISOU 760 CG1 VAL B 6 5860 5659 5714 -5 90 55 C
+ATOM 761 CG2 VAL B 6 -27.382 -16.547 -20.422 1.00 42.80 C
+ANISOU 761 CG2 VAL B 6 5551 5370 5340 37 -7 99 C
+ATOM 762 N LYS B 7 -26.334 -11.940 -20.314 1.00 40.23 N
+ANISOU 762 N LYS B 7 5512 4765 5007 -71 162 150 N
+ATOM 763 CA LYS B 7 -25.489 -10.806 -20.042 1.00 45.32 C
+ANISOU 763 CA LYS B 7 6277 5311 5631 -205 217 138 C
+ATOM 764 C LYS B 7 -25.268 -10.732 -18.545 1.00 45.32 C
+ANISOU 764 C LYS B 7 6243 5315 5660 -241 224 48 C
+ATOM 765 O LYS B 7 -26.230 -10.649 -17.762 1.00 42.09 O
+ANISOU 765 O LYS B 7 5848 4860 5282 -112 213 21 O
+ATOM 766 CB LYS B 7 -26.179 -9.567 -20.522 1.00 45.61 C
+ANISOU 766 CB LYS B 7 6527 5150 5652 -141 218 203 C
+ATOM 767 CG LYS B 7 -25.518 -8.255 -20.177 1.00 54.48 C
+ANISOU 767 CG LYS B 7 7863 6090 6747 -291 265 191 C
+ATOM 768 CD LYS B 7 -26.348 -7.148 -20.886 1.00 64.52 C
+ANISOU 768 CD LYS B 7 9392 7132 7990 -162 255 284 C
+ATOM 769 CE LYS B 7 -25.977 -5.744 -20.437 1.00 79.55 C
+ANISOU 769 CE LYS B 7 11603 8759 9861 -274 292 266 C
+ATOM 770 NZ LYS B 7 -26.138 -4.714 -21.507 1.00 86.71 N
+ANISOU 770 NZ LYS B 7 12802 9439 10702 -264 295 396 N
+ATOM 771 N PHE B 8 -24.001 -10.796 -18.153 1.00 44.26 N
+ANISOU 771 N PHE B 8 6044 5273 5500 -411 242 4 N
+ATOM 772 CA PHE B 8 -23.636 -10.739 -16.757 1.00 48.27 C
+ANISOU 772 CA PHE B 8 6521 5811 6006 -472 227 -80 C
+ATOM 773 C PHE B 8 -23.203 -9.366 -16.431 1.00 50.61 C
+ANISOU 773 C PHE B 8 7012 5952 6265 -641 245 -114 C
+ATOM 774 O PHE B 8 -22.332 -8.836 -17.115 1.00 51.85 O
+ANISOU 774 O PHE B 8 7205 6107 6388 -833 269 -77 O
+ATOM 775 CB PHE B 8 -22.495 -11.714 -16.458 1.00 46.54 C
+ANISOU 775 CB PHE B 8 6090 5823 5767 -542 208 -104 C
+ATOM 776 CG PHE B 8 -22.919 -13.133 -16.573 1.00 43.20 C
+ANISOU 776 CG PHE B 8 5543 5501 5370 -371 182 -85 C
+ATOM 777 CD1 PHE B 8 -23.753 -13.684 -15.611 1.00 45.99 C
+ANISOU 777 CD1 PHE B 8 5889 5839 5743 -264 152 -107 C
+ATOM 778 CD2 PHE B 8 -22.561 -13.888 -17.670 1.00 43.53 C
+ANISOU 778 CD2 PHE B 8 5511 5629 5397 -326 196 -45 C
+ATOM 779 CE1 PHE B 8 -24.172 -15.008 -15.719 1.00 45.51 C
+ANISOU 779 CE1 PHE B 8 5756 5836 5697 -151 123 -79 C
+ATOM 780 CE2 PHE B 8 -22.977 -15.203 -17.786 1.00 47.96 C
+ANISOU 780 CE2 PHE B 8 6024 6230 5968 -183 163 -39 C
+ATOM 781 CZ PHE B 8 -23.809 -15.751 -16.817 1.00 42.32 C
+ANISOU 781 CZ PHE B 8 5316 5479 5284 -113 120 -50 C
+ATOM 782 N ILE B 9 -23.818 -8.777 -15.407 1.00 50.12 N
+ANISOU 782 N ILE B 9 7095 5752 6194 -582 242 -186 N
+ATOM 783 CA ILE B 9 -23.293 -7.532 -14.841 1.00 52.49 C
+ANISOU 783 CA ILE B 9 7627 5881 6436 -773 243 -255 C
+ATOM 784 C ILE B 9 -22.569 -7.908 -13.581 1.00 53.51 C
+ANISOU 784 C ILE B 9 7645 6168 6518 -894 195 -352 C
+ATOM 785 O ILE B 9 -23.199 -8.276 -12.624 1.00 53.62 O
+ANISOU 785 O ILE B 9 7645 6206 6520 -744 190 -409 O
+ATOM 786 CB ILE B 9 -24.432 -6.583 -14.587 1.00 57.52 C
+ANISOU 786 CB ILE B 9 8544 6244 7065 -590 275 -283 C
+ATOM 787 CG1 ILE B 9 -25.188 -6.426 -15.903 1.00 59.96 C
+ANISOU 787 CG1 ILE B 9 8902 6461 7416 -426 296 -159 C
+ATOM 788 CG2 ILE B 9 -23.932 -5.267 -13.966 1.00 60.99 C
+ANISOU 788 CG2 ILE B 9 9309 6437 7425 -785 272 -375 C
+ATOM 789 CD1 ILE B 9 -26.172 -5.282 -15.905 1.00 63.59 C
+ANISOU 789 CD1 ILE B 9 9670 6630 7859 -227 324 -158 C
+ATOM 790 N THR B 10 -21.243 -7.928 -13.622 1.00 58.51 N
+ANISOU 790 N THR B 10 8157 6958 7116 -1157 160 -355 N
+ATOM 791 CA THR B 10 -20.440 -8.325 -12.483 1.00 58.08 C
+ANISOU 791 CA THR B 10 7958 7106 7001 -1275 86 -431 C
+ATOM 792 C THR B 10 -19.973 -7.044 -11.813 1.00 70.23 C
+ANISOU 792 C THR B 10 9748 8484 8451 -1550 48 -529 C
+ATOM 793 O THR B 10 -20.144 -5.958 -12.368 1.00 71.35 O
+ANISOU 793 O THR B 10 10161 8360 8588 -1655 87 -519 O
+ATOM 794 CB THR B 10 -19.189 -9.135 -12.876 1.00 58.06 C
+ANISOU 794 CB THR B 10 7627 7434 6998 -1387 54 -376 C
+ATOM 795 OG1 THR B 10 -18.233 -8.281 -13.503 1.00 67.21 O
+ANISOU 795 OG1 THR B 10 8801 8610 8125 -1697 67 -349 O
+ATOM 796 CG2 THR B 10 -19.528 -10.276 -13.818 1.00 59.69 C
+ANISOU 796 CG2 THR B 10 7661 7742 7275 -1147 101 -286 C
+ATOM 797 N PRO B 11 -19.376 -7.160 -10.620 1.00 72.85 N
+ANISOU 797 N PRO B 11 10022 8962 8697 -1676 -39 -622 N
+ATOM 798 CA PRO B 11 -18.837 -5.933 -10.022 1.00 82.51 C
+ANISOU 798 CA PRO B 11 11506 10030 9814 -1997 -96 -729 C
+ATOM 799 C PRO B 11 -17.740 -5.357 -10.913 1.00 82.13 C
+ANISOU 799 C PRO B 11 11402 10036 9765 -2359 -105 -662 C
+ATOM 800 O PRO B 11 -17.601 -4.166 -11.043 1.00 81.04 O
+ANISOU 800 O PRO B 11 11578 9634 9578 -2614 -104 -697 O
+ATOM 801 CB PRO B 11 -18.263 -6.417 -8.685 1.00 79.55 C
+ANISOU 801 CB PRO B 11 10990 9902 9333 -2070 -213 -819 C
+ATOM 802 CG PRO B 11 -19.024 -7.665 -8.373 1.00 77.41 C
+ANISOU 802 CG PRO B 11 10544 9762 9107 -1699 -182 -776 C
+ATOM 803 CD PRO B 11 -19.316 -8.308 -9.700 1.00 70.96 C
+ANISOU 803 CD PRO B 11 9555 8976 8429 -1526 -97 -639 C
+ATOM 804 N GLU B 12 -17.008 -6.230 -11.575 1.00 88.50 N
+ANISOU 804 N GLU B 12 11824 11180 10621 -2365 -98 -558 N
+ATOM 805 CA GLU B 12 -15.873 -5.804 -12.367 1.00 99.06 C
+ANISOU 805 CA GLU B 12 13027 12669 11940 -2715 -89 -484 C
+ATOM 806 C GLU B 12 -16.299 -5.351 -13.766 1.00 93.10 C
+ANISOU 806 C GLU B 12 12432 11697 11242 -2687 35 -371 C
+ATOM 807 O GLU B 12 -15.498 -4.776 -14.476 1.00 97.19 O
+ANISOU 807 O GLU B 12 12930 12268 11727 -3008 67 -299 O
+ATOM 808 CB GLU B 12 -14.832 -6.940 -12.446 1.00112.44 C
+ANISOU 808 CB GLU B 12 14216 14866 13638 -2694 -123 -425 C
+ATOM 809 CG GLU B 12 -14.678 -7.719 -11.130 1.00124.13 C
+ANISOU 809 CG GLU B 12 15529 16561 15070 -2562 -247 -503 C
+ATOM 810 CD GLU B 12 -13.339 -8.441 -10.973 1.00129.71 C
+ANISOU 810 CD GLU B 12 15773 17775 15735 -2649 -327 -459 C
+ATOM 811 OE1 GLU B 12 -12.591 -8.120 -10.015 1.00122.40 O
+ANISOU 811 OE1 GLU B 12 14767 17032 14705 -2906 -469 -526 O
+ATOM 812 OE2 GLU B 12 -13.042 -9.343 -11.788 1.00121.66 O
+ANISOU 812 OE2 GLU B 12 14470 16981 14772 -2441 -255 -362 O
+ATOM 813 N GLY B 13 -17.543 -5.608 -14.166 1.00 81.49 N
+ANISOU 813 N GLY B 13 11109 10009 9842 -2323 99 -344 N
+ATOM 814 CA GLY B 13 -18.037 -5.147 -15.451 1.00 73.28 C
+ANISOU 814 CA GLY B 13 10250 8758 8835 -2271 193 -234 C
+ATOM 815 C GLY B 13 -18.997 -6.122 -16.098 1.00 65.13 C
+ANISOU 815 C GLY B 13 9104 7761 7882 -1867 241 -172 C
+ATOM 816 O GLY B 13 -19.539 -6.995 -15.467 1.00 67.40 O
+ANISOU 816 O GLY B 13 9263 8138 8207 -1617 210 -222 O
+ATOM 817 N GLU B 14 -19.185 -5.957 -17.384 1.00 61.80 N
+ANISOU 817 N GLU B 14 8743 7270 7466 -1838 311 -57 N
+ATOM 818 CA GLU B 14 -20.256 -6.598 -18.125 1.00 63.32 C
+ANISOU 818 CA GLU B 14 8924 7423 7712 -1496 338 2 C
+ATOM 819 C GLU B 14 -19.671 -7.497 -19.189 1.00 56.31 C
+ANISOU 819 C GLU B 14 7774 6809 6810 -1480 388 83 C
+ATOM 820 O GLU B 14 -18.634 -7.194 -19.774 1.00 62.63 O
+ANISOU 820 O GLU B 14 8502 7742 7551 -1731 443 140 O
+ATOM 821 CB GLU B 14 -21.129 -5.544 -18.792 1.00 71.21 C
+ANISOU 821 CB GLU B 14 10284 8074 8699 -1428 362 71 C
+ATOM 822 CG GLU B 14 -22.416 -5.260 -18.043 1.00 86.78 C
+ANISOU 822 CG GLU B 14 12442 9819 10709 -1152 330 6 C
+ATOM 823 CD GLU B 14 -22.957 -3.842 -18.244 1.00101.03 C
+ANISOU 823 CD GLU B 14 14681 11229 12476 -1139 343 36 C
+ATOM 824 OE1 GLU B 14 -22.373 -2.917 -17.631 1.00107.53 O
+ANISOU 824 OE1 GLU B 14 15741 11869 13245 -1388 335 -29 O
+ATOM 825 OE2 GLU B 14 -23.973 -3.658 -18.983 1.00100.60 O
+ANISOU 825 OE2 GLU B 14 14745 11041 12435 -874 348 124 O
+ATOM 826 N LEU B 15 -20.365 -8.587 -19.454 1.00 56.17 N
+ANISOU 826 N LEU B 15 7631 6874 6835 -1191 377 86 N
+ATOM 827 CA LEU B 15 -20.023 -9.507 -20.528 1.00 55.27 C
+ANISOU 827 CA LEU B 15 7340 6967 6692 -1109 425 143 C
+ATOM 828 C LEU B 15 -21.290 -10.308 -20.860 1.00 53.66 C
+ANISOU 828 C LEU B 15 7166 6692 6529 -812 384 148 C
+ATOM 829 O LEU B 15 -22.039 -10.720 -19.940 1.00 50.69 O
+ANISOU 829 O LEU B 15 6774 6269 6216 -671 324 88 O
+ATOM 830 CB LEU B 15 -18.948 -10.454 -20.044 1.00 57.82 C
+ANISOU 830 CB LEU B 15 7356 7605 7007 -1128 426 93 C
+ATOM 831 CG LEU B 15 -18.440 -11.420 -21.099 1.00 63.30 C
+ANISOU 831 CG LEU B 15 7878 8524 7650 -1015 495 130 C
+ATOM 832 CD1 LEU B 15 -17.756 -10.666 -22.216 1.00 63.58 C
+ANISOU 832 CD1 LEU B 15 7943 8622 7594 -1222 602 221 C
+ATOM 833 CD2 LEU B 15 -17.443 -12.372 -20.490 1.00 65.97 C
+ANISOU 833 CD2 LEU B 15 7922 9161 7982 -958 487 79 C
+ATOM 834 N GLU B 16 -21.532 -10.510 -22.157 1.00 47.63 N
+ANISOU 834 N GLU B 16 6447 5937 5713 -745 415 221 N
+ATOM 835 CA GLU B 16 -22.664 -11.304 -22.654 1.00 45.67 C
+ANISOU 835 CA GLU B 16 6218 5656 5479 -515 358 230 C
+ATOM 836 C GLU B 16 -22.099 -12.584 -23.254 1.00 48.61 C
+ANISOU 836 C GLU B 16 6436 6232 5799 -443 384 205 C
+ATOM 837 O GLU B 16 -21.055 -12.553 -23.930 1.00 46.18 O
+ANISOU 837 O GLU B 16 6067 6070 5407 -536 474 229 O
+ATOM 838 CB GLU B 16 -23.451 -10.553 -23.698 1.00 48.11 C
+ANISOU 838 CB GLU B 16 6731 5809 5738 -476 346 328 C
+ATOM 839 CG GLU B 16 -24.832 -11.113 -24.032 1.00 53.37 C
+ANISOU 839 CG GLU B 16 7413 6439 6424 -265 251 343 C
+ATOM 840 CD GLU B 16 -25.747 -10.126 -24.829 1.00 57.72 C
+ANISOU 840 CD GLU B 16 8169 6829 6932 -188 209 453 C
+ATOM 841 OE1 GLU B 16 -26.936 -9.937 -24.446 1.00 69.98 O
+ANISOU 841 OE1 GLU B 16 9737 8308 8544 -25 134 464 O
+ATOM 842 OE2 GLU B 16 -25.279 -9.506 -25.809 1.00 71.51 O
+ANISOU 842 OE2 GLU B 16 10058 8536 8577 -278 255 541 O
+ATOM 843 N VAL B 17 -22.770 -13.706 -22.978 1.00 44.60 N
+ANISOU 843 N VAL B 17 5878 5736 5329 -281 315 156 N
+ATOM 844 CA VAL B 17 -22.304 -14.976 -23.436 1.00 46.75 C
+ANISOU 844 CA VAL B 17 6070 6143 5548 -182 330 114 C
+ATOM 845 C VAL B 17 -23.463 -15.746 -23.995 1.00 45.90 C
+ANISOU 845 C VAL B 17 6061 5952 5427 -66 243 110 C
+ATOM 846 O VAL B 17 -24.614 -15.485 -23.683 1.00 43.95 O
+ANISOU 846 O VAL B 17 5860 5598 5240 -49 164 134 O
+ATOM 847 CB VAL B 17 -21.605 -15.796 -22.302 1.00 47.60 C
+ANISOU 847 CB VAL B 17 6021 6360 5702 -132 323 46 C
+ATOM 848 CG1 VAL B 17 -20.698 -14.897 -21.492 1.00 51.12 C
+ANISOU 848 CG1 VAL B 17 6363 6888 6173 -288 361 47 C
+ATOM 849 CG2 VAL B 17 -22.618 -16.422 -21.353 1.00 49.09 C
+ANISOU 849 CG2 VAL B 17 6236 6442 5970 -53 227 18 C
+ATOM 850 N GLU B 18 -23.109 -16.745 -24.776 1.00 46.07 N
+ANISOU 850 N GLU B 18 6102 6043 5357 16 260 72 N
+ATOM 851 CA GLU B 18 -24.020 -17.745 -25.270 1.00 49.63 C
+ANISOU 851 CA GLU B 18 6660 6424 5772 95 165 41 C
+ATOM 852 C GLU B 18 -24.215 -18.851 -24.218 1.00 44.35 C
+ANISOU 852 C GLU B 18 5956 5714 5177 154 106 -15 C
+ATOM 853 O GLU B 18 -23.267 -19.284 -23.560 1.00 51.13 O
+ANISOU 853 O GLU B 18 6734 6641 6052 214 157 -53 O
+ATOM 854 CB GLU B 18 -23.469 -18.355 -26.555 1.00 50.78 C
+ANISOU 854 CB GLU B 18 6901 6634 5756 163 218 4 C
+ATOM 855 CG GLU B 18 -23.996 -17.686 -27.802 1.00 68.77 C
+ANISOU 855 CG GLU B 18 9305 8898 7926 113 200 68 C
+ATOM 856 CD GLU B 18 -23.835 -18.551 -29.075 1.00 88.05 C
+ANISOU 856 CD GLU B 18 11901 11375 10178 191 210 8 C
+ATOM 857 OE1 GLU B 18 -22.896 -19.410 -29.126 1.00 81.31 O
+ANISOU 857 OE1 GLU B 18 11040 10592 9262 305 301 -77 O
+ATOM 858 OE2 GLU B 18 -24.664 -18.355 -30.020 1.00 95.29 O
+ANISOU 858 OE2 GLU B 18 12955 12254 10995 158 122 45 O
+ATOM 859 N CYS B 19 -25.445 -19.302 -24.075 1.00 41.64 N
+ANISOU 859 N CYS B 19 5672 5279 4869 130 -6 -8 N
+ATOM 860 CA CYS B 19 -25.763 -20.344 -23.133 1.00 45.79 C
+ANISOU 860 CA CYS B 19 6202 5746 5449 144 -63 -39 C
+ATOM 861 C CYS B 19 -26.882 -21.159 -23.766 1.00 46.84 C
+ANISOU 861 C CYS B 19 6462 5798 5535 89 -183 -46 C
+ATOM 862 O CYS B 19 -27.984 -20.631 -23.986 1.00 45.31 O
+ANISOU 862 O CYS B 19 6227 5622 5365 10 -256 7 O
+ATOM 863 CB CYS B 19 -26.236 -19.742 -21.802 1.00 44.81 C
+ANISOU 863 CB CYS B 19 5955 5628 5442 93 -68 2 C
+ATOM 864 SG CYS B 19 -26.514 -21.029 -20.541 1.00 44.98 S
+ANISOU 864 SG CYS B 19 5996 5591 5503 93 -120 -8 S
+ATOM 865 N ASP B 20 -26.627 -22.429 -24.061 1.00 46.35 N
+ANISOU 865 N ASP B 20 6561 5651 5398 132 -213 -114 N
+ATOM 866 CA ASP B 20 -27.710 -23.303 -24.531 1.00 48.89 C
+ANISOU 866 CA ASP B 20 7032 5874 5668 19 -349 -130 C
+ATOM 867 C ASP B 20 -28.747 -23.474 -23.465 1.00 47.10 C
+ANISOU 867 C ASP B 20 6711 5635 5547 -116 -420 -68 C
+ATOM 868 O ASP B 20 -28.472 -23.214 -22.296 1.00 47.38 O
+ANISOU 868 O ASP B 20 6628 5699 5673 -83 -357 -35 O
+ATOM 869 CB ASP B 20 -27.195 -24.650 -25.016 1.00 49.61 C
+ANISOU 869 CB ASP B 20 7385 5821 5642 92 -366 -229 C
+ATOM 870 CG ASP B 20 -26.366 -24.538 -26.278 1.00 56.74 C
+ANISOU 870 CG ASP B 20 8391 6766 6398 224 -291 -299 C
+ATOM 871 OD1 ASP B 20 -26.482 -23.537 -27.079 1.00 61.65 O
+ANISOU 871 OD1 ASP B 20 8935 7508 6978 194 -270 -261 O
+ATOM 872 OD2 ASP B 20 -25.587 -25.487 -26.498 1.00 64.45 O
+ANISOU 872 OD2 ASP B 20 9551 7653 7283 379 -246 -389 O
+ATOM 873 N ASP B 21 -29.960 -23.866 -23.882 1.00 51.35 N
+ANISOU 873 N ASP B 21 7285 6165 6058 -283 -552 -48 N
+ATOM 874 CA ASP B 21 -31.093 -24.022 -22.958 1.00 47.36 C
+ANISOU 874 CA ASP B 21 6647 5708 5637 -444 -612 27 C
+ATOM 875 C ASP B 21 -30.985 -25.153 -21.926 1.00 47.41 C
+ANISOU 875 C ASP B 21 6767 5582 5664 -512 -610 28 C
+ATOM 876 O ASP B 21 -31.828 -25.247 -21.025 1.00 45.27 O
+ANISOU 876 O ASP B 21 6372 5373 5454 -650 -626 105 O
+ATOM 877 CB ASP B 21 -32.458 -24.057 -23.695 1.00 51.66 C
+ANISOU 877 CB ASP B 21 7134 6351 6143 -629 -764 67 C
+ATOM 878 CG ASP B 21 -32.657 -25.259 -24.632 1.00 61.29 C
+ANISOU 878 CG ASP B 21 8623 7436 7229 -779 -899 -7 C
+ATOM 879 OD1 ASP B 21 -31.869 -26.233 -24.690 1.00 60.99 O
+ANISOU 879 OD1 ASP B 21 8860 7188 7124 -738 -879 -93 O
+ATOM 880 OD2 ASP B 21 -33.671 -25.198 -25.362 1.00 76.44 O
+ANISOU 880 OD2 ASP B 21 10482 9466 9093 -935 -1042 19 O
+ATOM 881 N ASP B 22 -29.986 -26.019 -22.094 1.00 45.76 N
+ANISOU 881 N ASP B 22 6801 5197 5386 -402 -588 -47 N
+ATOM 882 CA ASP B 22 -29.698 -27.103 -21.184 1.00 49.94 C
+ANISOU 882 CA ASP B 22 7499 5560 5913 -408 -587 -39 C
+ATOM 883 C ASP B 22 -28.367 -26.870 -20.478 1.00 51.81 C
+ANISOU 883 C ASP B 22 7692 5815 6179 -156 -468 -51 C
+ATOM 884 O ASP B 22 -27.852 -27.770 -19.904 1.00 47.85 O
+ANISOU 884 O ASP B 22 7360 5171 5649 -76 -467 -52 O
+ATOM 885 CB ASP B 22 -29.681 -28.442 -21.915 1.00 54.09 C
+ANISOU 885 CB ASP B 22 8395 5838 6318 -461 -680 -116 C
+ATOM 886 CG ASP B 22 -28.657 -28.512 -23.084 1.00 63.91 C
+ANISOU 886 CG ASP B 22 9803 7027 7451 -230 -637 -239 C
+ATOM 887 OD1 ASP B 22 -28.251 -27.429 -23.607 1.00 56.77 O
+ANISOU 887 OD1 ASP B 22 8699 6311 6557 -118 -561 -247 O
+ATOM 888 OD2 ASP B 22 -28.283 -29.685 -23.476 1.00 60.29 O
+ANISOU 888 OD2 ASP B 22 9703 6324 6879 -163 -672 -325 O
+ATOM 889 N VAL B 23 -27.833 -25.644 -20.499 1.00 44.07 N
+ANISOU 889 N VAL B 23 6485 5013 5246 -45 -380 -50 N
+ATOM 890 CA VAL B 23 -26.611 -25.310 -19.757 1.00 47.28 C
+ANISOU 890 CA VAL B 23 6793 5491 5677 138 -286 -54 C
+ATOM 891 C VAL B 23 -26.941 -24.305 -18.663 1.00 46.19 C
+ANISOU 891 C VAL B 23 6430 5488 5630 71 -247 9 C
+ATOM 892 O VAL B 23 -27.644 -23.285 -18.881 1.00 39.27 O
+ANISOU 892 O VAL B 23 5415 4705 4798 -11 -238 32 O
+ATOM 893 CB VAL B 23 -25.523 -24.795 -20.707 1.00 50.38 C
+ANISOU 893 CB VAL B 23 7146 5975 6020 297 -208 -117 C
+ATOM 894 CG1 VAL B 23 -24.342 -24.208 -19.967 1.00 46.76 C
+ANISOU 894 CG1 VAL B 23 6507 5665 5593 423 -122 -109 C
+ATOM 895 CG2 VAL B 23 -25.132 -25.955 -21.653 1.00 50.32 C
+ANISOU 895 CG2 VAL B 23 7401 5823 5893 416 -228 -198 C
+ATOM 896 N TYR B 24 -26.524 -24.659 -17.451 1.00 44.23 N
+ANISOU 896 N TYR B 24 6178 5236 5390 119 -233 41 N
+ATOM 897 CA TYR B 24 -26.635 -23.726 -16.362 1.00 42.32 C
+ANISOU 897 CA TYR B 24 5758 5120 5199 83 -187 78 C
+ATOM 898 C TYR B 24 -25.823 -22.471 -16.675 1.00 41.44 C
+ANISOU 898 C TYR B 24 5501 5135 5109 147 -123 34 C
+ATOM 899 O TYR B 24 -24.735 -22.521 -17.198 1.00 44.52 O
+ANISOU 899 O TYR B 24 5887 5563 5465 255 -98 -5 O
+ATOM 900 CB TYR B 24 -26.178 -24.336 -15.052 1.00 44.23 C
+ANISOU 900 CB TYR B 24 6041 5350 5413 135 -194 117 C
+ATOM 901 CG TYR B 24 -27.087 -25.431 -14.497 1.00 46.96 C
+ANISOU 901 CG TYR B 24 6541 5568 5732 16 -244 192 C
+ATOM 902 CD1 TYR B 24 -28.468 -25.241 -14.364 1.00 44.56 C
+ANISOU 902 CD1 TYR B 24 6173 5299 5459 -181 -243 243 C
+ATOM 903 CD2 TYR B 24 -26.538 -26.649 -14.079 1.00 51.68 C
+ANISOU 903 CD2 TYR B 24 7347 6023 6266 106 -288 224 C
+ATOM 904 CE1 TYR B 24 -29.285 -26.242 -13.871 1.00 49.24 C
+ANISOU 904 CE1 TYR B 24 6889 5801 6017 -343 -281 325 C
+ATOM 905 CE2 TYR B 24 -27.342 -27.663 -13.564 1.00 49.44 C
+ANISOU 905 CE2 TYR B 24 7249 5591 5944 -40 -332 309 C
+ATOM 906 CZ TYR B 24 -28.691 -27.448 -13.430 1.00 51.30 C
+ANISOU 906 CZ TYR B 24 7400 5881 6209 -289 -324 362 C
+ATOM 907 OH TYR B 24 -29.429 -28.459 -12.887 1.00 52.12 O
+ANISOU 907 OH TYR B 24 7677 5862 6265 -476 -359 461 O
+ATOM 908 N VAL B 25 -26.397 -21.353 -16.303 1.00 42.58 N
+ANISOU 908 N VAL B 25 5534 5344 5298 74 -91 48 N
+ATOM 909 CA VAL B 25 -25.870 -19.977 -16.515 1.00 43.51 C
+ANISOU 909 CA VAL B 25 5561 5536 5435 77 -35 18 C
+ATOM 910 C VAL B 25 -24.479 -19.883 -15.914 1.00 45.47 C
+ANISOU 910 C VAL B 25 5750 5871 5655 125 -13 -11 C
+ATOM 911 O VAL B 25 -23.583 -19.234 -16.483 1.00 42.02 O
+ANISOU 911 O VAL B 25 5255 5505 5205 121 24 -37 O
+ATOM 912 CB VAL B 25 -27.014 -19.053 -15.974 1.00 47.07 C
+ANISOU 912 CB VAL B 25 5964 5993 5928 22 -14 42 C
+ATOM 913 CG1 VAL B 25 -26.658 -17.985 -14.979 1.00 51.34 C
+ANISOU 913 CG1 VAL B 25 6467 6569 6468 14 35 10 C
+ATOM 914 CG2 VAL B 25 -27.951 -18.612 -17.124 1.00 50.07 C
+ANISOU 914 CG2 VAL B 25 6347 6348 6328 11 -32 68 C
+ATOM 915 N LEU B 26 -24.262 -20.562 -14.781 1.00 42.91 N
+ANISOU 915 N LEU B 26 5432 5567 5305 159 -44 3 N
+ATOM 916 CA LEU B 26 -22.937 -20.508 -14.120 1.00 44.21 C
+ANISOU 916 CA LEU B 26 5508 5860 5427 214 -52 -16 C
+ATOM 917 C LEU B 26 -21.873 -21.156 -15.044 1.00 43.16 C
+ANISOU 917 C LEU B 26 5348 5786 5263 347 -46 -31 C
+ATOM 918 O LEU B 26 -20.782 -20.644 -15.204 1.00 41.77 O
+ANISOU 918 O LEU B 26 5032 5771 5066 355 -19 -54 O
+ATOM 919 CB LEU B 26 -22.973 -21.227 -12.757 1.00 43.87 C
+ANISOU 919 CB LEU B 26 5503 5824 5338 252 -103 21 C
+ATOM 920 CG LEU B 26 -21.633 -21.303 -12.009 1.00 51.12 C
+ANISOU 920 CG LEU B 26 6319 6909 6194 330 -147 15 C
+ATOM 921 CD1 LEU B 26 -20.989 -19.928 -11.865 1.00 47.47 C
+ANISOU 921 CD1 LEU B 26 5717 6587 5732 203 -127 -41 C
+ATOM 922 CD2 LEU B 26 -21.802 -21.989 -10.650 1.00 53.81 C
+ANISOU 922 CD2 LEU B 26 6734 7244 6465 368 -206 70 C
+ATOM 923 N ASP B 27 -22.221 -22.283 -15.633 1.00 44.33 N
+ANISOU 923 N ASP B 27 5638 5809 5394 443 -66 -21 N
+ATOM 924 CA ASP B 27 -21.332 -23.028 -16.510 1.00 46.01 C
+ANISOU 924 CA ASP B 27 5876 6049 5554 621 -47 -49 C
+ATOM 925 C ASP B 27 -20.956 -22.226 -17.766 1.00 49.22 C
+ANISOU 925 C ASP B 27 6200 6549 5953 583 32 -86 C
+ATOM 926 O ASP B 27 -19.802 -22.149 -18.106 1.00 50.44 O
+ANISOU 926 O ASP B 27 6223 6878 6063 680 86 -104 O
+ATOM 927 CB ASP B 27 -21.974 -24.337 -16.843 1.00 48.69 C
+ANISOU 927 CB ASP B 27 6461 6173 5864 695 -93 -45 C
+ATOM 928 CG ASP B 27 -22.021 -25.293 -15.605 1.00 61.91 C
+ANISOU 928 CG ASP B 27 8247 7761 7515 764 -163 12 C
+ATOM 929 OD1 ASP B 27 -21.027 -25.395 -14.870 1.00 72.00 O
+ANISOU 929 OD1 ASP B 27 9424 9171 8760 907 -177 30 O
+ATOM 930 OD2 ASP B 27 -23.034 -25.974 -15.376 1.00 65.76 O
+ANISOU 930 OD2 ASP B 27 8922 8059 8004 668 -211 51 O
+ATOM 931 N ALA B 28 -21.929 -21.573 -18.394 1.00 48.34 N
+ANISOU 931 N ALA B 28 6146 6346 5874 438 40 -82 N
+ATOM 932 CA ALA B 28 -21.708 -20.761 -19.556 1.00 48.04 C
+ANISOU 932 CA ALA B 28 6072 6368 5811 384 108 -93 C
+ATOM 933 C ALA B 28 -20.772 -19.641 -19.163 1.00 49.27 C
+ANISOU 933 C ALA B 28 6043 6698 5979 293 162 -84 C
+ATOM 934 O ALA B 28 -19.857 -19.319 -19.908 1.00 48.19 O
+ANISOU 934 O ALA B 28 5813 6707 5789 295 240 -88 O
+ATOM 935 CB ALA B 28 -23.039 -20.183 -20.056 1.00 52.12 C
+ANISOU 935 CB ALA B 28 6682 6758 6362 258 77 -68 C
+ATOM 936 N ALA B 29 -20.986 -19.058 -17.979 1.00 46.38 N
+ANISOU 936 N ALA B 29 5631 6327 5664 194 124 -74 N
+ATOM 937 CA ALA B 29 -20.076 -18.026 -17.489 1.00 48.20 C
+ANISOU 937 CA ALA B 29 5715 6706 5890 65 150 -79 C
+ATOM 938 C ALA B 29 -18.630 -18.516 -17.392 1.00 50.01 C
+ANISOU 938 C ALA B 29 5752 7184 6064 154 166 -86 C
+ATOM 939 O ALA B 29 -17.691 -17.860 -17.830 1.00 49.30 O
+ANISOU 939 O ALA B 29 5514 7276 5941 54 227 -80 O
+ATOM 940 CB ALA B 29 -20.518 -17.475 -16.122 1.00 48.24 C
+ANISOU 940 CB ALA B 29 5740 6659 5928 -29 96 -90 C
+ATOM 941 N GLU B 30 -18.455 -19.668 -16.787 1.00 50.74 N
+ANISOU 941 N GLU B 30 5842 7297 6140 344 111 -87 N
+ATOM 942 CA GLU B 30 -17.125 -20.211 -16.573 1.00 53.52 C
+ANISOU 942 CA GLU B 30 5996 7905 6434 495 109 -84 C
+ATOM 943 C GLU B 30 -16.487 -20.582 -17.882 1.00 55.58 C
+ANISOU 943 C GLU B 30 6200 8279 6639 634 213 -95 C
+ATOM 944 O GLU B 30 -15.310 -20.345 -18.062 1.00 53.30 O
+ANISOU 944 O GLU B 30 5662 8284 6302 650 267 -87 O
+ATOM 945 CB GLU B 30 -17.245 -21.433 -15.659 1.00 55.76 C
+ANISOU 945 CB GLU B 30 6364 8121 6701 708 18 -66 C
+ATOM 946 CG GLU B 30 -17.599 -20.966 -14.244 1.00 60.54 C
+ANISOU 946 CG GLU B 30 6973 8707 7322 564 -69 -52 C
+ATOM 947 CD GLU B 30 -17.847 -22.100 -13.266 1.00 67.44 C
+ANISOU 947 CD GLU B 30 7969 9491 8161 734 -157 -9 C
+ATOM 948 OE1 GLU B 30 -18.209 -23.248 -13.665 1.00 66.53 O
+ANISOU 948 OE1 GLU B 30 8035 9206 8037 915 -159 8 O
+ATOM 949 OE2 GLU B 30 -17.669 -21.807 -12.069 1.00 71.86 O
+ANISOU 949 OE2 GLU B 30 8471 10144 8689 666 -231 5 O
+ATOM 950 N GLU B 31 -17.279 -21.156 -18.796 1.00 55.65 N
+ANISOU 950 N GLU B 31 6432 8073 6637 723 241 -115 N
+ATOM 951 CA GLU B 31 -16.811 -21.477 -20.146 1.00 59.63 C
+ANISOU 951 CA GLU B 31 6942 8655 7058 853 350 -141 C
+ATOM 952 C GLU B 31 -16.291 -20.194 -20.865 1.00 55.72 C
+ANISOU 952 C GLU B 31 6283 8348 6540 632 457 -115 C
+ATOM 953 O GLU B 31 -15.355 -20.248 -21.599 1.00 58.65 O
+ANISOU 953 O GLU B 31 6505 8951 6826 714 569 -117 O
+ATOM 954 CB GLU B 31 -17.945 -22.145 -20.947 1.00 70.50 C
+ANISOU 954 CB GLU B 31 8629 9739 8417 905 329 -174 C
+ATOM 955 CG GLU B 31 -17.483 -23.157 -21.980 1.00 89.10 C
+ANISOU 955 CG GLU B 31 11093 12105 10654 1169 401 -233 C
+ATOM 956 CD GLU B 31 -16.540 -24.196 -21.373 1.00108.88 C
+ANISOU 956 CD GLU B 31 13534 14713 13120 1482 395 -248 C
+ATOM 957 OE1 GLU B 31 -16.868 -24.715 -20.275 1.00122.63 O
+ANISOU 957 OE1 GLU B 31 15352 16322 14918 1517 281 -221 O
+ATOM 958 OE2 GLU B 31 -15.461 -24.475 -21.968 1.00106.25 O
+ANISOU 958 OE2 GLU B 31 13067 14613 12689 1708 509 -276 O
+ATOM 959 N ALA B 32 -16.902 -19.037 -20.607 1.00 54.88 N
+ANISOU 959 N ALA B 32 6217 8134 6498 356 427 -85 N
+ATOM 960 CA ALA B 32 -16.492 -17.745 -21.179 1.00 59.73 C
+ANISOU 960 CA ALA B 32 6747 8857 7089 106 511 -44 C
+ATOM 961 C ALA B 32 -15.343 -17.016 -20.467 1.00 63.02 C
+ANISOU 961 C ALA B 32 6892 9546 7504 -75 520 -22 C
+ATOM 962 O ALA B 32 -14.998 -15.927 -20.905 1.00 63.67 O
+ANISOU 962 O ALA B 32 6934 9694 7561 -332 587 19 O
+ATOM 963 CB ALA B 32 -17.705 -16.806 -21.263 1.00 56.13 C
+ANISOU 963 CB ALA B 32 6511 8123 6691 -78 469 -20 C
+ATOM 964 N GLY B 33 -14.771 -17.574 -19.387 1.00 61.55 N
+ANISOU 964 N GLY B 33 6539 9514 7332 31 442 -42 N
+ATOM 965 CA GLY B 33 -13.600 -16.980 -18.707 1.00 63.73 C
+ANISOU 965 CA GLY B 33 6518 10110 7586 -146 423 -23 C
+ATOM 966 C GLY B 33 -13.895 -16.058 -17.525 1.00 66.50 C
+ANISOU 966 C GLY B 33 6927 10352 7985 -414 308 -38 C
+ATOM 967 O GLY B 33 -13.016 -15.338 -17.073 1.00 78.05 O
+ANISOU 967 O GLY B 33 8192 12044 9417 -656 282 -30 O
+ATOM 968 N ILE B 34 -15.129 -16.076 -17.028 1.00 67.68 N
+ANISOU 968 N ILE B 34 7348 10169 8195 -380 241 -66 N
+ATOM 969 CA ILE B 34 -15.538 -15.285 -15.866 1.00 69.74 C
+ANISOU 969 CA ILE B 34 7714 10302 8481 -573 147 -99 C
+ATOM 970 C ILE B 34 -15.518 -16.184 -14.636 1.00 64.98 C
+ANISOU 970 C ILE B 34 7061 9759 7866 -396 34 -118 C
+ATOM 971 O ILE B 34 -15.991 -17.333 -14.669 1.00 60.93 O
+ANISOU 971 O ILE B 34 6620 9161 7366 -127 24 -105 O
+ATOM 972 CB ILE B 34 -17.001 -14.806 -15.975 1.00 71.51 C
+ANISOU 972 CB ILE B 34 8249 10155 8763 -593 156 -112 C
+ATOM 973 CG1 ILE B 34 -17.270 -14.074 -17.281 1.00 80.00 C
+ANISOU 973 CG1 ILE B 34 9439 11114 9843 -696 254 -73 C
+ATOM 974 CG2 ILE B 34 -17.370 -13.876 -14.827 1.00 74.50 C
+ANISOU 974 CG2 ILE B 34 8756 10405 9144 -770 88 -161 C
+ATOM 975 CD1 ILE B 34 -18.763 -13.913 -17.553 1.00 74.26 C
+ANISOU 975 CD1 ILE B 34 8970 10076 9167 -610 251 -68 C
+ATOM 976 N ASP B 35 -15.021 -15.649 -13.537 1.00 61.68 N
+ANISOU 976 N ASP B 35 6562 9464 7408 -566 -59 -146 N
+ATOM 977 CA ASP B 35 -15.019 -16.414 -12.290 1.00 75.53 C
+ANISOU 977 CA ASP B 35 8296 11276 9122 -414 -177 -152 C
+ATOM 978 C ASP B 35 -16.098 -15.810 -11.437 1.00 67.96 C
+ANISOU 978 C ASP B 35 7599 10051 8171 -525 -210 -201 C
+ATOM 979 O ASP B 35 -16.004 -14.664 -11.028 1.00 71.36 O
+ANISOU 979 O ASP B 35 8091 10448 8572 -786 -232 -255 O
+ATOM 980 CB ASP B 35 -13.639 -16.434 -11.587 1.00 82.96 C
+ANISOU 980 CB ASP B 35 8931 12609 9978 -475 -282 -144 C
+ATOM 981 CG ASP B 35 -12.583 -17.205 -12.400 1.00 94.51 C
+ANISOU 981 CG ASP B 35 10096 14387 11425 -270 -232 -89 C
+ATOM 982 OD1 ASP B 35 -12.806 -18.403 -12.759 1.00 96.53 O
+ANISOU 982 OD1 ASP B 35 10403 14579 11694 79 -201 -57 O
+ATOM 983 OD2 ASP B 35 -11.544 -16.586 -12.714 1.00 99.59 O
+ANISOU 983 OD2 ASP B 35 10468 15337 12033 -469 -215 -78 O
+ATOM 984 N LEU B 36 -17.154 -16.583 -11.237 1.00 61.63 N
+ANISOU 984 N LEU B 36 6966 9051 7399 -328 -200 -183 N
+ATOM 985 CA LEU B 36 -18.261 -16.213 -10.383 1.00 56.78 C
+ANISOU 985 CA LEU B 36 6568 8229 6777 -371 -208 -218 C
+ATOM 986 C LEU B 36 -18.245 -17.129 -9.153 1.00 52.62 C
+ANISOU 986 C LEU B 36 6041 7780 6171 -238 -300 -192 C
+ATOM 987 O LEU B 36 -17.788 -18.261 -9.215 1.00 51.28 O
+ANISOU 987 O LEU B 36 5782 7714 5987 -45 -339 -130 O
+ATOM 988 CB LEU B 36 -19.602 -16.402 -11.121 1.00 60.32 C
+ANISOU 988 CB LEU B 36 7183 8425 7309 -276 -120 -195 C
+ATOM 989 CG LEU B 36 -19.852 -15.603 -12.408 1.00 57.54 C
+ANISOU 989 CG LEU B 36 6878 7960 7022 -360 -36 -197 C
+ATOM 990 CD1 LEU B 36 -21.213 -16.023 -13.015 1.00 57.02 C
+ANISOU 990 CD1 LEU B 36 6941 7702 7020 -235 11 -162 C
+ATOM 991 CD2 LEU B 36 -19.778 -14.120 -12.106 1.00 59.01 C
+ANISOU 991 CD2 LEU B 36 7159 8073 7187 -580 -26 -256 C
+ATOM 992 N PRO B 37 -18.782 -16.647 -8.045 1.00 49.77 N
+ANISOU 992 N PRO B 37 5814 7352 5742 -321 -326 -238 N
+ATOM 993 CA PRO B 37 -18.701 -17.404 -6.819 1.00 52.69 C
+ANISOU 993 CA PRO B 37 6200 7815 6003 -225 -415 -204 C
+ATOM 994 C PRO B 37 -19.633 -18.609 -6.877 1.00 53.75 C
+ANISOU 994 C PRO B 37 6445 7807 6169 -30 -373 -116 C
+ATOM 995 O PRO B 37 -20.659 -18.578 -7.575 1.00 52.82 O
+ANISOU 995 O PRO B 37 6420 7504 6142 -22 -275 -109 O
+ATOM 996 CB PRO B 37 -19.214 -16.410 -5.772 1.00 55.23 C
+ANISOU 996 CB PRO B 37 6682 8069 6232 -380 -415 -294 C
+ATOM 997 CG PRO B 37 -20.178 -15.544 -6.538 1.00 56.99 C
+ANISOU 997 CG PRO B 37 7035 8061 6556 -438 -287 -341 C
+ATOM 998 CD PRO B 37 -19.480 -15.359 -7.863 1.00 55.95 C
+ANISOU 998 CD PRO B 37 6768 7965 6526 -486 -269 -323 C
+ATOM 999 N TYR B 38 -19.264 -19.661 -6.164 1.00 51.10 N
+ANISOU 999 N TYR B 38 6105 7561 5748 112 -458 -39 N
+ATOM 1000 CA TYR B 38 -20.137 -20.809 -5.974 1.00 53.20 C
+ANISOU 1000 CA TYR B 38 6529 7673 6010 243 -434 55 C
+ATOM 1001 C TYR B 38 -19.656 -21.588 -4.747 1.00 54.18 C
+ANISOU 1001 C TYR B 38 6693 7909 5982 349 -548 134 C
+ATOM 1002 O TYR B 38 -18.582 -21.362 -4.322 1.00 49.82 O
+ANISOU 1002 O TYR B 38 6003 7570 5353 362 -654 116 O
+ATOM 1003 CB TYR B 38 -20.086 -21.734 -7.179 1.00 49.99 C
+ANISOU 1003 CB TYR B 38 6125 7167 5701 391 -407 104 C
+ATOM 1004 CG TYR B 38 -18.715 -22.275 -7.467 1.00 51.86 C
+ANISOU 1004 CG TYR B 38 6213 7579 5912 569 -486 127 C
+ATOM 1005 CD1 TYR B 38 -17.850 -21.585 -8.312 1.00 55.55 C
+ANISOU 1005 CD1 TYR B 38 6471 8204 6429 528 -464 64 C
+ATOM 1006 CD2 TYR B 38 -18.269 -23.505 -6.904 1.00 61.75 C
+ANISOU 1006 CD2 TYR B 38 7532 8850 7078 796 -577 225 C
+ATOM 1007 CE1 TYR B 38 -16.594 -22.086 -8.614 1.00 58.14 C
+ANISOU 1007 CE1 TYR B 38 6611 8752 6728 714 -515 89 C
+ATOM 1008 CE2 TYR B 38 -16.989 -24.012 -7.186 1.00 59.46 C
+ANISOU 1008 CE2 TYR B 38 7079 8753 6757 1025 -645 249 C
+ATOM 1009 CZ TYR B 38 -16.163 -23.294 -8.041 1.00 63.46 C
+ANISOU 1009 CZ TYR B 38 7329 9462 7319 985 -607 177 C
+ATOM 1010 OH TYR B 38 -14.891 -23.736 -8.343 1.00 72.30 O
+ANISOU 1010 OH TYR B 38 8229 10837 8402 1217 -652 201 O
+ATOM 1011 N SER B 39 -20.429 -22.569 -4.273 1.00 53.67 N
+ANISOU 1011 N SER B 39 6815 7706 5871 420 -534 237 N
+ATOM 1012 CA SER B 39 -19.980 -23.484 -3.243 1.00 53.24 C
+ANISOU 1012 CA SER B 39 6845 7718 5665 553 -645 347 C
+ATOM 1013 C SER B 39 -20.482 -24.911 -3.576 1.00 53.99 C
+ANISOU 1013 C SER B 39 7143 7585 5782 691 -631 477 C
+ATOM 1014 O SER B 39 -19.746 -25.715 -4.122 1.00 60.00 O
+ANISOU 1014 O SER B 39 7905 8323 6567 901 -692 520 O
+ATOM 1015 CB SER B 39 -20.438 -22.974 -1.880 1.00 54.47 C
+ANISOU 1015 CB SER B 39 7088 7945 5660 422 -647 339 C
+ATOM 1016 OG SER B 39 -19.961 -23.809 -0.856 1.00 58.10 O
+ANISOU 1016 OG SER B 39 7640 8485 5947 547 -768 457 O
+ATOM 1017 N CYS B 40 -21.745 -25.188 -3.303 1.00 53.52 N
+ANISOU 1017 N CYS B 40 7259 7360 5714 563 -542 532 N
+ATOM 1018 CA CYS B 40 -22.341 -26.502 -3.494 1.00 52.54 C
+ANISOU 1018 CA CYS B 40 7371 6999 5591 607 -533 661 C
+ATOM 1019 C CYS B 40 -22.554 -26.894 -4.990 1.00 54.29 C
+ANISOU 1019 C CYS B 40 7615 7039 5972 636 -494 621 C
+ATOM 1020 O CYS B 40 -22.599 -28.079 -5.354 1.00 56.18 O
+ANISOU 1020 O CYS B 40 8070 7067 6206 733 -528 702 O
+ATOM 1021 CB CYS B 40 -23.706 -26.493 -2.758 1.00 53.96 C
+ANISOU 1021 CB CYS B 40 7670 7122 5708 390 -431 727 C
+ATOM 1022 SG CYS B 40 -25.014 -25.506 -3.570 1.00 54.05 S
+ANISOU 1022 SG CYS B 40 7540 7122 5874 175 -270 621 S
+ATOM 1023 N ARG B 41 -22.745 -25.881 -5.830 1.00 55.21 N
+ANISOU 1023 N ARG B 41 7548 7218 6210 539 -423 498 N
+ATOM 1024 CA ARG B 41 -23.100 -26.036 -7.243 1.00 57.45 C
+ANISOU 1024 CA ARG B 41 7842 7361 6623 525 -377 449 C
+ATOM 1025 C ARG B 41 -24.289 -26.944 -7.426 1.00 53.39 C
+ANISOU 1025 C ARG B 41 7544 6624 6118 400 -351 531 C
+ATOM 1026 O ARG B 41 -24.325 -27.732 -8.363 1.00 57.10 O
+ANISOU 1026 O ARG B 41 8153 6914 6628 449 -373 531 O
+ATOM 1027 CB ARG B 41 -21.926 -26.568 -8.054 1.00 57.25 C
+ANISOU 1027 CB ARG B 41 7805 7331 6614 765 -433 421 C
+ATOM 1028 CG ARG B 41 -20.730 -25.656 -8.128 1.00 63.18 C
+ANISOU 1028 CG ARG B 41 8288 8346 7369 845 -452 341 C
+ATOM 1029 CD ARG B 41 -19.678 -26.364 -8.976 1.00 72.83 C
+ANISOU 1029 CD ARG B 41 9491 9584 8595 1112 -481 331 C
+ATOM 1030 NE ARG B 41 -20.005 -26.268 -10.416 1.00 66.24 N
+ANISOU 1030 NE ARG B 41 8672 8642 7853 1080 -399 256 N
+ATOM 1031 CZ ARG B 41 -19.501 -25.337 -11.206 1.00 60.12 C
+ANISOU 1031 CZ ARG B 41 7679 8033 7131 1040 -342 173 C
+ATOM 1032 NH1 ARG B 41 -18.683 -24.440 -10.693 1.00 58.08 N
+ANISOU 1032 NH1 ARG B 41 7175 8038 6852 995 -361 150 N
+ATOM 1033 NH2 ARG B 41 -19.820 -25.271 -12.489 1.00 59.63 N
+ANISOU 1033 NH2 ARG B 41 7655 7877 7124 1014 -273 118 N
+ATOM 1034 N ALA B 42 -25.254 -26.842 -6.528 1.00 50.75 N
+ANISOU 1034 N ALA B 42 7240 6313 5731 225 -301 598 N
+ATOM 1035 CA ALA B 42 -26.322 -27.854 -6.466 1.00 55.82 C
+ANISOU 1035 CA ALA B 42 8087 6773 6348 63 -286 714 C
+ATOM 1036 C ALA B 42 -27.689 -27.296 -6.092 1.00 53.85 C
+ANISOU 1036 C ALA B 42 7723 6630 6105 -178 -176 738 C
+ATOM 1037 O ALA B 42 -28.646 -28.060 -5.838 1.00 55.78 O
+ANISOU 1037 O ALA B 42 8091 6791 6308 -370 -150 854 O
+ATOM 1038 CB ALA B 42 -25.919 -28.950 -5.457 1.00 58.15 C
+ANISOU 1038 CB ALA B 42 8635 6960 6496 141 -354 856 C
+ATOM 1039 N GLY B 43 -27.766 -25.976 -6.007 1.00 52.94 N
+ANISOU 1039 N GLY B 43 7380 6706 6028 -168 -108 636 N
+ATOM 1040 CA GLY B 43 -29.019 -25.311 -5.704 1.00 57.58 C
+ANISOU 1040 CA GLY B 43 7828 7426 6621 -321 9 641 C
+ATOM 1041 C GLY B 43 -29.393 -25.157 -4.247 1.00 56.47 C
+ANISOU 1041 C GLY B 43 7699 7426 6330 -371 90 705 C
+ATOM 1042 O GLY B 43 -30.490 -24.676 -3.919 1.00 61.40 O
+ANISOU 1042 O GLY B 43 8200 8190 6936 -473 214 718 O
+ATOM 1043 N SER B 44 -28.507 -25.552 -3.359 1.00 57.15 N
+ANISOU 1043 N SER B 44 7922 7502 6288 -282 25 748 N
+ATOM 1044 CA SER B 44 -28.864 -25.573 -1.947 1.00 60.58 C
+ANISOU 1044 CA SER B 44 8415 8061 6539 -340 95 828 C
+ATOM 1045 C SER B 44 -28.070 -24.590 -1.083 1.00 55.02 C
+ANISOU 1045 C SER B 44 7667 7512 5724 -218 81 721 C
+ATOM 1046 O SER B 44 -27.939 -24.770 0.117 1.00 56.43 O
+ANISOU 1046 O SER B 44 7952 7776 5712 -219 84 785 O
+ATOM 1047 CB SER B 44 -28.724 -26.997 -1.455 1.00 64.11 C
+ANISOU 1047 CB SER B 44 9118 8363 6875 -384 27 1009 C
+ATOM 1048 OG SER B 44 -27.369 -27.403 -1.576 1.00 72.90 O
+ANISOU 1048 OG SER B 44 10341 9378 7978 -177 -128 997 O
+ATOM 1049 N CYS B 45 -27.538 -23.526 -1.680 1.00 50.30 N
+ANISOU 1049 N CYS B 45 6932 6949 5228 -137 60 559 N
+ATOM 1050 CA CYS B 45 -26.911 -22.490 -0.877 1.00 49.85 C
+ANISOU 1050 CA CYS B 45 6852 7028 5060 -85 47 441 C
+ATOM 1051 C CYS B 45 -27.172 -21.136 -1.520 1.00 51.33 C
+ANISOU 1051 C CYS B 45 6911 7228 5361 -83 119 279 C
+ATOM 1052 O CYS B 45 -27.967 -21.005 -2.440 1.00 55.12 O
+ANISOU 1052 O CYS B 45 7307 7650 5984 -106 191 278 O
+ATOM 1053 CB CYS B 45 -25.390 -22.791 -0.653 1.00 48.86 C
+ANISOU 1053 CB CYS B 45 6762 6928 4874 20 -134 439 C
+ATOM 1054 SG CYS B 45 -24.160 -22.368 -1.931 1.00 53.35 S
+ANISOU 1054 SG CYS B 45 7176 7476 5616 105 -244 330 S
+ATOM 1055 N SER B 46 -26.488 -20.125 -1.034 1.00 50.33 N
+ANISOU 1055 N SER B 46 6793 7170 5158 -63 86 148 N
+ATOM 1056 CA SER B 46 -26.687 -18.804 -1.525 1.00 53.49 C
+ANISOU 1056 CA SER B 46 7146 7540 5638 -62 151 0 C
+ATOM 1057 C SER B 46 -25.436 -18.250 -2.234 1.00 51.56 C
+ANISOU 1057 C SER B 46 6851 7262 5478 -77 28 -89 C
+ATOM 1058 O SER B 46 -25.397 -17.049 -2.580 1.00 51.57 O
+ANISOU 1058 O SER B 46 6861 7210 5522 -105 60 -215 O
+ATOM 1059 CB SER B 46 -27.077 -17.908 -0.321 1.00 54.94 C
+ANISOU 1059 CB SER B 46 7434 7804 5634 -60 242 -100 C
+ATOM 1060 OG SER B 46 -25.958 -17.693 0.515 1.00 59.45 O
+ANISOU 1060 OG SER B 46 8091 8449 6049 -97 114 -164 O
+ATOM 1061 N SER B 47 -24.417 -19.082 -2.465 1.00 50.22 N
+ANISOU 1061 N SER B 47 6631 7124 5322 -52 -104 -22 N
+ATOM 1062 CA SER B 47 -23.104 -18.545 -2.910 1.00 53.80 C
+ANISOU 1062 CA SER B 47 6993 7634 5811 -82 -216 -100 C
+ATOM 1063 C SER B 47 -23.102 -17.974 -4.299 1.00 49.57 C
+ANISOU 1063 C SER B 47 6378 7002 5454 -106 -173 -147 C
+ATOM 1064 O SER B 47 -22.409 -17.004 -4.556 1.00 47.90 O
+ANISOU 1064 O SER B 47 6131 6812 5254 -198 -204 -242 O
+ATOM 1065 CB SER B 47 -21.985 -19.587 -2.863 1.00 55.00 C
+ANISOU 1065 CB SER B 47 7072 7893 5931 4 -358 -10 C
+ATOM 1066 OG SER B 47 -21.799 -19.986 -1.539 1.00 67.17 O
+ANISOU 1066 OG SER B 47 8697 9542 7281 24 -428 35 O
+ATOM 1067 N CYS B 48 -23.836 -18.597 -5.210 1.00 47.83 N
+ANISOU 1067 N CYS B 48 6142 6677 5355 -48 -112 -75 N
+ATOM 1068 CA CYS B 48 -23.825 -18.180 -6.626 1.00 44.63 C
+ANISOU 1068 CA CYS B 48 5671 6187 5098 -57 -82 -102 C
+ATOM 1069 C CYS B 48 -25.021 -17.249 -6.959 1.00 50.82 C
+ANISOU 1069 C CYS B 48 6502 6866 5939 -77 30 -146 C
+ATOM 1070 O CYS B 48 -25.428 -17.128 -8.127 1.00 51.63 O
+ANISOU 1070 O CYS B 48 6573 6888 6154 -61 61 -130 O
+ATOM 1071 CB CYS B 48 -23.944 -19.426 -7.480 1.00 41.68 C
+ANISOU 1071 CB CYS B 48 5279 5758 4800 24 -100 -7 C
+ATOM 1072 SG CYS B 48 -25.514 -20.250 -7.174 1.00 47.58 S
+ANISOU 1072 SG CYS B 48 6110 6423 5543 17 -32 87 S
+ATOM 1073 N ALA B 49 -25.604 -16.621 -5.943 1.00 49.42 N
+ANISOU 1073 N ALA B 49 6406 6702 5668 -83 90 -197 N
+ATOM 1074 CA ALA B 49 -26.803 -15.852 -6.145 1.00 47.37 C
+ANISOU 1074 CA ALA B 49 6180 6371 5446 -34 205 -227 C
+ATOM 1075 C ALA B 49 -26.501 -14.656 -7.025 1.00 46.14 C
+ANISOU 1075 C ALA B 49 6068 6096 5364 -55 208 -304 C
+ATOM 1076 O ALA B 49 -25.486 -13.952 -6.837 1.00 47.19 O
+ANISOU 1076 O ALA B 49 6266 6210 5452 -154 153 -386 O
+ATOM 1077 CB ALA B 49 -27.369 -15.388 -4.811 1.00 48.90 C
+ANISOU 1077 CB ALA B 49 6469 6616 5493 -1 286 -284 C
+ATOM 1078 N GLY B 50 -27.414 -14.412 -7.959 1.00 46.35 N
+ANISOU 1078 N GLY B 50 6066 6052 5491 20 266 -269 N
+ATOM 1079 CA GLY B 50 -27.486 -13.112 -8.644 1.00 47.72 C
+ANISOU 1079 CA GLY B 50 6340 6080 5709 42 296 -328 C
+ATOM 1080 C GLY B 50 -28.933 -12.665 -8.683 1.00 52.51 C
+ANISOU 1080 C GLY B 50 6951 6666 6333 212 397 -314 C
+ATOM 1081 O GLY B 50 -29.796 -13.183 -7.949 1.00 51.98 O
+ANISOU 1081 O GLY B 50 6805 6723 6220 284 461 -282 O
+ATOM 1082 N LYS B 51 -29.194 -11.690 -9.542 1.00 56.73 N
+ANISOU 1082 N LYS B 51 7570 7061 6924 284 413 -325 N
+ATOM 1083 CA LYS B 51 -30.512 -11.104 -9.670 1.00 58.00 C
+ANISOU 1083 CA LYS B 51 7730 7209 7099 498 500 -309 C
+ATOM 1084 C LYS B 51 -30.801 -10.888 -11.160 1.00 51.95 C
+ANISOU 1084 C LYS B 51 6929 6374 6435 547 454 -226 C
+ATOM 1085 O LYS B 51 -30.004 -10.302 -11.879 1.00 52.34 O
+ANISOU 1085 O LYS B 51 7113 6268 6503 462 408 -238 O
+ATOM 1086 CB LYS B 51 -30.496 -9.813 -8.890 1.00 62.10 C
+ANISOU 1086 CB LYS B 51 8498 7573 7524 591 570 -437 C
+ATOM 1087 CG LYS B 51 -31.824 -9.123 -8.706 1.00 71.92 C
+ANISOU 1087 CG LYS B 51 9764 8816 8744 885 686 -447 C
+ATOM 1088 CD LYS B 51 -31.618 -8.015 -7.667 1.00 84.43 C
+ANISOU 1088 CD LYS B 51 11656 10230 10191 959 758 -609 C
+ATOM 1089 CE LYS B 51 -32.841 -7.727 -6.792 1.00 94.36 C
+ANISOU 1089 CE LYS B 51 12897 11600 11354 1256 917 -653 C
+ATOM 1090 NZ LYS B 51 -33.550 -6.484 -7.218 1.00 96.90 N
+ANISOU 1090 NZ LYS B 51 13408 11730 11677 1566 985 -687 N
+ATOM 1091 N VAL B 52 -31.914 -11.423 -11.620 1.00 50.92 N
+ANISOU 1091 N VAL B 52 6608 6386 6353 653 460 -133 N
+ATOM 1092 CA VAL B 52 -32.367 -11.250 -12.978 1.00 51.68 C
+ANISOU 1092 CA VAL B 52 6658 6458 6518 721 403 -47 C
+ATOM 1093 C VAL B 52 -32.869 -9.817 -13.125 1.00 55.73 C
+ANISOU 1093 C VAL B 52 7340 6819 7014 951 455 -71 C
+ATOM 1094 O VAL B 52 -33.750 -9.385 -12.411 1.00 58.68 O
+ANISOU 1094 O VAL B 52 7692 7253 7351 1160 545 -97 O
+ATOM 1095 CB VAL B 52 -33.490 -12.237 -13.328 1.00 54.96 C
+ANISOU 1095 CB VAL B 52 6806 7103 6972 744 375 55 C
+ATOM 1096 CG1 VAL B 52 -34.003 -12.011 -14.775 1.00 52.68 C
+ANISOU 1096 CG1 VAL B 52 6472 6811 6730 819 290 142 C
+ATOM 1097 CG2 VAL B 52 -33.016 -13.669 -13.135 1.00 50.23 C
+ANISOU 1097 CG2 VAL B 52 6115 6592 6375 524 325 77 C
+ATOM 1098 N VAL B 53 -32.237 -9.071 -14.009 1.00 58.89 N
+ANISOU 1098 N VAL B 53 7936 7012 7426 915 408 -62 N
+ATOM 1099 CA VAL B 53 -32.688 -7.736 -14.395 1.00 62.70 C
+ANISOU 1099 CA VAL B 53 8634 7295 7891 1137 434 -54 C
+ATOM 1100 C VAL B 53 -33.762 -7.758 -15.502 1.00 61.16 C
+ANISOU 1100 C VAL B 53 8295 7206 7737 1336 378 79 C
+ATOM 1101 O VAL B 53 -34.656 -6.932 -15.513 1.00 69.08 O
+ANISOU 1101 O VAL B 53 9355 8170 8723 1636 413 102 O
+ATOM 1102 CB VAL B 53 -31.492 -6.995 -14.961 1.00 67.39 C
+ANISOU 1102 CB VAL B 53 9512 7623 8467 954 398 -72 C
+ATOM 1103 CG1 VAL B 53 -31.901 -5.593 -15.416 1.00 75.74 C
+ANISOU 1103 CG1 VAL B 53 10871 8410 9495 1168 416 -46 C
+ATOM 1104 CG2 VAL B 53 -30.375 -6.982 -13.920 1.00 67.44 C
+ANISOU 1104 CG2 VAL B 53 9626 7572 8426 722 423 -198 C
+ATOM 1105 N SER B 54 -33.617 -8.645 -16.484 1.00 54.51 N
+ANISOU 1105 N SER B 54 7294 6485 6931 1182 280 163 N
+ATOM 1106 CA SER B 54 -34.604 -8.785 -17.528 1.00 57.42 C
+ANISOU 1106 CA SER B 54 7508 6990 7316 1325 196 285 C
+ATOM 1107 C SER B 54 -34.480 -10.128 -18.163 1.00 49.00 C
+ANISOU 1107 C SER B 54 6241 6104 6271 1103 103 329 C
+ATOM 1108 O SER B 54 -33.420 -10.732 -18.126 1.00 48.61 O
+ANISOU 1108 O SER B 54 6245 6001 6221 872 101 279 O
+ATOM 1109 CB SER B 54 -34.457 -7.676 -18.615 1.00 67.92 C
+ANISOU 1109 CB SER B 54 9097 8093 8615 1441 149 357 C
+ATOM 1110 OG SER B 54 -33.212 -7.732 -19.310 1.00 68.84 O
+ANISOU 1110 OG SER B 54 9383 8061 8712 1181 119 358 O
+ATOM 1111 N GLY B 55 -35.568 -10.582 -18.760 1.00 49.29 N
+ANISOU 1111 N GLY B 55 6054 6357 6315 1182 19 420 N
+ATOM 1112 CA GLY B 55 -35.709 -11.925 -19.288 1.00 50.10 C
+ANISOU 1112 CA GLY B 55 5974 6638 6423 971 -80 453 C
+ATOM 1113 C GLY B 55 -36.015 -12.954 -18.190 1.00 54.88 C
+ANISOU 1113 C GLY B 55 6384 7412 7052 843 -31 418 C
+ATOM 1114 O GLY B 55 -36.357 -12.606 -17.055 1.00 51.85 O
+ANISOU 1114 O GLY B 55 5948 7078 6673 954 81 384 O
+ATOM 1115 N SER B 56 -35.910 -14.235 -18.540 1.00 52.05 N
+ANISOU 1115 N SER B 56 5952 7132 6691 610 -114 429 N
+ATOM 1116 CA SER B 56 -36.309 -15.287 -17.628 1.00 53.81 C
+ANISOU 1116 CA SER B 56 6017 7504 6924 461 -86 428 C
+ATOM 1117 C SER B 56 -35.313 -16.444 -17.548 1.00 48.18 C
+ANISOU 1117 C SER B 56 5432 6672 6199 230 -112 379 C
+ATOM 1118 O SER B 56 -34.496 -16.695 -18.438 1.00 51.01 O
+ANISOU 1118 O SER B 56 5943 6898 6540 166 -175 352 O
+ATOM 1119 CB SER B 56 -37.721 -15.783 -17.988 1.00 54.48 C
+ANISOU 1119 CB SER B 56 5818 7872 7006 422 -173 525 C
+ATOM 1120 OG SER B 56 -37.776 -16.208 -19.330 1.00 61.00 O
+ANISOU 1120 OG SER B 56 6673 8698 7805 316 -335 559 O
+ATOM 1121 N VAL B 57 -35.377 -17.125 -16.430 1.00 52.89 N
+ANISOU 1121 N VAL B 57 5977 7324 6794 133 -50 372 N
+ATOM 1122 CA VAL B 57 -34.589 -18.335 -16.192 1.00 52.55 C
+ANISOU 1122 CA VAL B 57 6056 7179 6732 -51 -77 346 C
+ATOM 1123 C VAL B 57 -35.550 -19.389 -15.674 1.00 55.14 C
+ANISOU 1123 C VAL B 57 6247 7658 7045 -229 -95 418 C
+ATOM 1124 O VAL B 57 -36.603 -19.052 -15.133 1.00 53.51 O
+ANISOU 1124 O VAL B 57 5830 7660 6841 -192 -35 473 O
+ATOM 1125 CB VAL B 57 -33.487 -18.134 -15.162 1.00 52.68 C
+ANISOU 1125 CB VAL B 57 6199 7082 6734 -9 13 278 C
+ATOM 1126 CG1 VAL B 57 -32.429 -17.171 -15.703 1.00 51.20 C
+ANISOU 1126 CG1 VAL B 57 6147 6751 6553 92 24 213 C
+ATOM 1127 CG2 VAL B 57 -34.091 -17.723 -13.810 1.00 53.07 C
+ANISOU 1127 CG2 VAL B 57 6147 7252 6763 53 130 286 C
+ATOM 1128 N ASP B 58 -35.198 -20.651 -15.913 1.00 54.40 N
+ANISOU 1128 N ASP B 58 6283 7459 6926 -420 -174 422 N
+ATOM 1129 CA ASP B 58 -35.847 -21.810 -15.319 1.00 52.99 C
+ANISOU 1129 CA ASP B 58 6069 7345 6718 -650 -190 493 C
+ATOM 1130 C ASP B 58 -34.894 -22.245 -14.184 1.00 50.66 C
+ANISOU 1130 C ASP B 58 5942 6913 6390 -637 -113 472 C
+ATOM 1131 O ASP B 58 -33.754 -22.666 -14.424 1.00 47.29 O
+ANISOU 1131 O ASP B 58 5729 6287 5951 -598 -150 415 O
+ATOM 1132 CB ASP B 58 -36.003 -22.916 -16.375 1.00 56.52 C
+ANISOU 1132 CB ASP B 58 6638 7699 7137 -861 -345 501 C
+ATOM 1133 CG ASP B 58 -36.384 -24.259 -15.771 1.00 65.37 C
+ANISOU 1133 CG ASP B 58 7842 8781 8214 -1139 -373 568 C
+ATOM 1134 OD1 ASP B 58 -36.846 -24.290 -14.603 1.00 66.65 O
+ANISOU 1134 OD1 ASP B 58 7883 9073 8365 -1194 -270 640 O
+ATOM 1135 OD2 ASP B 58 -36.259 -25.280 -16.483 1.00 70.20 O
+ANISOU 1135 OD2 ASP B 58 8664 9224 8785 -1310 -494 551 O
+ATOM 1136 N GLN B 59 -35.324 -22.089 -12.942 1.00 54.05 N
+ANISOU 1136 N GLN B 59 6267 7475 6792 -640 -1 517 N
+ATOM 1137 CA GLN B 59 -34.515 -22.555 -11.829 1.00 56.53 C
+ANISOU 1137 CA GLN B 59 6742 7686 7049 -640 51 516 C
+ATOM 1138 C GLN B 59 -35.268 -23.486 -10.889 1.00 59.14 C
+ANISOU 1138 C GLN B 59 7050 8107 7313 -851 94 632 C
+ATOM 1139 O GLN B 59 -35.188 -23.390 -9.661 1.00 65.41 O
+ANISOU 1139 O GLN B 59 7848 8966 8035 -822 198 658 O
+ATOM 1140 CB GLN B 59 -33.848 -21.372 -11.086 1.00 52.52 C
+ANISOU 1140 CB GLN B 59 6227 7196 6529 -422 151 436 C
+ATOM 1141 CG GLN B 59 -34.803 -20.396 -10.480 1.00 52.17 C
+ANISOU 1141 CG GLN B 59 5988 7361 6471 -326 274 442 C
+ATOM 1142 CD GLN B 59 -34.109 -19.292 -9.719 1.00 53.41 C
+ANISOU 1142 CD GLN B 59 6218 7483 6592 -139 359 343 C
+ATOM 1143 OE1 GLN B 59 -33.067 -19.483 -9.016 1.00 53.43 O
+ANISOU 1143 OE1 GLN B 59 6375 7387 6535 -140 352 304 O
+ATOM 1144 NE2 GLN B 59 -34.697 -18.133 -9.795 1.00 52.42 N
+ANISOU 1144 NE2 GLN B 59 5992 7441 6483 26 432 304 N
+ATOM 1145 N SER B 60 -35.956 -24.435 -11.476 1.00 61.58 N
+ANISOU 1145 N SER B 60 7365 8407 7623 -1092 6 703 N
+ATOM 1146 CA SER B 60 -36.740 -25.363 -10.706 1.00 72.30 C
+ANISOU 1146 CA SER B 60 8709 9847 8911 -1360 39 834 C
+ATOM 1147 C SER B 60 -35.825 -26.402 -10.017 1.00 74.05 C
+ANISOU 1147 C SER B 60 9269 9808 9057 -1412 17 868 C
+ATOM 1148 O SER B 60 -36.221 -27.047 -9.059 1.00 79.84 O
+ANISOU 1148 O SER B 60 10049 10581 9705 -1588 76 985 O
+ATOM 1149 CB SER B 60 -37.836 -25.999 -11.579 1.00 70.49 C
+ANISOU 1149 CB SER B 60 8372 9709 8700 -1655 -64 902 C
+ATOM 1150 OG SER B 60 -37.380 -26.382 -12.862 1.00 66.63 O
+ANISOU 1150 OG SER B 60 8069 9001 8245 -1672 -224 825 O
+ATOM 1151 N ASP B 61 -34.586 -26.497 -10.469 1.00 73.32 N
+ANISOU 1151 N ASP B 61 9398 9476 8984 -1231 -57 775 N
+ATOM 1152 CA ASP B 61 -33.572 -27.336 -9.811 1.00 80.97 C
+ANISOU 1152 CA ASP B 61 10666 10220 9879 -1177 -83 802 C
+ATOM 1153 C ASP B 61 -32.954 -26.686 -8.541 1.00 78.11 C
+ANISOU 1153 C ASP B 61 10262 9960 9455 -993 15 795 C
+ATOM 1154 O ASP B 61 -32.067 -27.263 -7.927 1.00 77.14 O
+ANISOU 1154 O ASP B 61 10352 9697 9259 -910 -16 823 O
+ATOM 1155 CB ASP B 61 -32.442 -27.683 -10.824 1.00 80.12 C
+ANISOU 1155 CB ASP B 61 10771 9865 9803 -1012 -194 700 C
+ATOM 1156 CG ASP B 61 -32.957 -28.443 -12.071 1.00 80.27 C
+ANISOU 1156 CG ASP B 61 10914 9741 9842 -1194 -306 687 C
+ATOM 1157 OD1 ASP B 61 -34.142 -28.856 -12.081 1.00 92.44 O
+ANISOU 1157 OD1 ASP B 61 12396 11355 11371 -1491 -323 772 O
+ATOM 1158 OD2 ASP B 61 -32.182 -28.623 -13.047 1.00 76.90 O
+ANISOU 1158 OD2 ASP B 61 10638 9149 9429 -1052 -377 588 O
+ATOM 1159 N GLN B 62 -33.390 -25.476 -8.178 1.00 79.30 N
+ANISOU 1159 N GLN B 62 10161 10347 9623 -909 123 751 N
+ATOM 1160 CA GLN B 62 -32.867 -24.772 -7.012 1.00 68.13 C
+ANISOU 1160 CA GLN B 62 8730 9027 8129 -755 210 719 C
+ATOM 1161 C GLN B 62 -33.726 -25.126 -5.824 1.00 70.39 C
+ANISOU 1161 C GLN B 62 8983 9467 8294 -906 322 843 C
+ATOM 1162 O GLN B 62 -34.807 -25.613 -6.012 1.00 70.22 O
+ANISOU 1162 O GLN B 62 8868 9532 8279 -1119 351 940 O
+ATOM 1163 CB GLN B 62 -32.896 -23.248 -7.236 1.00 67.38 C
+ANISOU 1163 CB GLN B 62 8445 9063 8093 -577 276 593 C
+ATOM 1164 CG GLN B 62 -34.246 -22.561 -6.972 1.00 69.55 C
+ANISOU 1164 CG GLN B 62 8479 9582 8363 -600 408 617 C
+ATOM 1165 CD GLN B 62 -34.463 -22.057 -5.534 1.00 62.14 C
+ANISOU 1165 CD GLN B 62 7513 8808 7289 -536 557 618 C
+ATOM 1166 OE1 GLN B 62 -33.521 -21.731 -4.823 1.00 54.90 O
+ANISOU 1166 OE1 GLN B 62 6736 7827 6294 -429 553 551 O
+ATOM 1167 NE2 GLN B 62 -35.725 -21.958 -5.128 1.00 63.75 N
+ANISOU 1167 NE2 GLN B 62 7519 9253 7449 -599 689 690 N
+ATOM 1168 N SER B 63 -33.270 -24.812 -4.615 1.00 70.67 N
+ANISOU 1168 N SER B 63 9076 9569 8205 -808 389 839 N
+ATOM 1169 CA SER B 63 -34.035 -25.114 -3.403 1.00 75.26 C
+ANISOU 1169 CA SER B 63 9643 10319 8633 -940 519 961 C
+ATOM 1170 C SER B 63 -33.862 -24.131 -2.248 1.00 70.31 C
+ANISOU 1170 C SER B 63 8977 9863 7874 -780 639 888 C
+ATOM 1171 O SER B 63 -34.598 -24.210 -1.268 1.00 78.27 O
+ANISOU 1171 O SER B 63 9939 11060 8737 -863 783 973 O
+ATOM 1172 CB SER B 63 -33.622 -26.492 -2.865 1.00 78.05 C
+ANISOU 1172 CB SER B 63 10283 10493 8878 -1077 445 1110 C
+ATOM 1173 OG SER B 63 -32.682 -26.352 -1.790 1.00 90.02 O
+ANISOU 1173 OG SER B 63 11950 12004 10249 -923 435 1099 O
+ATOM 1174 N PHE B 64 -32.871 -23.255 -2.316 1.00 65.41 N
+ANISOU 1174 N PHE B 64 8394 9180 7277 -573 583 734 N
+ATOM 1175 CA PHE B 64 -32.513 -22.466 -1.160 1.00 66.55 C
+ANISOU 1175 CA PHE B 64 8587 9435 7264 -453 656 655 C
+ATOM 1176 C PHE B 64 -33.316 -21.199 -1.122 1.00 68.15 C
+ANISOU 1176 C PHE B 64 8618 9800 7476 -340 809 543 C
+ATOM 1177 O PHE B 64 -33.653 -20.718 -0.042 1.00 74.02 O
+ANISOU 1177 O PHE B 64 9375 10700 8049 -284 945 514 O
+ATOM 1178 CB PHE B 64 -31.016 -22.107 -1.193 1.00 68.74 C
+ANISOU 1178 CB PHE B 64 8990 9582 7543 -323 508 542 C
+ATOM 1179 CG PHE B 64 -30.513 -21.437 0.066 1.00 66.26 C
+ANISOU 1179 CG PHE B 64 8771 9370 7032 -245 537 461 C
+ATOM 1180 CD1 PHE B 64 -30.170 -22.204 1.194 1.00 72.14 C
+ANISOU 1180 CD1 PHE B 64 9675 10158 7576 -288 506 569 C
+ATOM 1181 CD2 PHE B 64 -30.367 -20.052 0.126 1.00 68.69 C
+ANISOU 1181 CD2 PHE B 64 9050 9711 7337 -137 581 279 C
+ATOM 1182 CE1 PHE B 64 -29.710 -21.588 2.347 1.00 71.63 C
+ANISOU 1182 CE1 PHE B 64 9709 10202 7302 -228 515 487 C
+ATOM 1183 CE2 PHE B 64 -29.898 -19.430 1.275 1.00 69.45 C
+ANISOU 1183 CE2 PHE B 64 9273 9885 7231 -91 592 184 C
+ATOM 1184 CZ PHE B 64 -29.571 -20.192 2.381 1.00 72.58 C
+ANISOU 1184 CZ PHE B 64 9799 10357 7420 -139 555 283 C
+ATOM 1185 N LEU B 65 -33.564 -20.610 -2.286 1.00 63.83 N
+ANISOU 1185 N LEU B 65 7937 9206 7106 -274 785 473 N
+ATOM 1186 CA LEU B 65 -34.355 -19.387 -2.350 1.00 66.16 C
+ANISOU 1186 CA LEU B 65 8089 9630 7419 -115 921 375 C
+ATOM 1187 C LEU B 65 -35.835 -19.702 -2.078 1.00 70.47 C
+ANISOU 1187 C LEU B 65 8411 10440 7921 -180 1083 494 C
+ATOM 1188 O LEU B 65 -36.350 -20.690 -2.636 1.00 62.63 O
+ANISOU 1188 O LEU B 65 7317 9477 7002 -379 1035 634 O
+ATOM 1189 CB LEU B 65 -34.235 -18.733 -3.729 1.00 59.60 C
+ANISOU 1189 CB LEU B 65 7191 8674 6779 -25 837 299 C
+ATOM 1190 CG LEU B 65 -32.861 -18.246 -4.188 1.00 57.76 C
+ANISOU 1190 CG LEU B 65 7120 8221 6602 27 700 183 C
+ATOM 1191 CD1 LEU B 65 -32.917 -17.582 -5.576 1.00 57.81 C
+ANISOU 1191 CD1 LEU B 65 7061 8127 6775 102 646 135 C
+ATOM 1192 CD2 LEU B 65 -32.327 -17.275 -3.169 1.00 54.39 C
+ANISOU 1192 CD2 LEU B 65 6839 7788 6036 131 752 49 C
+ATOM 1193 N ASP B 66 -36.487 -18.860 -1.244 1.00 74.89 N
+ANISOU 1193 N ASP B 66 8903 11198 8353 -19 1274 433 N
+ATOM 1194 CA ASP B 66 -37.951 -18.868 -1.031 1.00 83.97 C
+ANISOU 1194 CA ASP B 66 9768 12675 9461 -11 1464 525 C
+ATOM 1195 C ASP B 66 -38.674 -18.077 -2.147 1.00 89.05 C
+ANISOU 1195 C ASP B 66 10182 13382 10272 163 1465 482 C
+ATOM 1196 O ASP B 66 -38.020 -17.512 -3.028 1.00 82.08 O
+ANISOU 1196 O ASP B 66 9403 12261 9520 266 1329 383 O
+ATOM 1197 CB ASP B 66 -38.358 -18.435 0.427 1.00 96.74 C
+ANISOU 1197 CB ASP B 66 11411 14515 10828 108 1694 490 C
+ATOM 1198 CG ASP B 66 -37.950 -16.966 0.829 1.00101.11 C
+ANISOU 1198 CG ASP B 66 12141 14972 11304 434 1759 259 C
+ATOM 1199 OD1 ASP B 66 -37.822 -16.062 -0.014 1.00103.38 O
+ANISOU 1199 OD1 ASP B 66 12437 15111 11732 617 1698 145 O
+ATOM 1200 OD2 ASP B 66 -37.801 -16.698 2.048 1.00107.31 O
+ANISOU 1200 OD2 ASP B 66 13086 15829 11857 502 1880 192 O
+ATOM 1201 N ASP B 67 -40.005 -18.040 -2.158 1.00 86.95 N
+ANISOU 1201 N ASP B 67 9589 13450 9995 197 1609 569 N
+ATOM 1202 CA ASP B 67 -40.677 -17.431 -3.312 1.00 90.53 C
+ANISOU 1202 CA ASP B 67 9811 13977 10608 358 1567 559 C
+ATOM 1203 C ASP B 67 -40.717 -15.891 -3.254 1.00 86.24 C
+ANISOU 1203 C ASP B 67 9333 13386 10046 784 1662 390 C
+ATOM 1204 O ASP B 67 -40.642 -15.233 -4.281 1.00 81.53 O
+ANISOU 1204 O ASP B 67 8742 12650 9585 940 1557 340 O
+ATOM 1205 CB ASP B 67 -42.050 -18.071 -3.552 1.00102.24 C
+ANISOU 1205 CB ASP B 67 10878 15858 12109 201 1632 735 C
+ATOM 1206 CG ASP B 67 -41.961 -19.594 -3.777 1.00110.12 C
+ANISOU 1206 CG ASP B 67 11890 16814 13135 -260 1502 895 C
+ATOM 1207 OD1 ASP B 67 -41.291 -20.027 -4.737 1.00 98.84 O
+ANISOU 1207 OD1 ASP B 67 10618 15101 11835 -390 1286 884 O
+ATOM 1208 OD2 ASP B 67 -42.569 -20.364 -2.992 1.00123.31 O
+ANISOU 1208 OD2 ASP B 67 13438 18728 14684 -494 1624 1033 O
+ATOM 1209 N GLU B 68 -40.822 -15.309 -2.066 1.00 91.45 N
+ANISOU 1209 N GLU B 68 10086 14137 10521 974 1859 301 N
+ATOM 1210 CA GLU B 68 -40.562 -13.877 -1.887 1.00 92.79 C
+ANISOU 1210 CA GLU B 68 10476 14135 10644 1350 1926 105 C
+ATOM 1211 C GLU B 68 -39.357 -13.490 -2.763 1.00 88.95 C
+ANISOU 1211 C GLU B 68 10277 13221 10296 1308 1700 12 C
+ATOM 1212 O GLU B 68 -39.451 -12.586 -3.592 1.00 86.77 O
+ANISOU 1212 O GLU B 68 10035 12811 10122 1529 1655 -46 O
+ATOM 1213 CB GLU B 68 -40.252 -13.581 -0.409 1.00103.28 C
+ANISOU 1213 CB GLU B 68 12042 15476 11725 1425 2090 -9 C
+ATOM 1214 CG GLU B 68 -39.658 -12.210 -0.110 1.00110.78 C
+ANISOU 1214 CG GLU B 68 13356 16139 12594 1717 2114 -242 C
+ATOM 1215 CD GLU B 68 -40.711 -11.114 -0.156 1.00127.27 C
+ANISOU 1215 CD GLU B 68 15344 18364 14648 2164 2303 -314 C
+ATOM 1216 OE1 GLU B 68 -41.594 -11.091 0.736 1.00128.34 O
+ANISOU 1216 OE1 GLU B 68 15322 18834 14608 2332 2547 -306 O
+ATOM 1217 OE2 GLU B 68 -40.658 -10.276 -1.086 1.00135.31 O
+ANISOU 1217 OE2 GLU B 68 16444 19164 15804 2367 2214 -371 O
+ATOM 1218 N GLN B 69 -38.246 -14.206 -2.567 1.00 72.49 N
+ANISOU 1218 N GLN B 69 8389 10950 8204 1029 1565 15 N
+ATOM 1219 CA GLN B 69 -36.950 -13.911 -3.200 1.00 73.21 C
+ANISOU 1219 CA GLN B 69 8740 10685 8389 958 1373 -72 C
+ATOM 1220 C GLN B 69 -36.830 -14.132 -4.727 1.00 65.48 C
+ANISOU 1220 C GLN B 69 7666 9593 7621 882 1203 -2 C
+ATOM 1221 O GLN B 69 -36.176 -13.383 -5.439 1.00 63.34 O
+ANISOU 1221 O GLN B 69 7557 9080 7428 951 1109 -83 O
+ATOM 1222 CB GLN B 69 -35.889 -14.744 -2.517 1.00 75.50 C
+ANISOU 1222 CB GLN B 69 9196 10892 8596 710 1285 -63 C
+ATOM 1223 CG GLN B 69 -35.602 -14.267 -1.103 1.00 78.45 C
+ANISOU 1223 CG GLN B 69 9777 11287 8741 786 1396 -180 C
+ATOM 1224 CD GLN B 69 -34.680 -15.215 -0.356 1.00 80.20 C
+ANISOU 1224 CD GLN B 69 10125 11490 8855 555 1301 -133 C
+ATOM 1225 OE1 GLN B 69 -34.695 -16.439 -0.569 1.00 76.67 O
+ANISOU 1225 OE1 GLN B 69 9569 11099 8460 360 1233 26 O
+ATOM 1226 NE2 GLN B 69 -33.869 -14.655 0.531 1.00 79.87 N
+ANISOU 1226 NE2 GLN B 69 10337 11359 8650 578 1283 -273 N
+ATOM 1227 N ILE B 70 -37.462 -15.169 -5.220 1.00 61.39 N
+ANISOU 1227 N ILE B 70 6901 9247 7174 715 1163 150 N
+ATOM 1228 CA ILE B 70 -37.598 -15.345 -6.623 1.00 62.15 C
+ANISOU 1228 CA ILE B 70 6889 9291 7432 668 1022 213 C
+ATOM 1229 C ILE B 70 -38.394 -14.186 -7.226 1.00 73.71 C
+ANISOU 1229 C ILE B 70 8249 10811 8945 974 1070 184 C
+ATOM 1230 O ILE B 70 -37.990 -13.601 -8.254 1.00 73.86 O
+ANISOU 1230 O ILE B 70 8375 10629 9058 1051 959 151 O
+ATOM 1231 CB ILE B 70 -38.275 -16.689 -6.902 1.00 63.18 C
+ANISOU 1231 CB ILE B 70 6790 9618 7596 406 976 375 C
+ATOM 1232 CG1 ILE B 70 -37.310 -17.798 -6.413 1.00 66.78 C
+ANISOU 1232 CG1 ILE B 70 7440 9927 8005 147 902 402 C
+ATOM 1233 CG2 ILE B 70 -38.638 -16.782 -8.387 1.00 57.25 C
+ANISOU 1233 CG2 ILE B 70 5905 8860 6984 377 830 431 C
+ATOM 1234 CD1 ILE B 70 -37.651 -19.227 -6.791 1.00 70.61 C
+ANISOU 1234 CD1 ILE B 70 7840 10465 8522 -155 814 547 C
+ATOM 1235 N GLY B 71 -39.521 -13.852 -6.588 1.00 75.76 N
+ANISOU 1235 N GLY B 71 8304 11355 9126 1166 1244 206 N
+ATOM 1236 CA GLY B 71 -40.376 -12.761 -7.036 1.00 72.95 C
+ANISOU 1236 CA GLY B 71 7834 11088 8796 1528 1307 188 C
+ATOM 1237 C GLY B 71 -39.624 -11.447 -7.147 1.00 76.38 C
+ANISOU 1237 C GLY B 71 8635 11163 9222 1770 1297 33 C
+ATOM 1238 O GLY B 71 -39.883 -10.642 -8.039 1.00 79.14 O
+ANISOU 1238 O GLY B 71 9008 11417 9641 1993 1244 36 O
+ATOM 1239 N GLU B 72 -38.660 -11.230 -6.267 1.00 77.34 N
+ANISOU 1239 N GLU B 72 9065 11073 9246 1700 1332 -94 N
+ATOM 1240 CA GLU B 72 -37.776 -10.071 -6.409 1.00 82.72 C
+ANISOU 1240 CA GLU B 72 10132 11378 9918 1818 1290 -240 C
+ATOM 1241 C GLU B 72 -36.680 -10.326 -7.459 1.00 73.65 C
+ANISOU 1241 C GLU B 72 9106 9983 8893 1567 1086 -215 C
+ATOM 1242 O GLU B 72 -35.725 -9.562 -7.537 1.00 70.35 O
+ANISOU 1242 O GLU B 72 8999 9266 8462 1543 1035 -321 O
+ATOM 1243 CB GLU B 72 -37.154 -9.705 -5.053 1.00 94.77 C
+ANISOU 1243 CB GLU B 72 11940 12798 11270 1810 1386 -397 C
+ATOM 1244 CG GLU B 72 -38.118 -9.911 -3.884 1.00110.12 C
+ANISOU 1244 CG GLU B 72 13720 15060 13058 1957 1598 -397 C
+ATOM 1245 CD GLU B 72 -37.932 -8.936 -2.746 1.00125.11 C
+ANISOU 1245 CD GLU B 72 15946 16831 14757 2160 1737 -591 C
+ATOM 1246 OE1 GLU B 72 -38.918 -8.231 -2.409 1.00134.61 O
+ANISOU 1246 OE1 GLU B 72 17112 18158 15874 2531 1921 -638 O
+ATOM 1247 OE2 GLU B 72 -36.813 -8.896 -2.185 1.00125.40 O
+ANISOU 1247 OE2 GLU B 72 16271 16663 14709 1956 1661 -698 O
+ATOM 1248 N GLY B 73 -36.799 -11.410 -8.233 1.00 65.49 N
+ANISOU 1248 N GLY B 73 7839 9083 7962 1362 977 -81 N
+ATOM 1249 CA GLY B 73 -35.815 -11.747 -9.280 1.00 62.64 C
+ANISOU 1249 CA GLY B 73 7570 8528 7700 1152 805 -56 C
+ATOM 1250 C GLY B 73 -34.511 -12.432 -8.913 1.00 64.69 C
+ANISOU 1250 C GLY B 73 7964 8676 7938 882 732 -95 C
+ATOM 1251 O GLY B 73 -33.621 -12.552 -9.759 1.00 61.13 O
+ANISOU 1251 O GLY B 73 7598 8075 7554 753 615 -91 O
+ATOM 1252 N PHE B 74 -34.380 -12.937 -7.687 1.00 63.75 N
+ANISOU 1252 N PHE B 74 7851 8656 7716 805 798 -121 N
+ATOM 1253 CA PHE B 74 -33.146 -13.627 -7.305 1.00 53.01 C
+ANISOU 1253 CA PHE B 74 6598 7217 6322 587 711 -142 C
+ATOM 1254 C PHE B 74 -32.988 -14.972 -7.975 1.00 47.15 C
+ANISOU 1254 C PHE B 74 5729 6525 5658 405 605 -25 C
+ATOM 1255 O PHE B 74 -33.925 -15.691 -8.210 1.00 47.19 O
+ANISOU 1255 O PHE B 74 5555 6679 5693 369 619 77 O
+ATOM 1256 CB PHE B 74 -33.033 -13.757 -5.799 1.00 57.58 C
+ANISOU 1256 CB PHE B 74 7252 7883 6742 571 795 -193 C
+ATOM 1257 CG PHE B 74 -32.721 -12.455 -5.116 1.00 62.39 C
+ANISOU 1257 CG PHE B 74 8094 8364 7244 697 859 -353 C
+ATOM 1258 CD1 PHE B 74 -31.451 -11.886 -5.228 1.00 64.10 C
+ANISOU 1258 CD1 PHE B 74 8521 8379 7455 591 755 -452 C
+ATOM 1259 CD2 PHE B 74 -33.694 -11.780 -4.360 1.00 68.55 C
+ANISOU 1259 CD2 PHE B 74 8895 9233 7917 917 1026 -411 C
+ATOM 1260 CE1 PHE B 74 -31.155 -10.674 -4.606 1.00 68.98 C
+ANISOU 1260 CE1 PHE B 74 9402 8846 7962 659 796 -610 C
+ATOM 1261 CE2 PHE B 74 -33.400 -10.578 -3.721 1.00 69.76 C
+ANISOU 1261 CE2 PHE B 74 9331 9224 7950 1040 1082 -581 C
+ATOM 1262 CZ PHE B 74 -32.132 -10.015 -3.852 1.00 73.33 C
+ANISOU 1262 CZ PHE B 74 10030 9434 8398 891 957 -683 C
+ATOM 1263 N VAL B 75 -31.754 -15.313 -8.293 1.00 47.62 N
+ANISOU 1263 N VAL B 75 5890 6460 5740 284 497 -46 N
+ATOM 1264 CA VAL B 75 -31.467 -16.527 -9.040 1.00 46.67 C
+ANISOU 1264 CA VAL B 75 5712 6336 5685 155 395 39 C
+ATOM 1265 C VAL B 75 -30.245 -17.245 -8.471 1.00 44.46 C
+ANISOU 1265 C VAL B 75 5526 6018 5347 63 327 28 C
+ATOM 1266 O VAL B 75 -29.283 -16.611 -8.088 1.00 45.81 O
+ANISOU 1266 O VAL B 75 5789 6141 5474 68 309 -55 O
+ATOM 1267 CB VAL B 75 -31.345 -16.225 -10.573 1.00 48.40 C
+ANISOU 1267 CB VAL B 75 5921 6459 6009 172 323 45 C
+ATOM 1268 CG1 VAL B 75 -30.229 -15.219 -10.891 1.00 49.82 C
+ANISOU 1268 CG1 VAL B 75 6236 6497 6194 190 302 -42 C
+ATOM 1269 CG2 VAL B 75 -31.192 -17.513 -11.372 1.00 52.32 C
+ANISOU 1269 CG2 VAL B 75 6386 6945 6547 57 228 117 C
+ATOM 1270 N LEU B 76 -30.313 -18.572 -8.356 1.00 47.02 N
+ANISOU 1270 N LEU B 76 5836 6371 5658 -24 284 120 N
+ATOM 1271 CA LEU B 76 -29.121 -19.328 -8.132 1.00 46.01 C
+ANISOU 1271 CA LEU B 76 5797 6192 5492 -56 197 127 C
+ATOM 1272 C LEU B 76 -28.512 -19.742 -9.476 1.00 40.71 C
+ANISOU 1272 C LEU B 76 5131 5424 4910 -54 113 128 C
+ATOM 1273 O LEU B 76 -29.048 -20.600 -10.147 1.00 46.45 O
+ANISOU 1273 O LEU B 76 5862 6109 5676 -101 81 191 O
+ATOM 1274 CB LEU B 76 -29.384 -20.509 -7.221 1.00 47.02 C
+ANISOU 1274 CB LEU B 76 5975 6357 5531 -120 195 227 C
+ATOM 1275 CG LEU B 76 -30.003 -20.207 -5.836 1.00 48.21 C
+ANISOU 1275 CG LEU B 76 6126 6635 5556 -128 299 239 C
+ATOM 1276 CD1 LEU B 76 -30.102 -21.517 -5.059 1.00 49.81 C
+ANISOU 1276 CD1 LEU B 76 6416 6849 5659 -217 281 368 C
+ATOM 1277 CD2 LEU B 76 -29.254 -19.158 -5.030 1.00 49.77 C
+ANISOU 1277 CD2 LEU B 76 6382 6864 5663 -57 312 121 C
+ATOM 1278 N THR B 77 -27.369 -19.136 -9.812 1.00 41.43 N
+ANISOU 1278 N THR B 77 5232 5494 5012 -17 79 55 N
+ATOM 1279 CA THR B 77 -26.727 -19.284 -11.128 1.00 40.67 C
+ANISOU 1279 CA THR B 77 5128 5343 4981 1 33 43 C
+ATOM 1280 C THR B 77 -26.271 -20.689 -11.435 1.00 44.46 C
+ANISOU 1280 C THR B 77 5663 5781 5447 32 -31 92 C
+ATOM 1281 O THR B 77 -26.273 -21.097 -12.621 1.00 45.14 O
+ANISOU 1281 O THR B 77 5776 5802 5573 48 -54 93 O
+ATOM 1282 CB THR B 77 -25.599 -18.252 -11.327 1.00 45.56 C
+ANISOU 1282 CB THR B 77 5722 5989 5598 -3 32 -32 C
+ATOM 1283 OG1 THR B 77 -24.616 -18.284 -10.248 1.00 43.74 O
+ANISOU 1283 OG1 THR B 77 5481 5849 5287 -11 -5 -59 O
+ATOM 1284 CG2 THR B 77 -26.220 -16.863 -11.400 1.00 41.29 C
+ANISOU 1284 CG2 THR B 77 5203 5403 5080 -24 94 -78 C
+ATOM 1285 N CYS B 78 -25.967 -21.485 -10.393 1.00 45.27 N
+ANISOU 1285 N CYS B 78 5822 5901 5476 54 -62 136 N
+ATOM 1286 CA CYS B 78 -25.538 -22.878 -10.640 1.00 40.58 C
+ANISOU 1286 CA CYS B 78 5341 5220 4856 123 -127 189 C
+ATOM 1287 C CYS B 78 -26.708 -23.807 -10.971 1.00 41.12 C
+ANISOU 1287 C CYS B 78 5522 5162 4939 26 -135 258 C
+ATOM 1288 O CYS B 78 -26.504 -24.884 -11.423 1.00 43.05 O
+ANISOU 1288 O CYS B 78 5913 5275 5166 63 -188 285 O
+ATOM 1289 CB CYS B 78 -24.806 -23.414 -9.415 1.00 46.97 C
+ANISOU 1289 CB CYS B 78 6199 6078 5566 196 -175 233 C
+ATOM 1290 SG CYS B 78 -25.953 -23.849 -8.071 1.00 49.40 S
+ANISOU 1290 SG CYS B 78 6603 6375 5792 77 -143 334 S
+ATOM 1291 N ALA B 79 -27.946 -23.393 -10.780 1.00 44.78 N
+ANISOU 1291 N ALA B 79 5918 5669 5425 -101 -84 285 N
+ATOM 1292 CA ALA B 79 -29.075 -24.281 -11.005 1.00 47.60 C
+ANISOU 1292 CA ALA B 79 6343 5956 5784 -250 -101 364 C
+ATOM 1293 C ALA B 79 -30.185 -23.636 -11.871 1.00 49.22 C
+ANISOU 1293 C ALA B 79 6406 6233 6061 -337 -80 350 C
+ATOM 1294 O ALA B 79 -31.381 -24.008 -11.779 1.00 50.46 O
+ANISOU 1294 O ALA B 79 6514 6441 6216 -497 -73 423 O
+ATOM 1295 CB ALA B 79 -29.642 -24.689 -9.663 1.00 51.35 C
+ANISOU 1295 CB ALA B 79 6846 6483 6181 -345 -59 459 C
+ATOM 1296 N ALA B 80 -29.766 -22.691 -12.710 1.00 47.73 N
+ANISOU 1296 N ALA B 80 6146 6065 5924 -239 -75 270 N
+ATOM 1297 CA ALA B 80 -30.656 -21.820 -13.483 1.00 47.79 C
+ANISOU 1297 CA ALA B 80 6019 6149 5986 -255 -60 260 C
+ATOM 1298 C ALA B 80 -30.291 -21.968 -14.960 1.00 45.38 C
+ANISOU 1298 C ALA B 80 5782 5759 5701 -235 -129 220 C
+ATOM 1299 O ALA B 80 -29.179 -21.667 -15.325 1.00 42.72 O
+ANISOU 1299 O ALA B 80 5492 5381 5359 -133 -121 162 O
+ATOM 1300 CB ALA B 80 -30.480 -20.367 -13.042 1.00 44.94 C
+ANISOU 1300 CB ALA B 80 5565 5866 5641 -146 20 209 C
+ATOM 1301 N TYR B 81 -31.241 -22.453 -15.772 1.00 45.42 N
+ANISOU 1301 N TYR B 81 5782 5764 5709 -349 -198 253 N
+ATOM 1302 CA TYR B 81 -31.175 -22.431 -17.214 1.00 43.03 C
+ANISOU 1302 CA TYR B 81 5534 5415 5397 -340 -266 217 C
+ATOM 1303 C TYR B 81 -31.816 -21.180 -17.774 1.00 44.38 C
+ANISOU 1303 C TYR B 81 5553 5705 5604 -286 -255 229 C
+ATOM 1304 O TYR B 81 -32.869 -20.780 -17.277 1.00 44.18 O
+ANISOU 1304 O TYR B 81 5365 5812 5607 -312 -236 284 O
+ATOM 1305 CB TYR B 81 -31.969 -23.595 -17.812 1.00 42.89 C
+ANISOU 1305 CB TYR B 81 5610 5343 5342 -522 -376 244 C
+ATOM 1306 CG TYR B 81 -31.528 -24.936 -17.365 1.00 42.13 C
+ANISOU 1306 CG TYR B 81 5733 5076 5198 -585 -404 245 C
+ATOM 1307 CD1 TYR B 81 -30.314 -25.445 -17.790 1.00 44.66 C
+ANISOU 1307 CD1 TYR B 81 6255 5239 5473 -442 -407 173 C
+ATOM 1308 CD2 TYR B 81 -32.339 -25.734 -16.540 1.00 48.75 C
+ANISOU 1308 CD2 TYR B 81 6588 5909 6023 -781 -423 329 C
+ATOM 1309 CE1 TYR B 81 -29.894 -26.718 -17.417 1.00 43.35 C
+ANISOU 1309 CE1 TYR B 81 6335 4883 5252 -447 -440 177 C
+ATOM 1310 CE2 TYR B 81 -31.956 -27.041 -16.215 1.00 49.19 C
+ANISOU 1310 CE2 TYR B 81 6919 5750 6019 -844 -464 343 C
+ATOM 1311 CZ TYR B 81 -30.702 -27.516 -16.640 1.00 48.71 C
+ANISOU 1311 CZ TYR B 81 7087 5502 5916 -648 -475 264 C
+ATOM 1312 OH TYR B 81 -30.184 -28.775 -16.265 1.00 52.95 O
+ANISOU 1312 OH TYR B 81 7931 5800 6387 -626 -510 278 O
+ATOM 1313 N PRO B 82 -31.222 -20.582 -18.851 1.00 42.24 N
+ANISOU 1313 N PRO B 82 5338 5394 5317 -199 -264 189 N
+ATOM 1314 CA PRO B 82 -31.916 -19.427 -19.426 1.00 43.63 C
+ANISOU 1314 CA PRO B 82 5410 5655 5512 -135 -271 223 C
+ATOM 1315 C PRO B 82 -33.193 -19.929 -20.110 1.00 42.47 C
+ANISOU 1315 C PRO B 82 5186 5607 5344 -243 -390 277 C
+ATOM 1316 O PRO B 82 -33.182 -21.018 -20.729 1.00 43.18 O
+ANISOU 1316 O PRO B 82 5392 5637 5378 -371 -481 256 O
+ATOM 1317 CB PRO B 82 -30.922 -18.885 -20.482 1.00 44.26 C
+ANISOU 1317 CB PRO B 82 5608 5658 5550 -62 -258 186 C
+ATOM 1318 CG PRO B 82 -29.978 -19.997 -20.799 1.00 44.00 C
+ANISOU 1318 CG PRO B 82 5714 5541 5462 -94 -268 127 C
+ATOM 1319 CD PRO B 82 -30.010 -20.955 -19.610 1.00 43.22 C
+ANISOU 1319 CD PRO B 82 5616 5415 5388 -148 -264 126 C
+ATOM 1320 N THR B 83 -34.264 -19.156 -20.049 1.00 43.35 N
+ANISOU 1320 N THR B 83 5114 5871 5484 -188 -400 342 N
+ATOM 1321 CA THR B 83 -35.417 -19.426 -20.932 1.00 48.62 C
+ANISOU 1321 CA THR B 83 5669 6684 6117 -276 -540 401 C
+ATOM 1322 C THR B 83 -35.748 -18.249 -21.876 1.00 46.65 C
+ANISOU 1322 C THR B 83 5378 6497 5848 -103 -583 444 C
+ATOM 1323 O THR B 83 -36.739 -18.269 -22.580 1.00 52.22 O
+ANISOU 1323 O THR B 83 5955 7366 6519 -132 -710 507 O
+ATOM 1324 CB THR B 83 -36.648 -19.794 -20.074 1.00 51.91 C
+ANISOU 1324 CB THR B 83 5841 7312 6568 -382 -542 472 C
+ATOM 1325 OG1 THR B 83 -36.869 -18.747 -19.119 1.00 51.49 O
+ANISOU 1325 OG1 THR B 83 5651 7343 6568 -184 -407 493 O
+ATOM 1326 CG2 THR B 83 -36.374 -21.131 -19.339 1.00 48.25 C
+ANISOU 1326 CG2 THR B 83 5482 6756 6094 -602 -531 453 C
+ATOM 1327 N SER B 84 -34.922 -17.220 -21.872 1.00 49.15 N
+ANISOU 1327 N SER B 84 5810 6685 6177 63 -486 421 N
+ATOM 1328 CA SER B 84 -34.968 -16.169 -22.893 1.00 47.46 C
+ANISOU 1328 CA SER B 84 5660 6452 5920 210 -525 469 C
+ATOM 1329 C SER B 84 -33.560 -15.596 -22.849 1.00 44.74 C
+ANISOU 1329 C SER B 84 5522 5905 5571 249 -408 413 C
+ATOM 1330 O SER B 84 -32.757 -15.991 -21.985 1.00 42.92 O
+ANISOU 1330 O SER B 84 5325 5604 5377 186 -319 344 O
+ATOM 1331 CB SER B 84 -35.999 -15.072 -22.468 1.00 52.98 C
+ANISOU 1331 CB SER B 84 6195 7271 6664 424 -504 546 C
+ATOM 1332 OG SER B 84 -35.478 -14.259 -21.372 1.00 56.24 O
+ANISOU 1332 OG SER B 84 6673 7559 7133 543 -346 502 O
+ATOM 1333 N ASP B 85 -33.263 -14.621 -23.694 1.00 42.09 N
+ANISOU 1333 N ASP B 85 5315 5491 5184 344 -407 456 N
+ATOM 1334 CA ASP B 85 -32.096 -13.779 -23.472 1.00 44.39 C
+ANISOU 1334 CA ASP B 85 5767 5616 5481 363 -284 426 C
+ATOM 1335 C ASP B 85 -32.367 -13.068 -22.174 1.00 44.33 C
+ANISOU 1335 C ASP B 85 5710 5574 5557 461 -200 408 C
+ATOM 1336 O ASP B 85 -33.473 -12.654 -21.914 1.00 44.74 O
+ANISOU 1336 O ASP B 85 5658 5704 5635 607 -226 457 O
+ATOM 1337 CB ASP B 85 -31.910 -12.741 -24.580 1.00 50.33 C
+ANISOU 1337 CB ASP B 85 6690 6279 6153 434 -297 505 C
+ATOM 1338 CG ASP B 85 -31.692 -13.380 -25.963 1.00 53.63 C
+ANISOU 1338 CG ASP B 85 7180 6749 6447 352 -376 524 C
+ATOM 1339 OD1 ASP B 85 -31.204 -14.529 -26.022 1.00 47.82 O
+ANISOU 1339 OD1 ASP B 85 6425 6053 5688 233 -377 444 O
+ATOM 1340 OD2 ASP B 85 -32.060 -12.736 -26.984 1.00 54.69 O
+ANISOU 1340 OD2 ASP B 85 7411 6877 6491 428 -443 619 O
+ATOM 1341 N VAL B 86 -31.347 -12.922 -21.361 1.00 40.17 N
+ANISOU 1341 N VAL B 86 5253 4953 5056 392 -100 335 N
+ATOM 1342 CA VAL B 86 -31.545 -12.627 -20.001 1.00 40.95 C
+ANISOU 1342 CA VAL B 86 5304 5044 5208 443 -28 288 C
+ATOM 1343 C VAL B 86 -30.338 -11.876 -19.512 1.00 40.30 C
+ANISOU 1343 C VAL B 86 5380 4811 5117 374 55 227 C
+ATOM 1344 O VAL B 86 -29.225 -12.135 -19.945 1.00 43.19 O
+ANISOU 1344 O VAL B 86 5796 5158 5455 238 66 208 O
+ATOM 1345 CB VAL B 86 -31.795 -13.954 -19.226 1.00 47.21 C
+ANISOU 1345 CB VAL B 86 5933 5975 6029 355 -41 254 C
+ATOM 1346 CG1 VAL B 86 -30.588 -14.864 -19.281 1.00 53.03 C
+ANISOU 1346 CG1 VAL B 86 6718 6685 6745 209 -38 201 C
+ATOM 1347 CG2 VAL B 86 -32.149 -13.690 -17.770 1.00 54.18 C
+ANISOU 1347 CG2 VAL B 86 6757 6889 6939 415 40 215 C
+ATOM 1348 N THR B 87 -30.567 -10.923 -18.633 1.00 40.44 N
+ANISOU 1348 N THR B 87 5478 4736 5147 466 116 194 N
+ATOM 1349 CA THR B 87 -29.526 -10.137 -17.998 1.00 44.61 C
+ANISOU 1349 CA THR B 87 6175 5117 5656 367 180 122 C
+ATOM 1350 C THR B 87 -29.555 -10.459 -16.518 1.00 45.83 C
+ANISOU 1350 C THR B 87 6259 5336 5818 364 223 34 C
+ATOM 1351 O THR B 87 -30.627 -10.480 -15.920 1.00 50.57 O
+ANISOU 1351 O THR B 87 6782 6002 6428 521 248 34 O
+ATOM 1352 CB THR B 87 -29.811 -8.653 -18.240 1.00 48.52 C
+ANISOU 1352 CB THR B 87 6913 5392 6126 483 206 148 C
+ATOM 1353 OG1 THR B 87 -29.766 -8.415 -19.647 1.00 50.14 O
+ANISOU 1353 OG1 THR B 87 7196 5550 6304 478 160 251 O
+ATOM 1354 CG2 THR B 87 -28.775 -7.748 -17.578 1.00 51.37 C
+ANISOU 1354 CG2 THR B 87 7497 5567 6453 330 258 66 C
+ATOM 1355 N ILE B 88 -28.383 -10.757 -15.950 1.00 46.15 N
+ANISOU 1355 N ILE B 88 6302 5394 5839 188 231 -31 N
+ATOM 1356 CA ILE B 88 -28.248 -11.202 -14.561 1.00 48.38 C
+ANISOU 1356 CA ILE B 88 6524 5758 6100 163 252 -105 C
+ATOM 1357 C ILE B 88 -27.148 -10.356 -13.868 1.00 49.51 C
+ANISOU 1357 C ILE B 88 6821 5800 6187 17 267 -195 C
+ATOM 1358 O ILE B 88 -26.006 -10.333 -14.336 1.00 50.31 O
+ANISOU 1358 O ILE B 88 6922 5912 6279 -155 240 -192 O
+ATOM 1359 CB ILE B 88 -27.854 -12.697 -14.495 1.00 47.16 C
+ANISOU 1359 CB ILE B 88 6193 5770 5956 88 209 -84 C
+ATOM 1360 CG1 ILE B 88 -29.028 -13.550 -14.899 1.00 45.49 C
+ANISOU 1360 CG1 ILE B 88 5857 5647 5780 178 185 -12 C
+ATOM 1361 CG2 ILE B 88 -27.449 -13.095 -13.075 1.00 50.06 C
+ANISOU 1361 CG2 ILE B 88 6533 6211 6275 43 217 -145 C
+ATOM 1362 CD1 ILE B 88 -28.663 -14.921 -15.331 1.00 44.53 C
+ANISOU 1362 CD1 ILE B 88 5652 5603 5664 105 128 18 C
+ATOM 1363 N GLU B 89 -27.473 -9.703 -12.758 1.00 53.87 N
+ANISOU 1363 N GLU B 89 7496 6283 6689 72 309 -278 N
+ATOM 1364 CA GLU B 89 -26.437 -9.087 -11.897 1.00 55.06 C
+ANISOU 1364 CA GLU B 89 7788 6369 6762 -106 296 -383 C
+ATOM 1365 C GLU B 89 -25.875 -10.173 -10.991 1.00 50.59 C
+ANISOU 1365 C GLU B 89 7047 6015 6159 -183 255 -407 C
+ATOM 1366 O GLU B 89 -26.632 -10.952 -10.372 1.00 53.81 O
+ANISOU 1366 O GLU B 89 7350 6536 6558 -58 279 -389 O
+ATOM 1367 CB GLU B 89 -26.978 -7.962 -10.983 1.00 64.61 C
+ANISOU 1367 CB GLU B 89 9255 7398 7894 -8 353 -489 C
+ATOM 1368 CG GLU B 89 -27.906 -6.925 -11.597 1.00 75.35 C
+ANISOU 1368 CG GLU B 89 10817 8537 9275 195 408 -466 C
+ATOM 1369 CD GLU B 89 -28.548 -5.964 -10.562 1.00 82.40 C
+ANISOU 1369 CD GLU B 89 11968 9264 10073 373 485 -588 C
+ATOM 1370 OE1 GLU B 89 -29.068 -6.404 -9.504 1.00 81.15 O
+ANISOU 1370 OE1 GLU B 89 11720 9254 9857 488 538 -645 O
+ATOM 1371 OE2 GLU B 89 -28.574 -4.751 -10.836 1.00 78.16 O
+ANISOU 1371 OE2 GLU B 89 11754 8436 9505 415 502 -623 O
+ATOM 1372 N THR B 90 -24.559 -10.217 -10.878 1.00 51.58 N
+ANISOU 1372 N THR B 90 7135 6210 6250 -392 193 -434 N
+ATOM 1373 CA THR B 90 -23.886 -11.258 -10.104 1.00 50.76 C
+ANISOU 1373 CA THR B 90 6862 6321 6103 -439 132 -438 C
+ATOM 1374 C THR B 90 -23.428 -10.795 -8.698 1.00 54.51 C
+ANISOU 1374 C THR B 90 7442 6820 6450 -544 93 -549 C
+ATOM 1375 O THR B 90 -23.592 -9.656 -8.337 1.00 56.29 O
+ANISOU 1375 O THR B 90 7894 6876 6618 -596 118 -640 O
+ATOM 1376 CB THR B 90 -22.680 -11.779 -10.880 1.00 51.05 C
+ANISOU 1376 CB THR B 90 6727 6500 6170 -558 78 -385 C
+ATOM 1377 OG1 THR B 90 -21.707 -10.743 -11.014 1.00 54.51 O
+ANISOU 1377 OG1 THR B 90 7235 6905 6570 -789 55 -432 O
+ATOM 1378 CG2 THR B 90 -23.111 -12.265 -12.264 1.00 50.66 C
+ANISOU 1378 CG2 THR B 90 6610 6424 6212 -455 115 -293 C
+ATOM 1379 N HIS B 91 -22.903 -11.730 -7.904 1.00 57.41 N
+ANISOU 1379 N HIS B 91 7670 7387 6755 -556 26 -538 N
+ATOM 1380 CA HIS B 91 -22.350 -11.451 -6.562 1.00 53.16 C
+ANISOU 1380 CA HIS B 91 7206 6925 6066 -666 -42 -633 C
+ATOM 1381 C HIS B 91 -23.379 -10.865 -5.635 1.00 52.82 C
+ANISOU 1381 C HIS B 91 7383 6755 5930 -566 36 -720 C
+ATOM 1382 O HIS B 91 -23.140 -9.839 -5.055 1.00 57.23 O
+ANISOU 1382 O HIS B 91 8152 7207 6385 -681 21 -845 O
+ATOM 1383 CB HIS B 91 -21.120 -10.564 -6.646 1.00 52.81 C
+ANISOU 1383 CB HIS B 91 7193 6894 5976 -939 -126 -702 C
+ATOM 1384 CG HIS B 91 -19.981 -11.185 -7.409 1.00 56.19 C
+ANISOU 1384 CG HIS B 91 7349 7534 6464 -1027 -193 -617 C
+ATOM 1385 ND1 HIS B 91 -20.029 -11.423 -8.768 1.00 58.74 N
+ANISOU 1385 ND1 HIS B 91 7574 7829 6914 -972 -131 -528 N
+ATOM 1386 CD2 HIS B 91 -18.759 -11.596 -7.006 1.00 57.11 C
+ANISOU 1386 CD2 HIS B 91 7263 7919 6514 -1145 -312 -608 C
+ATOM 1387 CE1 HIS B 91 -18.883 -11.936 -9.173 1.00 56.30 C
+ANISOU 1387 CE1 HIS B 91 7023 7755 6612 -1044 -186 -477 C
+ATOM 1388 NE2 HIS B 91 -18.094 -12.046 -8.123 1.00 61.01 N
+ANISOU 1388 NE2 HIS B 91 7535 8546 7100 -1142 -299 -520 N
+ATOM 1389 N LYS B 92 -24.532 -11.528 -5.533 1.00 51.89 N
+ANISOU 1389 N LYS B 92 7218 6656 5842 -359 126 -655 N
+ATOM 1390 CA LYS B 92 -25.686 -11.045 -4.764 1.00 55.84 C
+ANISOU 1390 CA LYS B 92 7874 7083 6259 -208 243 -719 C
+ATOM 1391 C LYS B 92 -25.938 -11.835 -3.472 1.00 58.34 C
+ANISOU 1391 C LYS B 92 8162 7572 6430 -160 255 -708 C
+ATOM 1392 O LYS B 92 -26.959 -11.637 -2.823 1.00 58.98 O
+ANISOU 1392 O LYS B 92 8322 7655 6430 -18 378 -739 O
+ATOM 1393 CB LYS B 92 -26.964 -11.067 -5.656 1.00 58.46 C
+ANISOU 1393 CB LYS B 92 8144 7346 6720 -12 355 -640 C
+ATOM 1394 CG LYS B 92 -26.997 -9.991 -6.743 1.00 61.75 C
+ANISOU 1394 CG LYS B 92 8682 7550 7230 -3 369 -662 C
+ATOM 1395 CD LYS B 92 -26.411 -8.664 -6.237 1.00 67.88 C
+ANISOU 1395 CD LYS B 92 9757 8134 7899 -115 352 -813 C
+ATOM 1396 CE LYS B 92 -26.933 -7.436 -6.946 1.00 70.75 C
+ANISOU 1396 CE LYS B 92 10351 8225 8305 -10 414 -844 C
+ATOM 1397 NZ LYS B 92 -28.067 -6.929 -6.119 1.00 81.14 N
+ANISOU 1397 NZ LYS B 92 11822 9481 9525 253 540 -928 N
+ATOM 1398 N GLU B 93 -25.011 -12.712 -3.102 1.00 57.86 N
+ANISOU 1398 N GLU B 93 7989 7669 6322 -262 135 -655 N
+ATOM 1399 CA GLU B 93 -25.136 -13.464 -1.883 1.00 65.82 C
+ANISOU 1399 CA GLU B 93 9004 8833 7172 -230 128 -625 C
+ATOM 1400 C GLU B 93 -25.494 -12.505 -0.726 1.00 69.11 C
+ANISOU 1400 C GLU B 93 9655 9212 7388 -218 194 -777 C
+ATOM 1401 O GLU B 93 -26.466 -12.735 -0.015 1.00 63.37 O
+ANISOU 1401 O GLU B 93 8970 8546 6562 -93 320 -761 O
+ATOM 1402 CB GLU B 93 -23.834 -14.222 -1.595 1.00 65.64 C
+ANISOU 1402 CB GLU B 93 8876 8968 7096 -333 -46 -573 C
+ATOM 1403 CG GLU B 93 -23.788 -14.779 -0.175 1.00 79.13 C
+ANISOU 1403 CG GLU B 93 10652 10826 8585 -318 -84 -555 C
+ATOM 1404 CD GLU B 93 -22.987 -16.055 -0.039 1.00 76.96 C
+ANISOU 1404 CD GLU B 93 10243 10705 8292 -298 -222 -415 C
+ATOM 1405 OE1 GLU B 93 -21.780 -16.023 -0.371 1.00 79.66 O
+ANISOU 1405 OE1 GLU B 93 10469 11135 8663 -371 -367 -426 O
+ATOM 1406 OE2 GLU B 93 -23.601 -17.080 0.373 1.00 67.00 O
+ANISOU 1406 OE2 GLU B 93 8994 9478 6985 -203 -176 -287 O
+ATOM 1407 N GLU B 94 -24.725 -11.432 -0.566 1.00 69.03 N
+ANISOU 1407 N GLU B 94 9811 9108 7309 -360 117 -926 N
+ATOM 1408 CA GLU B 94 -24.928 -10.483 0.552 1.00 77.95 C
+ANISOU 1408 CA GLU B 94 11229 10170 8216 -366 159 -1102 C
+ATOM 1409 C GLU B 94 -26.428 -10.119 0.763 1.00 81.07 C
+ANISOU 1409 C GLU B 94 11734 10485 8584 -108 385 -1134 C
+ATOM 1410 O GLU B 94 -26.904 -10.013 1.908 1.00 85.54 O
+ANISOU 1410 O GLU B 94 12445 11120 8935 -23 471 -1211 O
+ATOM 1411 CB GLU B 94 -24.036 -9.252 0.313 1.00 87.19 C
+ANISOU 1411 CB GLU B 94 12594 11164 9368 -580 56 -1254 C
+ATOM 1412 CG GLU B 94 -24.432 -7.953 1.012 1.00106.45 C
+ANISOU 1412 CG GLU B 94 15427 13387 11633 -560 129 -1466 C
+ATOM 1413 CD GLU B 94 -23.735 -7.773 2.341 1.00110.68 C
+ANISOU 1413 CD GLU B 94 16139 14025 11889 -732 8 -1602 C
+ATOM 1414 OE1 GLU B 94 -22.649 -8.362 2.521 1.00117.37 O
+ANISOU 1414 OE1 GLU B 94 16802 15085 12706 -936 -180 -1543 O
+ATOM 1415 OE2 GLU B 94 -24.273 -7.047 3.196 1.00115.53 O
+ANISOU 1415 OE2 GLU B 94 17075 14520 12301 -644 98 -1769 O
+ATOM 1416 N ALA B 95 -27.170 -9.967 -0.337 1.00 78.47 N
+ANISOU 1416 N ALA B 95 11311 10048 8454 26 480 -1068 N
+ATOM 1417 CA ALA B 95 -28.574 -9.572 -0.290 1.00 77.65 C
+ANISOU 1417 CA ALA B 95 11250 9907 8344 296 683 -1084 C
+ATOM 1418 C ALA B 95 -29.499 -10.685 0.182 1.00 81.60 C
+ANISOU 1418 C ALA B 95 11531 10661 8809 409 797 -947 C
+ATOM 1419 O ALA B 95 -30.560 -10.398 0.728 1.00 86.75 O
+ANISOU 1419 O ALA B 95 12220 11380 9361 612 978 -982 O
+ATOM 1420 CB ALA B 95 -29.025 -9.052 -1.654 1.00 73.64 C
+ANISOU 1420 CB ALA B 95 10698 9230 8050 400 717 -1040 C
+ATOM 1421 N ILE B 96 -29.102 -11.941 -0.054 1.00 86.66 N
+ANISOU 1421 N ILE B 96 11957 11441 9527 280 698 -787 N
+ATOM 1422 CA ILE B 96 -29.871 -13.143 0.330 1.00 86.56 C
+ANISOU 1422 CA ILE B 96 11762 11641 9485 314 780 -627 C
+ATOM 1423 C ILE B 96 -29.477 -13.617 1.721 1.00 84.77 C
+ANISOU 1423 C ILE B 96 11641 11556 9011 242 759 -633 C
+ATOM 1424 O ILE B 96 -29.685 -14.761 2.056 1.00 83.12 O
+ANISOU 1424 O ILE B 96 11324 11491 8764 195 764 -478 O
+ATOM 1425 CB ILE B 96 -29.623 -14.323 -0.663 1.00 90.19 C
+ANISOU 1425 CB ILE B 96 12007 12122 10139 213 673 -451 C
+ATOM 1426 CG1 ILE B 96 -30.006 -13.941 -2.082 1.00 90.30 C
+ANISOU 1426 CG1 ILE B 96 11917 12018 10374 272 679 -433 C
+ATOM 1427 CG2 ILE B 96 -30.408 -15.587 -0.291 1.00 96.15 C
+ANISOU 1427 CG2 ILE B 96 12623 13049 10858 195 743 -278 C
+ATOM 1428 CD1 ILE B 96 -31.453 -13.513 -2.211 1.00 91.73 C
+ANISOU 1428 CD1 ILE B 96 12017 12259 10577 456 854 -422 C
+ATOM 1429 N MET B 97 -28.867 -12.760 2.519 1.00 96.04 N
+ANISOU 1429 N MET B 97 13305 12930 10255 212 718 -806 N
+ATOM 1430 CA MET B 97 -28.752 -13.030 3.959 1.00108.10 C
+ANISOU 1430 CA MET B 97 14968 14612 11491 186 733 -832 C
+ATOM 1431 C MET B 97 -29.333 -11.852 4.784 1.00112.54 C
+ANISOU 1431 C MET B 97 15786 15132 11839 327 893 -1037 C
+ATOM 1432 O MET B 97 -30.047 -12.090 5.759 1.00113.07 O
+ANISOU 1432 O MET B 97 15896 15370 11696 422 1051 -1023 O
+ATOM 1433 CB MET B 97 -27.301 -13.410 4.291 1.00103.41 C
+ANISOU 1433 CB MET B 97 14414 14054 10823 -6 483 -827 C
+ATOM 1434 CG MET B 97 -26.722 -14.327 3.206 1.00102.45 C
+ANISOU 1434 CG MET B 97 14057 13920 10946 -76 347 -664 C
+ATOM 1435 SD MET B 97 -25.246 -15.322 3.559 1.00117.34 S
+ANISOU 1435 SD MET B 97 15877 15943 12762 -203 84 -561 S
+ATOM 1436 CE MET B 97 -24.043 -14.027 3.907 1.00103.96 C
+ANISOU 1436 CE MET B 97 14327 14224 10946 -367 -80 -786 C
+ATOM 1437 N LEU B 98 -29.087 -10.604 4.344 1.00119.26 N
+ANISOU 1437 N LEU B 98 16822 15748 12742 354 871 -1217 N
+ATOM 1438 CA LEU B 98 -29.639 -9.356 4.952 1.00123.66 C
+ANISOU 1438 CA LEU B 98 17689 16180 13115 531 1024 -1437 C
+ATOM 1439 C LEU B 98 -30.866 -9.535 5.875 1.00124.53 C
+ANISOU 1439 C LEU B 98 17792 16500 13023 769 1286 -1430 C
+ATOM 1440 O LEU B 98 -32.001 -9.708 5.420 1.00113.44 O
+ANISOU 1440 O LEU B 98 16173 15192 11737 973 1471 -1329 O
+ATOM 1441 CB LEU B 98 -29.945 -8.322 3.862 1.00113.25 C
+ANISOU 1441 CB LEU B 98 16446 14588 11996 658 1065 -1512 C
+TER 1442 LEU B 98
+HETATM 1443 FE1 FES A 201 -15.271 -14.172 -26.506 1.00 44.84 FE
+ANISOU 1443 FE1 FES A 201 6513 5131 5392 -266 1479 -131 FE
+HETATM 1444 FE2 FES A 201 -13.886 -13.246 -28.774 1.00 43.12 FE
+ANISOU 1444 FE2 FES A 201 6178 4976 5230 -316 1145 -235 FE
+HETATM 1445 S1 FES A 201 -13.297 -13.107 -26.664 1.00 54.52 S
+ANISOU 1445 S1 FES A 201 7773 6436 6506 -96 1188 -102 S
+HETATM 1446 S2 FES A 201 -15.933 -14.020 -28.613 1.00 59.15 S
+ANISOU 1446 S2 FES A 201 8119 7001 7354 -510 1368 -300 S
+HETATM 1447 CL CL A 202 -7.271 -6.453 -50.333 1.00 66.75 CL
+ANISOU 1447 CL CL A 202 8476 9756 7127 -15 320 384 CL
+HETATM 1448 FE1 FES B 201 -24.764 -23.326 -3.870 1.00 41.78 FE
+ANISOU 1448 FE1 FES B 201 5702 5769 4400 126 -205 391 FE
+HETATM 1449 FE2 FES B 201 -25.332 -22.283 -6.421 1.00 37.10 FE
+ANISOU 1449 FE2 FES B 201 4925 5056 4113 76 -116 248 FE
+HETATM 1450 S1 FES B 201 -23.427 -22.583 -5.443 1.00 50.74 S
+ANISOU 1450 S1 FES B 201 6641 6936 5699 218 -266 253 S
+HETATM 1451 S2 FES B 201 -26.631 -22.784 -4.792 1.00 52.36 S
+ANISOU 1451 S2 FES B 201 6974 7030 5890 -29 -34 366 S
+HETATM 1452 CL CL B 202 -35.655 -14.036 -25.892 1.00 63.11 CL
+ANISOU 1452 CL CL B 202 7828 8449 7699 533 -737 677 CL
+HETATM 1453 O HOH A 301 -5.604 9.621 -30.726 1.00 71.67 O
+ANISOU 1453 O HOH A 301 9741 6570 10921 -503 1286 -1155 O
+HETATM 1454 O HOH A 302 -9.976 -2.053 -46.606 1.00 60.80 O
+ANISOU 1454 O HOH A 302 7211 8696 7192 404 154 904 O
+HETATM 1455 O HOH A 303 -25.242 -15.543 -37.047 1.00 85.19 O
+ANISOU 1455 O HOH A 303 9346 12270 10750 -2562 894 -1311 O
+HETATM 1456 O HOH A 304 -8.615 -1.310 -44.946 1.00 51.68 O
+ANISOU 1456 O HOH A 304 6188 7004 6442 421 264 856 O
+HETATM 1457 O HOH A 305 -6.495 -20.103 -36.227 1.00 66.33 O
+ANISOU 1457 O HOH A 305 9914 6783 8504 -320 2093 -239 O
+HETATM 1458 O HOH A 306 -15.756 -22.203 -33.220 1.00 75.41 O
+ANISOU 1458 O HOH A 306 10813 7895 9944 -1695 2618 -965 O
+HETATM 1459 O HOH A 307 -29.136 -5.336 -24.489 1.00 68.01 O
+ANISOU 1459 O HOH A 307 7381 9218 9240 419 2448 230 O
+HETATM 1460 O HOH A 308 -31.273 -2.568 -37.684 1.00 80.28 O
+ANISOU 1460 O HOH A 308 6166 13841 10493 472 476 1418 O
+HETATM 1461 O HOH A 309 -12.248 -4.951 -30.108 1.00 43.84 O
+ANISOU 1461 O HOH A 309 5908 5247 5501 5 448 -372 O
+HETATM 1462 O HOH A 310 1.254 -8.613 -35.928 1.00 55.59 O
+ANISOU 1462 O HOH A 310 7059 6744 7319 249 231 444 O
+HETATM 1463 O HOH A 311 -14.907 -5.701 -24.000 1.00 59.32 O
+ANISOU 1463 O HOH A 311 8290 7265 6981 168 940 -557 O
+HETATM 1464 O HOH A 312 -10.817 -7.018 -29.284 1.00 41.62 O
+ANISOU 1464 O HOH A 312 5784 4984 5045 -27 423 -341 O
+HETATM 1465 O HOH A 313 2.334 -6.045 -37.941 1.00 48.64 O
+ANISOU 1465 O HOH A 313 5952 5811 6716 139 202 488 O
+HETATM 1466 O HOH A 314 -15.179 -4.981 -27.668 1.00 53.48 O
+ANISOU 1466 O HOH A 314 7171 6503 6643 87 768 -437 O
+HETATM 1467 O HOH A 315 -0.012 -13.050 -38.710 1.00 53.80 O
+ANISOU 1467 O HOH A 315 7374 6131 6936 327 934 389 O
+HETATM 1468 O HOH A 316 -4.588 7.953 -34.979 1.00 55.02 O
+ANISOU 1468 O HOH A 316 7176 4879 8848 -164 1054 -241 O
+HETATM 1469 O HOH A 317 -7.401 1.030 -46.099 1.00 71.07 O
+ANISOU 1469 O HOH A 317 8592 9256 9152 695 478 1286 O
+HETATM 1470 O HOH B 301 -17.227 -5.370 -20.274 1.00 67.76 O
+ANISOU 1470 O HOH B 301 9358 8307 8078 -2373 512 237 O
+HETATM 1471 O HOH B 302 -16.773 -19.622 -11.270 1.00 63.07 O
+ANISOU 1471 O HOH B 302 7080 9333 7548 271 -261 -62 O
+HETATM 1472 O HOH B 303 -33.187 -25.431 -12.986 1.00 63.64 O
+ANISOU 1472 O HOH B 303 8214 8071 7895 -876 -197 526 O
+HETATM 1473 O HOH B 304 -33.633 -10.672 -27.113 1.00 59.09 O
+ANISOU 1473 O HOH B 304 8015 7375 7058 804 -526 819 O
+HETATM 1474 O HOH B 305 -29.987 -6.037 -4.511 1.00 66.34 O
+ANISOU 1474 O HOH B 305 10207 7566 7433 765 801 -1097 O
+HETATM 1475 O HOH B 306 -13.899 -20.518 -11.569 1.00 81.57 O
+ANISOU 1475 O HOH B 306 8854 12357 9778 587 -327 -7 O
+HETATM 1476 O HOH B 307 -22.312 -17.195 -9.418 1.00 47.15 O
+ANISOU 1476 O HOH B 307 5812 6486 5616 -124 -89 -163 O
+HETATM 1477 O HOH B 308 -34.144 -23.559 -20.590 1.00 51.64 O
+ANISOU 1477 O HOH B 308 6612 6627 6378 -778 -651 271 O
+HETATM 1478 O HOH B 309 -24.795 -27.082 -17.164 1.00 48.12 O
+ANISOU 1478 O HOH B 309 7064 5473 5745 466 -276 10 O
+HETATM 1479 O HOH B 310 -32.217 -13.054 4.356 1.00 88.41 O
+ANISOU 1479 O HOH B 310 12239 12424 8929 628 1337 -721 O
+HETATM 1480 O HOH B 311 -23.165 -14.400 -5.121 1.00 48.01 O
+ANISOU 1480 O HOH B 311 6333 6580 5329 -351 -63 -448 O
+HETATM 1481 O HOH B 312 -20.108 -19.770 -22.685 1.00 54.43 O
+ANISOU 1481 O HOH B 312 6815 7445 6419 397 344 -109 O
+HETATM 1482 O HOH B 313 -29.379 -10.101 -22.915 1.00 62.52 O
+ANISOU 1482 O HOH B 313 8624 7375 7757 322 17 426 O
+HETATM 1483 O HOH B 314 -23.815 -23.224 -24.077 1.00 46.69 O
+ANISOU 1483 O HOH B 314 6623 5782 5333 479 -2 -224 O
+HETATM 1484 O HOH B 315 -31.917 -9.402 -21.408 1.00 63.89 O
+ANISOU 1484 O HOH B 315 8654 7581 8038 758 -17 436 O
+HETATM 1485 O HOH B 316 -43.034 -22.451 -5.025 1.00 82.32 O
+ANISOU 1485 O HOH B 316 8131 13423 9723 -1213 1232 1263 O
+HETATM 1486 O HOH B 317 -13.942 -19.466 -15.267 1.00 82.69 O
+ANISOU 1486 O HOH B 317 8966 12435 10017 416 49 -55 O
+HETATM 1487 O HOH B 318 -23.364 -14.585 -8.816 1.00 50.88 O
+ANISOU 1487 O HOH B 318 6512 6761 6060 -288 14 -313 O
+HETATM 1488 O HOH B 319 -41.794 -18.985 0.026 0.50 60.91 O
+ANISOU 1488 O HOH B 319 5945 10874 6323 -9 2050 811 O
+HETATM 1489 O HOH B 320 -29.672 -24.828 -29.742 1.00 55.49 O
+ANISOU 1489 O HOH B 320 8618 6605 5859 -263 -781 -333 O
+HETATM 1490 O HOH B 321 -38.215 -20.833 -12.380 1.00 58.66 O
+ANISOU 1490 O HOH B 321 6197 8706 7384 -584 159 654 O
+CONECT 301 1443
+CONECT 333 1443
+CONECT 351 1444
+CONECT 569 1444
+CONECT 1022 1448
+CONECT 1054 1448
+CONECT 1072 1449
+CONECT 1290 1449
+CONECT 1443 301 333 1445 1446
+CONECT 1444 351 569 1445 1446
+CONECT 1445 1443 1444
+CONECT 1446 1443 1444
+CONECT 1448 1022 1054 1450 1451
+CONECT 1449 1072 1290 1450 1451
+CONECT 1450 1448 1449
+CONECT 1451 1448 1449
+MASTER 410 0 4 7 14 0 6 6 1488 2 16 18
+END
--- /dev/null
+package jalview.ext.rbvi.chimera;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+public class AtomSpecModelTest
+{
+ @Test(groups = "Functional")
+ public void testGetAtomSpec()
+ {
+ AtomSpecModel model = new AtomSpecModel();
+ assertEquals(model.getAtomSpec(), "");
+ model.addRange(1, 2, 4, "A");
+ assertEquals(model.getAtomSpec(), "#1:2-4.A");
+ model.addRange(1, 8, 8, "A");
+ assertEquals(model.getAtomSpec(), "#1:2-4.A,8.A");
+ model.addRange(1, 5, 7, "B");
+ assertEquals(model.getAtomSpec(), "#1:2-4.A,8.A,5-7.B");
+ model.addRange(1, 3, 5, "A");
+ assertEquals(model.getAtomSpec(), "#1:2-5.A,8.A,5-7.B");
+ model.addRange(0, 1, 4, "B");
+ assertEquals(model.getAtomSpec(), "#0:1-4.B|#1:2-5.A,8.A,5-7.B");
+ model.addRange(0, 5, 9, "C");
+ assertEquals(model.getAtomSpec(), "#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-7.B");
+ model.addRange(1, 8, 10, "B");
+ assertEquals(model.getAtomSpec(), "#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-10.B");
+ model.addRange(1, 8, 9, "B");
+ assertEquals(model.getAtomSpec(), "#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-10.B");
+ model.addRange(0, 3, 10, "C"); // subsumes 5-9
+ assertEquals(model.getAtomSpec(), "#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B");
+ }
+
+}
*/
package jalview.ext.rbvi.chimera;
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertTrue;
-
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
import jalview.gui.JvOptionPane;
+import jalview.gui.SequenceRenderer;
+import jalview.schemes.JalviewColourScheme;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureMappingcommandSet;
+import jalview.structure.StructureSelectionManager;
import java.awt.Color;
-import java.util.Arrays;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
}
@Test(groups = { "Functional" })
- public void testAddColourRange()
- {
- Map<Color, Map<Integer, Map<String, List<int[]>>>> map = new LinkedHashMap<Color, Map<Integer, Map<String, List<int[]>>>>();
- ChimeraCommands.addColourRange(map, Color.pink, 1, 2, 4, "A");
- ChimeraCommands.addColourRange(map, Color.pink, 1, 8, 8, "A");
- ChimeraCommands.addColourRange(map, Color.pink, 1, 5, 7, "B");
- ChimeraCommands.addColourRange(map, Color.red, 1, 3, 5, "A");
- ChimeraCommands.addColourRange(map, Color.red, 0, 1, 4, "B");
- ChimeraCommands.addColourRange(map, Color.orange, 0, 5, 9, "C");
-
- // three colours mapped
- assertEquals(3, map.keySet().size());
-
- // Red has two models, Pink and Orange one each
- assertEquals(2, map.get(Color.red).keySet().size());
- assertEquals(1, map.get(Color.orange).keySet().size());
- assertEquals(1, map.get(Color.pink).keySet().size());
-
- // pink model 1 has two chains, red.0 / red.1 / orange.0 one each
- assertEquals(2, map.get(Color.pink).get(1).keySet().size());
- assertEquals(1, map.get(Color.red).get(0).keySet().size());
- assertEquals(1, map.get(Color.red).get(1).keySet().size());
- assertEquals(1, map.get(Color.orange).get(0).keySet().size());
-
- // inspect positions
- List<int[]> posList = map.get(Color.pink).get(1).get("A");
- assertEquals(2, posList.size());
- assertTrue(Arrays.equals(new int[] { 2, 4 }, posList.get(0)));
- assertTrue(Arrays.equals(new int[] { 8, 8 }, posList.get(1)));
-
- posList = map.get(Color.pink).get(1).get("B");
- assertEquals(1, posList.size());
- assertTrue(Arrays.equals(new int[] { 5, 7 }, posList.get(0)));
-
- posList = map.get(Color.red).get(0).get("B");
- assertEquals(1, posList.size());
- assertTrue(Arrays.equals(new int[] { 1, 4 }, posList.get(0)));
-
- posList = map.get(Color.red).get(1).get("A");
- assertEquals(1, posList.size());
- assertTrue(Arrays.equals(new int[] { 3, 5 }, posList.get(0)));
-
- posList = map.get(Color.orange).get(0).get("C");
- assertEquals(1, posList.size());
- assertTrue(Arrays.equals(new int[] { 5, 9 }, posList.get(0)));
- }
-
- @Test(groups = { "Functional" })
public void testBuildColourCommands()
{
- Map<Color, Map<Integer, Map<String, List<int[]>>>> map = new LinkedHashMap<Color, Map<Integer, Map<String, List<int[]>>>>();
+ Map<Object, AtomSpecModel> map = new LinkedHashMap<Object, AtomSpecModel>();
ChimeraCommands.addColourRange(map, Color.blue, 0, 2, 5, "A");
ChimeraCommands.addColourRange(map, Color.blue, 0, 7, 7, "B");
ChimeraCommands.addColourRange(map, Color.blue, 0, 9, 23, "A");
ChimeraCommands.addColourRange(map, Color.yellow, 1, 8, 8, "A");
ChimeraCommands.addColourRange(map, Color.yellow, 1, 3, 5, "A");
ChimeraCommands.addColourRange(map, Color.red, 0, 3, 5, "A");
+ ChimeraCommands.addColourRange(map, Color.red, 0, 6, 9, "A");
// Colours should appear in the Chimera command in the order in which
- // they were added; within colour, by model, by chain, and positions as
- // added
+ // they were added; within colour, by model, by chain, ranges in start order
String command = ChimeraCommands.buildColourCommands(map).get(0);
assertEquals(
- "color #0000ff #0:2-5.A,9-23.A,7.B|#1:1.A,4-7.B; color #ffff00 #1:8.A,3-5.A; color #ff0000 #0:3-5.A",
- command);
+ command,
+ "color #0000ff #0:2-5.A,9-23.A,7.B|#1:1.A,4-7.B; color #ffff00 #1:3-5.A,8.A; color #ff0000 #0:3-9.A");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testBuildSetAttributeCommands()
+ {
+ /*
+ * make a map of { featureType, {featureValue, {residue range specification } } }
+ */
+ Map<String, Map<Object, AtomSpecModel>> featuresMap = new LinkedHashMap<String, Map<Object, AtomSpecModel>>();
+ Map<Object, AtomSpecModel> featureValues = new HashMap<Object, AtomSpecModel>();
+
+ /*
+ * start with just one feature/value...
+ */
+ featuresMap.put("chain", featureValues);
+ ChimeraCommands.addColourRange(featureValues, "X", 0, 8, 20, "A");
+
+ List<String> commands = ChimeraCommands
+ .buildSetAttributeCommands(featuresMap);
+ assertEquals(1, commands.size());
+
+ /*
+ * feature name gets a jv_ namespace prefix
+ * feature value is quoted in case it contains spaces
+ */
+ assertEquals(commands.get(0), "setattr r jv_chain 'X' #0:8-20.A");
+
+ // add same feature value, overlapping range
+ ChimeraCommands.addColourRange(featureValues, "X", 0, 3, 9, "A");
+ // same feature value, contiguous range
+ ChimeraCommands.addColourRange(featureValues, "X", 0, 21, 25, "A");
+ commands = ChimeraCommands.buildSetAttributeCommands(featuresMap);
+ assertEquals(1, commands.size());
+ assertEquals(commands.get(0), "setattr r jv_chain 'X' #0:3-25.A");
+
+ // same feature value and model, different chain
+ ChimeraCommands.addColourRange(featureValues, "X", 0, 21, 25, "B");
+ // same feature value and chain, different model
+ ChimeraCommands.addColourRange(featureValues, "X", 1, 26, 30, "A");
+ commands = ChimeraCommands.buildSetAttributeCommands(featuresMap);
+ assertEquals(1, commands.size());
+ assertEquals(commands.get(0),
+ "setattr r jv_chain 'X' #0:3-25.A,21-25.B|#1:26-30.A");
+
+ // same feature, different value
+ ChimeraCommands.addColourRange(featureValues, "Y", 0, 40, 50, "A");
+ commands = ChimeraCommands.buildSetAttributeCommands(featuresMap);
+ assertEquals(2, commands.size());
+ // commands are ordered by feature type but not by value
+ // so use contains to test for the expected command:
+ assertTrue(commands
+ .contains("setattr r jv_chain 'X' #0:3-25.A,21-25.B|#1:26-30.A"));
+ assertTrue(commands.contains("setattr r jv_chain 'Y' #0:40-50.A"));
+
+ featuresMap.clear();
+ featureValues.clear();
+ featuresMap.put("side-chain binding!", featureValues);
+ ChimeraCommands.addColourRange(featureValues,
+ "<html>metal <a href=\"http:a.b.c/x\"> 'ion!", 0, 7, 15,
+ "A");
+ // feature names are sanitised to change non-alphanumeric to underscore
+ // feature values are sanitised to encode single quote characters
+ commands = ChimeraCommands.buildSetAttributeCommands(featuresMap);
+ assertTrue(commands
+ .contains("setattr r jv_side_chain_binding_ '<html>metal <a href=\"http:a.b.c/x\"> 'ion!' #0:7-15.A"));
+ }
+
+ /**
+ * Tests for the method that prefixes and sanitises a feature name so it can
+ * be used as a valid, namespaced attribute name in Chimera
+ */
+ @Test(groups = { "Functional" })
+ public void testMakeAttributeName()
+ {
+ assertEquals(ChimeraCommands.makeAttributeName(null), "jv_");
+ assertEquals(ChimeraCommands.makeAttributeName(""), "jv_");
+ assertEquals(ChimeraCommands.makeAttributeName("helix"), "jv_helix");
+ assertEquals(ChimeraCommands.makeAttributeName("Hello World 24"),
+ "jv_Hello_World_24");
+ assertEquals(
+ ChimeraCommands.makeAttributeName("!this is-a_very*{odd(name"),
+ "jv__this_is_a_very__odd_name");
+ // name ending in color gets underscore appended
+ assertEquals(ChimeraCommands.makeAttributeName("helixColor"),
+ "jv_helixColor_");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetColourBySequenceCommands_hiddenColumns()
+ {
+ /*
+ * load these sequences, coloured by Strand propensity,
+ * with columns 2-4 hidden
+ */
+ SequenceI seq1 = new Sequence("seq1", "MHRSQSSSGG");
+ SequenceI seq2 = new Sequence("seq2", "MVRSNGGSSS");
+ AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
+ AlignFrame af = new AlignFrame(al, 800, 500);
+ af.changeColour_actionPerformed(JalviewColourScheme.Strand.toString());
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(2);
+ cs.addElement(3);
+ cs.addElement(4);
+ af.getViewport().setColumnSelection(cs);
+ af.hideSelColumns_actionPerformed(null);
+ SequenceRenderer sr = new SequenceRenderer(af.getViewport());
+ SequenceI[][] seqs = new SequenceI[][] { { seq1 }, { seq2 } };
+ String[] files = new String[] { "seq1.pdb", "seq2.pdb" };
+ StructureSelectionManager ssm = new StructureSelectionManager();
+
+ /*
+ * map residues 1-10 to residues 21-30 (atoms 105-150) in structures
+ */
+ HashMap<Integer, int[]> map = new HashMap<Integer, int[]>();
+ for (int pos = 1; pos <= seq1.getLength(); pos++)
+ {
+ map.put(pos, new int[] { 20 + pos, 5 * (20 + pos) });
+ }
+ StructureMapping sm1 = new StructureMapping(seq1, "seq1.pdb", "pdb1",
+ "A", map, null);
+ ssm.addStructureMapping(sm1);
+ StructureMapping sm2 = new StructureMapping(seq2, "seq2.pdb", "pdb2",
+ "B", map, null);
+ ssm.addStructureMapping(sm2);
+
+ StructureMappingcommandSet[] commands = ChimeraCommands
+ .getColourBySequenceCommand(ssm, files, seqs, sr, null,
+ af.getViewport());
+ assertEquals(1, commands.length);
+ assertEquals(1, commands[0].commands.length);
+ String theCommand = commands[0].commands[0];
+ // M colour is #82827d (see strand.html help page)
+ assertTrue(theCommand.contains("color #82827d #0:21.A|#1:21.B"));
+ // H colour is #60609f
+ assertTrue(theCommand.contains("color #60609f #0:22.A"));
+ // V colour is ##ffff00
+ assertTrue(theCommand.contains("color #ffff00 #1:22.B"));
+ // hidden columns are Gray (128, 128, 128)
+ assertTrue(theCommand.contains("color #808080 #0:23-25.A|#1:23-25.B"));
+ // S and G are both coloured #4949b6
+ assertTrue(theCommand.contains("color #4949b6 #0:26-30.A|#1:26-30.B"));
}
}
*/
package jalview.ext.rbvi.chimera;
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import jalview.api.FeatureRenderer;
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
import jalview.gui.JvOptionPane;
import jalview.gui.Preferences;
import jalview.gui.StructureViewer;
import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.FileLoader;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureSelectionManager;
+import jalview.ws.sifts.SiftsClient;
+import jalview.ws.sifts.SiftsException;
+import jalview.ws.sifts.SiftsSettings;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Vector;
import jalview.io.DataSourceType;
import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
}
+ private JalviewStructureDisplayI chimeraViewer;
+
/**
* @throws java.lang.Exception
*/
@BeforeClass(alwaysRun = true)
public static void setUpBeforeClass() throws Exception
{
- jalview.bin.Jalview.main(new String[] {
- "-noquestionnaire -nonews -props",
+ Jalview.main(new String[] { "-noquestionnaire", "-nonews", "-props",
"test/jalview/ext/rbvi/chimera/testProps.jvprops" });
+ Cache.setProperty(Preferences.STRUCTURE_DISPLAY,
+ ViewerType.CHIMERA.name());
+ Cache.setProperty("SHOW_ANNOTATIONS", "false");
+ Cache.setProperty(Preferences.STRUCT_FROM_PDB, "false");
+ Cache.setProperty(Preferences.STRUCTURE_DISPLAY,
+ ViewerType.CHIMERA.name());
+ Cache.setProperty("MAP_WITH_SIFTS", "true");
+ // TODO this should not be necessary!
+ SiftsSettings.setMapWithSifts(true);
}
/**
@AfterClass(alwaysRun = true)
public static void tearDownAfterClass() throws Exception
{
- jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDownAfterTest() throws Exception
+ {
+ SiftsClient.setMockSiftsFile(null);
+ if (chimeraViewer != null)
+ {
+ chimeraViewer.closeViewer(true);
+ }
}
- @Test(groups = { "Functional" })
+ /**
+ * Load 1GAQ and view the first structure for which a PDB id is found. Note no
+ * network connection is needed - PDB file is read locally, SIFTS fetch fails
+ * so mapping falls back to Needleman-Wunsch - ok for this test.
+ */
+ // External as local install of Chimera required
+ @Test(groups = { "External" })
public void testSingleSeqViewChimera()
{
- Cache.setProperty(Preferences.STRUCTURE_DISPLAY,
- ViewerType.CHIMERA.name());
String inFile = "examples/1gaq.txt";
- AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
- inFile, DataSourceType.FILE);
- assertTrue("Didn't read input file " + inFile, af != null);
- for (SequenceI sq : af.getViewport().getAlignment().getSequences())
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Failed to create AlignFrame");
+ SequenceI sq = af.getViewport().getAlignment().getSequenceAt(0);
+ assertEquals(sq.getName(), "1GAQ|A");
+ SequenceI dsq = sq.getDatasetSequence();
+ Vector<PDBEntry> pdbIds = dsq.getAllPDBEntries();
+ assertEquals(pdbIds.size(), 1);
+ PDBEntry pdbEntry = pdbIds.get(0);
+ assertEquals(pdbEntry.getId(), "1GAQ");
+ StructureViewer structureViewer = new StructureViewer(af.getViewport()
+ .getStructureSelectionManager());
+ chimeraViewer = structureViewer.viewStructures(pdbEntry,
+ new SequenceI[] { sq }, af.getCurrentView().getAlignPanel());
+ JalviewChimeraBinding binding = (JalviewChimeraBinding) chimeraViewer
+ .getBinding();
+
+ /*
+ * Wait for viewer load thread to complete
+ */
+ while (!binding.isFinishedInit())
{
- System.out.println("** sq=" + sq.getName());
- SequenceI dsq = sq.getDatasetSequence();
- while (dsq.getDatasetSequence() != null)
+ try
+ {
+ Thread.sleep(500);
+ } catch (InterruptedException e)
{
- dsq = dsq.getDatasetSequence();
}
- if (dsq.getAllPDBEntries() != null
- && dsq.getAllPDBEntries().size() > 0)
+ }
+
+ assertTrue(binding.isChimeraRunning(), "Failed to start Chimera");
+
+ assertEquals(chimeraViewer.getBinding().getPdbCount(), 1);
+ chimeraViewer.closeViewer(true);
+ chimeraViewer = null;
+ return;
+ }
+
+ /**
+ * Test for writing Jalview features as attributes on mapped residues in
+ * Chimera. Note this uses local copies of PDB and SIFTS file, no network
+ * connection required.
+ *
+ * @throws IOException
+ * @throws SiftsException
+ */
+ // External as this requires a local install of Chimera
+ @Test(groups = { "External" })
+ public void testTransferFeatures() throws IOException, SiftsException
+ {
+ String inFile = "examples/uniref50.fa";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Failed to create AlignFrame");
+ SequenceI sq = af.getViewport().getAlignment().findName("FER2_ARATH");
+ assertNotNull(sq, "Didn't find FER2_ARATH");
+
+ /*
+ * need a Uniprot dbref for SIFTS mapping to work!!
+ */
+ sq.addDBRef(new DBRefEntry("UNIPROT", "0", "P16972", null));
+
+ /*
+ * use local test PDB and SIFTS files
+ */
+ String pdbFilePath = new File(
+ "test/jalview/ext/rbvi/chimera/4zho.pdb").getPath();
+ PDBEntry pdbEntry = new PDBEntry("4ZHO", null, null, pdbFilePath);
+ String siftsFilePath = new File(
+ "test/jalview/ext/rbvi/chimera/4zho.xml.gz")
+ .getPath();
+ SiftsClient.setMockSiftsFile(new File(siftsFilePath));
+
+ StructureViewer structureViewer = new StructureViewer(af.getViewport()
+ .getStructureSelectionManager());
+ chimeraViewer = structureViewer.viewStructures(pdbEntry,
+ new SequenceI[] { sq }, af.getCurrentView().getAlignPanel());
+
+ JalviewChimeraBinding binding = (JalviewChimeraBinding) chimeraViewer
+ .getBinding();
+ do
+ {
+ try
+ {
+ Thread.sleep(500);
+ } catch (InterruptedException e)
+ {
+ }
+ } while (!binding.isFinishedInit());
+
+ assertTrue(binding.isChimeraRunning(), "Failed to launch Chimera");
+
+ assertEquals(binding.getPdbCount(), 1);
+
+ /*
+ * check mapping is (sequence) 53-145 to (structure) 2-94 A/B
+ * (or possibly 52-145 to 1-94 - see JAL-2319)
+ */
+ StructureSelectionManager ssm = binding.getSsm();
+ String pdbFile = binding.getPdbFile()[0];
+ StructureMapping[] mappings = ssm.getMapping(pdbFile);
+ assertTrue(mappings[0].getMappingDetailsOutput().contains("SIFTS"),
+ "Failed to perform SIFTS mapping");
+ assertEquals(mappings.length, 2);
+ assertEquals(mappings[0].getChain(), "A");
+ assertEquals(mappings[0].getPDBResNum(53), 2);
+ assertEquals(mappings[0].getPDBResNum(145), 94);
+ assertEquals(mappings[1].getChain(), "B");
+ assertEquals(mappings[1].getPDBResNum(53), 2);
+ assertEquals(mappings[1].getPDBResNum(145), 94);
+
+ /*
+ * now add some features to FER2_ARATH
+ */
+ // feature on a sequence region not mapped to structure:
+ sq.addSequenceFeature(new SequenceFeature("transit peptide",
+ "chloroplast", 1, 51, Float.NaN, null));
+ // feature on a region mapped to structure:
+ sq.addSequenceFeature(new SequenceFeature("domain",
+ "2Fe-2S ferredoxin-type", 55, 145, Float.NaN, null));
+ // on sparse positions of the sequence
+ sq.addSequenceFeature(new SequenceFeature("metal ion-binding site",
+ "Iron-Sulfur (2Fe-2S)", 91, 91, Float.NaN, null));
+ sq.addSequenceFeature(new SequenceFeature("metal ion-binding site",
+ "Iron-Sulfur (2Fe-2S)", 96, 96, Float.NaN, null));
+ // on a sequence region that is partially mapped to structure:
+ sq.addSequenceFeature(new SequenceFeature("helix", null, 50, 60,
+ Float.NaN, null));
+ // and again:
+ sq.addSequenceFeature(new SequenceFeature("chain", null, 50, 70,
+ Float.NaN, null));
+ // add numeric valued features - score is set as attribute value
+ sq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 62,
+ 62, -2.1f, null));
+ sq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 65,
+ 65, 3.6f, null));
+ sq.addSequenceFeature(new SequenceFeature("RESNUM", "ALA: 2 4zhoA",
+ 53, 53, Float.NaN, null));
+
+ /*
+ * set all features visible except for chain
+ */
+ af.setShowSeqFeatures(true);
+ FeatureRenderer fr = af.getFeatureRenderer();
+ fr.setVisible("transit peptide");
+ fr.setVisible("domain");
+ fr.setVisible("metal ion-binding site");
+ fr.setVisible("helix");
+ fr.setVisible("kd");
+ fr.setVisible("RESNUM");
+
+ /*
+ * 'perform' menu action to copy visible features to
+ * attributes in Chimera
+ */
+ // TODO rename and pull up method to binding interface
+ // once functionality is added for Jmol as well
+ binding.sendFeaturesToViewer(af.getViewport().getAlignPanel());
+
+ /*
+ * give Chimera time to open the commands file and execute it
+ */
+ try
+ {
+ Thread.sleep(1000);
+ } catch (InterruptedException e)
+ {
+ }
+
+ /*
+ * ask Chimera for its residue attribute names
+ */
+ List<String> reply = binding.sendChimeraCommand("list resattr", true);
+ // prefixed and sanitised attribute names for Jalview features:
+ assertTrue(reply.contains("resattr jv_domain"));
+ assertTrue(reply.contains("resattr jv_metal_ion_binding_site"));
+ assertTrue(reply.contains("resattr jv_helix"));
+ assertTrue(reply.contains("resattr jv_kd"));
+ assertTrue(reply.contains("resattr jv_RESNUM"));
+ // feature is not on a mapped region - no attribute created
+ assertFalse(reply.contains("resattr jv_transit_peptide"));
+ // feature is not visible - no attribute created
+ assertFalse(reply.contains("resattr jv_chain"));
+
+ /*
+ * ask Chimera for residues with an attribute
+ * 91 and 96 on sequence --> residues 40 and 45 on chains A and B
+ */
+ reply = binding.sendChimeraCommand(
+ "list resi att jv_metal_ion_binding_site", true);
+ assertEquals(reply.size(), 4);
+ assertTrue(reply
+ .contains("residue id #0:40.A jv_metal_ion_binding_site \"Iron-Sulfur (2Fe-2S)\" index 40"));
+ assertTrue(reply
+ .contains("residue id #0:45.A jv_metal_ion_binding_site \"Iron-Sulfur (2Fe-2S)\" index 45"));
+ assertTrue(reply
+ .contains("residue id #0:40.B jv_metal_ion_binding_site \"Iron-Sulfur (2Fe-2S)\" index 40"));
+ assertTrue(reply
+ .contains("residue id #0:45.B jv_metal_ion_binding_site \"Iron-Sulfur (2Fe-2S)\" index 45"));
+
+ /*
+ * check attributes with score values
+ * sequence positions 62 and 65 --> residues 11 and 14 on chains A and B
+ */
+ reply = binding.sendChimeraCommand("list resi att jv_kd", true);
+ assertEquals(reply.size(), 4);
+ assertTrue(reply.contains("residue id #0:11.A jv_kd -2.1 index 11"));
+ assertTrue(reply.contains("residue id #0:14.A jv_kd 3.6 index 14"));
+ assertTrue(reply.contains("residue id #0:11.B jv_kd -2.1 index 11"));
+ assertTrue(reply.contains("residue id #0:14.B jv_kd 3.6 index 14"));
+
+ /*
+ * list residues with positive kd score
+ */
+ reply = binding.sendChimeraCommand(
+ "list resi spec :*/jv_kd>0 attr jv_kd", true);
+ assertEquals(reply.size(), 2);
+ assertTrue(reply.contains("residue id #0:14.A jv_kd 3.6 index 14"));
+ assertTrue(reply.contains("residue id #0:14.B jv_kd 3.6 index 14"));
+
+ SiftsClient.setMockSiftsFile(null);
+ chimeraViewer.closeViewer(true);
+ chimeraViewer = null;
+ }
+
+ /**
+ * Test for creating Jalview features from attributes on mapped residues in
+ * Chimera. Note this uses local copies of PDB and SIFTS file, no network
+ * connection required.
+ *
+ * @throws IOException
+ * @throws SiftsException
+ */
+ // External as this requires a local install of Chimera
+ @Test(groups = { "External" })
+ public void testGetAttributes() throws IOException, SiftsException
+ {
+ String inFile = "examples/uniref50.fa";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Failed to create AlignFrame");
+ SequenceI fer2Arath = af.getViewport().getAlignment()
+ .findName("FER2_ARATH");
+ assertNotNull(fer2Arath, "Didn't find FER2_ARATH");
+
+ /*
+ * need a Uniprot dbref for SIFTS mapping to work!!
+ */
+ fer2Arath.addDBRef(new DBRefEntry("UNIPROT", "0", "P16972", null));
+
+ /*
+ * use local test PDB and SIFTS files
+ */
+ String pdbFilePath = new File(
+ "test/jalview/ext/rbvi/chimera/4zho.pdb").getPath();
+ PDBEntry pdbEntry = new PDBEntry("4ZHO", null, null, pdbFilePath);
+ String siftsFilePath = new File(
+ "test/jalview/ext/rbvi/chimera/4zho.xml.gz")
+ .getPath();
+ SiftsClient.setMockSiftsFile(new File(siftsFilePath));
+
+ StructureViewer structureViewer = new StructureViewer(af.getViewport()
+ .getStructureSelectionManager());
+ chimeraViewer = structureViewer.viewStructures(pdbEntry,
+ new SequenceI[] { fer2Arath }, af.getCurrentView()
+ .getAlignPanel());
+
+ JalviewChimeraBinding binding = (JalviewChimeraBinding) chimeraViewer
+ .getBinding();
+ do
+ {
+ try
+ {
+ Thread.sleep(500);
+ } catch (InterruptedException e)
{
- for (int q = 0; q < dsq.getAllPDBEntries().size(); q++)
- {
- final StructureViewer structureViewer = new StructureViewer(af
- .getViewport().getStructureSelectionManager());
- structureViewer.setViewerType(ViewerType.CHIMERA);
- JalviewStructureDisplayI chimeraViewer = structureViewer
- .viewStructures(dsq.getAllPDBEntries().elementAt(q),
- new SequenceI[] { sq }, af.getCurrentView()
- .getAlignPanel());
- /*
- * Wait for viewer load thread to complete
- */
- while (!chimeraViewer.getBinding().isFinishedInit())
- {
- try
- {
- Thread.sleep(500);
- } catch (InterruptedException e)
- {
- }
- }
- assertEquals(1, chimeraViewer.getBinding().getPdbCount());
- chimeraViewer.closeViewer(true);
- // todo: break here means only once through this loop?
- break;
- }
- break;
}
+ } while (!binding.isFinishedInit());
+
+ assertTrue(binding.isChimeraRunning(), "Failed to launch Chimera");
+
+ assertEquals(binding.getPdbCount(), 1);
+
+ /*
+ * 'perform' menu action to copy visible features to
+ * attributes in Chimera
+ */
+ // TODO rename and pull up method to binding interface
+ // once functionality is added for Jmol as well
+ binding.copyStructureAttributesToFeatures("isHelix", af.getViewport()
+ .getAlignPanel());
+
+ /*
+ * verify 22 residues have isHelix feature
+ * (may merge into ranges in future)
+ */
+ af.setShowSeqFeatures(true);
+ FeatureRenderer fr = af.getFeatureRenderer();
+ fr.setVisible("isHelix");
+ for (int res = 75; res <= 83; res++)
+ {
+ checkFeaturesAtRes(fer2Arath, fr, res, "isHelix");
}
+ for (int res = 117; res <= 123; res++)
+ {
+ checkFeaturesAtRes(fer2Arath, fr, res, "isHelix");
+ }
+ for (int res = 129; res <= 131; res++)
+ {
+ checkFeaturesAtRes(fer2Arath, fr, res, "isHelix");
+ }
+ for (int res = 143; res <= 145; res++)
+ {
+ checkFeaturesAtRes(fer2Arath, fr, res, "isHelix");
+ }
+
+ /*
+ * fetch a numeric valued attribute
+ */
+ binding.copyStructureAttributesToFeatures("phi", af.getViewport()
+ .getAlignPanel());
+ fr.setVisible("phi");
+ List<SequenceFeature> fs = fr.findFeaturesAtRes(fer2Arath, 54);
+ assertEquals(fs.size(), 3);
+ assertEquals(fs.get(0).getType(), "RESNUM");
+ assertEquals(fs.get(1).getType(), "phi");
+ assertEquals(fs.get(2).getType(), "phi");
+ assertEquals(fs.get(1).getDescription(), "A"); // chain
+ assertEquals(fs.get(2).getDescription(), "B");
+ assertEquals(fs.get(1).getScore(), -131.0713f, 0.001f);
+ assertEquals(fs.get(2).getScore(), -127.39512, 0.001f);
+
+ /*
+ * tear down - also in AfterMethod
+ */
+ SiftsClient.setMockSiftsFile(null);
+ chimeraViewer.closeViewer(true);
+ chimeraViewer = null;
+ }
+
+ /**
+ * Helper method to verify new feature at a sequence position
+ *
+ * @param seq
+ * @param fr
+ * @param res
+ * @param featureType
+ */
+ protected void checkFeaturesAtRes(SequenceI seq, FeatureRenderer fr,
+ int res, String featureType)
+ {
+ String where = "at position " + res;
+ List<SequenceFeature> fs = fr.findFeaturesAtRes(seq, res);
+ assertEquals(fs.size(), 2, where);
+ assertEquals(fs.get(0).getType(), "RESNUM", where);
+ SequenceFeature sf = fs.get(1);
+ assertEquals(sf.getType(), featureType, where);
+ assertEquals(sf.getFeatureGroup(), "Chimera", where);
+ assertEquals(sf.getDescription(), "True", where);
+ assertEquals(sf.getScore(), Float.NaN, where);
}
}
-#---JalviewX Properties File---
-#Fri Apr 25 09:54:25 BST 2014
-SCREEN_Y=768
-SCREEN_X=936
-SHOW_WSDISCOVERY_ERRORS=true
-LATEST_VERSION=2.8.0b1
-SHOW_CONSERVATION=true
+ANNOTATIONCOLOUR_MAX=ff0000
+ANNOTATIONCOLOUR_MIN=ffc800
+ANTI_ALIAS=false
+AUTHORFNAMES=Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+AUTHORS=J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
+AUTO_CALC_CONSENSUS=true
+BLC_JVSUFFIX=true
+BUILD_DATE=01 November 2013
+CLUSTAL_JVSUFFIX=true
+DAS_ACTIVE_SOURCE=uniprot\t
+DAS_LOCAL_SOURCE=
+DAS_REGISTRY_URL=http\://www.ebi.ac.uk/das-srv/registry/das/
+DEFAULT_COLOUR=None
+DEFAULT_FILE_FORMAT=FASTA
+FASTA_JVSUFFIX=true
+FIGURE_AUTOIDWIDTH=false
+FIGURE_USERIDWIDTH=
+FONT_NAME=SansSerif
+FONT_SIZE=10
+FONT_STYLE=plain
+GAP_SYMBOL=-
+ID_ITALICS=true
+JALVIEW_NEWS_RSS_LASTMODIFIED=Apr 23, 2014 2\:53\:26 PM
+JALVIEW_RSS_WINDOW_SCREEN_HEIGHT=328
JALVIEW_RSS_WINDOW_SCREEN_WIDTH=550
+JALVIEW_RSS_WINDOW_SCREEN_X=0
+JALVIEW_RSS_WINDOW_SCREEN_Y=0
+JAVA_CONSOLE_SCREEN_HEIGHT=162
JAVA_CONSOLE_SCREEN_WIDTH=450
+JAVA_CONSOLE_SCREEN_X=830
+JAVA_CONSOLE_SCREEN_Y=475
+JWS2HOSTURLS=http\://www.compbio.dundee.ac.uk/jabaws
LAST_DIRECTORY=/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples
-ID_ITALICS=true
-SORT_ALIGNMENT=No sort
-SHOW_IDENTITY=true
-WSMENU_BYHOST=false
-SEQUENCE_LINKS=EMBL-EBI Search|http\://www.ebi.ac.uk/ebisearch/search.ebi?db\=allebi&query\=$SEQUENCE_ID$
-SHOW_FULLSCREEN=false
-RECENT_URL=http\://www.jalview.org/examples/exampleFile_2_7.jar
-FONT_NAME=SansSerif
-BLC_JVSUFFIX=true
-VERSION_CHECK=false
-YEAR=2011
-SHOW_DBREFS_TOOLTIP=true
+LATEST_VERSION=2.8.0b1
MSF_JVSUFFIX=true
-SCREENGEOMETRY_HEIGHT=1600
-JAVA_CONSOLE_SCREEN_Y=475
-JAVA_CONSOLE_SCREEN_X=830
+NOQUESTIONNAIRES=true
+PAD_GAPS=false
PFAM_JVSUFFIX=true
+PILEUP_JVSUFFIX=true
PIR_JVSUFFIX=true
-STARTUP_FILE=http\://www.jalview.org/examples/exampleFile_2_3.jar
-JAVA_CONSOLE_SCREEN_HEIGHT=162
PIR_MODELLER=false
-GAP_SYMBOL=-
-SHOW_QUALITY=true
+RECENT_FILE=examples/uniref50.fa\t/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples/RF00031_folded.stk\t/Volumes/Data/Users/jimp/bs_ig_mult.out
+RECENT_URL=http\://www.jalview.org/examples/exampleFile_2_7.jar
+RIGHT_ALIGN_IDS=false
+RSBS_SERVICES=|Multi-Harmony|Analysis|Sequence Harmony and Multi-Relief (Brandt et al. 2010)|hseparable,gapCharacter\='-',returns\='ANNOTATION'|?tool\=jalview|http\://zeus.few.vu.nl/programs/shmrwww/index.php?tool\=jalview&groups\=$PARTITION\:min\='2',minsize\='2',sep\=' '$&ali_file\=$ALIGNMENT\:format\='FASTA',writeasfile$
+SCREEN_HEIGHT=650
+SCREEN_WIDTH=900
+SCREEN_X=936
+SCREEN_Y=768
+SCREENGEOMETRY_HEIGHT=1600
+SCREENGEOMETRY_WIDTH=2560
+SEQUENCE_LINKS=EMBL-EBI Search|http\://www.ebi.ac.uk/ebisearch/search.ebi?db\=allebi&query\=$SEQUENCE_ID$
+SHOW_ANNOTATIONS=true
+SHOW_CONSENSUS_HISTOGRAM=true
+SHOW_CONSENSUS_LOGO=false
+SHOW_CONSERVATION=true
+SHOW_DBREFS_TOOLTIP=true
+SHOW_ENFIN_SERVICES=true
+SHOW_FULLSCREEN=false
+SHOW_GROUP_CONSENSUS=false
SHOW_GROUP_CONSERVATION=false
+SHOW_IDENTITY=true
+SHOW_JAVA_CONSOLE=false
+SHOW_JVSUFFIX=true
SHOW_JWS2_SERVICES=true
SHOW_NPFEATS_TOOLTIP=true
-FONT_STYLE=plain
-ANTI_ALIAS=false
-SORT_BY_TREE=false
-RSBS_SERVICES=|Multi-Harmony|Analysis|Sequence Harmony and Multi-Relief (Brandt et al. 2010)|hseparable,gapCharacter\='-',returns\='ANNOTATION'|?tool\=jalview|http\://zeus.few.vu.nl/programs/shmrwww/index.php?tool\=jalview&groups\=$PARTITION\:min\='2',minsize\='2',sep\=' '$&ali_file\=$ALIGNMENT\:format\='FASTA',writeasfile$
-AUTHORFNAMES=Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
-JALVIEW_RSS_WINDOW_SCREEN_HEIGHT=328
-SHOW_GROUP_CONSENSUS=false
-SHOW_CONSENSUS_HISTOGRAM=true
SHOW_OVERVIEW=false
-AUTHORS=J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
-FIGURE_AUTOIDWIDTH=false
-SCREEN_WIDTH=900
-ANNOTATIONCOLOUR_MIN=ffc800
+SHOW_QUALITY=true
SHOW_STARTUP_FILE=false
-RECENT_FILE=examples/uniref50.fa\t/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples/RF00031_folded.stk\t/Volumes/Data/Users/jimp/bs_ig_mult.out
-DEFAULT_FILE_FORMAT=FASTA
-SHOW_JAVA_CONSOLE=false
-VERSION=2.8b1
-FIGURE_USERIDWIDTH=
-WSMENU_BYTYPE=false
-DEFAULT_COLOUR=None
-NOQUESTIONNAIRES=true
-JALVIEW_NEWS_RSS_LASTMODIFIED=Apr 23, 2014 2\:53\:26 PM
-BUILD_DATE=01 November 2013
-PILEUP_JVSUFFIX=true
-SHOW_CONSENSUS_LOGO=false
-SCREENGEOMETRY_WIDTH=2560
-SHOW_ANNOTATIONS=true
-JALVIEW_RSS_WINDOW_SCREEN_Y=0
-USAGESTATS=false
-JALVIEW_RSS_WINDOW_SCREEN_X=0
SHOW_UNCONSERVED=false
-SHOW_JVSUFFIX=true
-DAS_LOCAL_SOURCE=
-SCREEN_HEIGHT=650
-ANNOTATIONCOLOUR_MAX=ff0000
-AUTO_CALC_CONSENSUS=true
-FASTA_JVSUFFIX=true
-DAS_ACTIVE_SOURCE=uniprot\t
-JWS2HOSTURLS=http\://www.compbio.dundee.ac.uk/jabaws
-PAD_GAPS=false
-CLUSTAL_JVSUFFIX=true
-SHOW_ENFIN_SERVICES=true
-FONT_SIZE=10
-RIGHT_ALIGN_IDS=false
+SHOW_WSDISCOVERY_ERRORS=true
+SORT_ALIGNMENT=No sort
+SORT_BY_TREE=false
+STARTUP_FILE=
+USAGESTATS=false
USE_PROXY=false
+VERSION_CHECK=false
+VERSION=2.8b1
WRAP_ALIGNMENT=false
-#DAS_REGISTRY_URL=http\://www.dasregistry.org/das/ # retired 01/05/2015
-DAS_REGISTRY_URL=http\://www.ebi.ac.uk/das-srv/registry/das/
+WSMENU_BYHOST=false
+WSMENU_BYTYPE=false
+YEAR=2011
*/
package jalview.gui;
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertFalse;
-import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.io.Jalview2xmlTests;
+import jalview.renderer.ResidueShaderI;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.JalviewColourScheme;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.util.MessageManager;
+import java.awt.Color;
import java.util.List;
+import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class AlignFrameTest
{
+ AlignFrame af;
@BeforeClass(alwaysRun = true)
public void setUpJvOptionPane()
seq2.addSequenceFeature(new SequenceFeature("Turn", "", 7, 9,
Float.NaN, null));
AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
- AlignFrame af = new AlignFrame(al, al.getWidth(), al.getHeight());
+ AlignFrame alignFrame = new AlignFrame(al, al.getWidth(), al.getHeight());
/*
* hiding a feature not present does nothing
*/
- assertFalse(af.hideFeatureColumns("exon", true));
- assertTrue(af.getViewport().getColumnSelection().isEmpty());
- assertTrue(af.getViewport().getColumnSelection().getHiddenColumns()
+ assertFalse(alignFrame.hideFeatureColumns("exon", true));
+ assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
+ assertTrue(alignFrame.getViewport().getColumnSelection().getHiddenColumns()
.isEmpty());
- assertFalse(af.hideFeatureColumns("exon", false));
- assertTrue(af.getViewport().getColumnSelection().isEmpty());
- assertTrue(af.getViewport().getColumnSelection().getHiddenColumns()
+ assertFalse(alignFrame.hideFeatureColumns("exon", false));
+ assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
+ assertTrue(alignFrame.getViewport().getColumnSelection().getHiddenColumns()
.isEmpty());
/*
* hiding a feature in all columns does nothing
*/
- assertFalse(af.hideFeatureColumns("Metal", true));
- assertTrue(af.getViewport().getColumnSelection().isEmpty());
- List<int[]> hidden = af.getViewport().getColumnSelection()
+ assertFalse(alignFrame.hideFeatureColumns("Metal", true));
+ assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
+ List<int[]> hidden = alignFrame.getViewport().getColumnSelection()
.getHiddenColumns();
assertTrue(hidden.isEmpty());
* sequence positions [2-4], [7-9] are column positions
* [1-3], [6-8] base zero
*/
- assertTrue(af.hideFeatureColumns("Turn", true));
- hidden = af.getViewport().getColumnSelection().getHiddenColumns();
- assertEquals(2, hidden.size());
- assertEquals(1, hidden.get(0)[0]);
- assertEquals(3, hidden.get(0)[1]);
- assertEquals(6, hidden.get(1)[0]);
- assertEquals(8, hidden.get(1)[1]);
+ assertTrue(alignFrame.hideFeatureColumns("Turn", true));
+ hidden = alignFrame.getViewport().getColumnSelection().getHiddenColumns();
+ assertEquals(hidden.size(), 2);
+ assertEquals(hidden.get(0)[0], 1);
+ assertEquals(hidden.get(0)[1], 3);
+ assertEquals(hidden.get(1)[0], 6);
+ assertEquals(hidden.get(1)[1], 8);
+ }
+
+ @BeforeClass(alwaysRun = true)
+ public static void setUpBeforeClass() throws Exception
+ {
+ /*
+ * use read-only test properties file
+ */
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ Jalview.main(new String[] { "-nonews" });
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown()
+ {
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+ /**
+ * configure (read-only) properties for test to ensure Consensus is computed
+ * for colour Above PID testing
+ */
+ @BeforeMethod(alwaysRun = true)
+ public void setUp()
+ {
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+ Boolean.TRUE.toString());
+ af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
+ DataSourceType.FILE);
+
+ /*
+ * wait for Consensus thread to complete
+ */
+ synchronized (this)
+ {
+ while (af.getViewport().getConsensusSeq() == null)
+ {
+ try
+ {
+ wait(50);
+ } catch (InterruptedException e)
+ {
+ }
+ }
+ }
+ }
+
+ /**
+ * Test that changing background (alignment) colour scheme
+ * <ul>
+ * <li>with Apply Colour to All Groups not selected, does not change group
+ * colours</li>
+ * <li>with Apply Colour to All Groups selected, does change group colours</li>
+ * <li>in neither case, changes alignment or group colour thresholds (PID or
+ * Conservation)</li>
+ * </ul>
+ */
+ @Test(groups = "Functional")
+ public void testChangeColour_background_groupsAndThresholds()
+ {
+ AlignViewport av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+
+ /*
+ * Colour alignment by Buried Index
+ */
+ af.applyToAllGroups_actionPerformed(false);
+ af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
+ assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
+ assertFalse(av.getResidueShading().conservationApplied());
+ assertEquals(av.getResidueShading().getThreshold(), 0);
+
+ /*
+ * Apply Conservation 20%
+ */
+ af.conservationMenuItem_actionPerformed(true);
+ SliderPanel sp = SliderPanel.getSliderPanel();
+ assertEquals(sp.getTitle(), MessageManager.formatMessage(
+ "label.conservation_colour_increment",
+ new String[] { "Background" }));
+ assertTrue(sp.isForConservation());
+ sp.valueChanged(20);
+ assertTrue(av.getResidueShading().conservationApplied());
+ assertEquals(av.getResidueShading().getConservationInc(), 20);
+
+ /*
+ * Apply PID threshold 10% (conservation still applies as well)
+ */
+ af.abovePIDThreshold_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertFalse(sp.isForConservation());
+ assertEquals(sp.getTitle(), MessageManager.formatMessage(
+ "label.percentage_identity_threshold",
+ new String[] { "Background" }));
+ sp.valueChanged(10);
+ assertEquals(av.getResidueShading().getThreshold(), 10);
+ assertTrue(av.getResidueShading().conservationApplied());
+ assertEquals(av.getResidueShading().getConservationInc(), 20);
+
+ /*
+ * create a group with Strand colouring, 30% Conservation
+ * and 40% PID threshold
+ */
+ SequenceGroup sg = new SequenceGroup();
+ sg.addSequence(al.getSequenceAt(0), false);
+ sg.setStartRes(15);
+ sg.setEndRes(25);
+ av.setSelectionGroup(sg);
+
+ /*
+ * apply 30% Conservation to group
+ */
+ PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
+ popupMenu.changeColour_actionPerformed(JalviewColourScheme.Strand
+ .toString());
+ assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
+ assertEquals(al.getGroups().size(), 1);
+ assertSame(al.getGroups().get(0), sg);
+ popupMenu.conservationMenuItem_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertTrue(sp.isForConservation());
+ assertEquals(sp.getTitle(), MessageManager.formatMessage(
+ "label.conservation_colour_increment",
+ new String[] { sg.getName() }));
+ sp.valueChanged(30);
+ assertTrue(sg.getGroupColourScheme().conservationApplied());
+ assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
+
+ /*
+ * apply 40% PID threshold to group
+ */
+ popupMenu.abovePIDColour_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertFalse(sp.isForConservation());
+ assertEquals(sp.getTitle(), MessageManager.formatMessage(
+ "label.percentage_identity_threshold",
+ new String[] { sg.getName() }));
+ sp.valueChanged(40);
+ assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
+ // conservation threshold is unchanged:
+ assertTrue(sg.getGroupColourScheme().conservationApplied());
+ assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
+
+ /*
+ * change alignment colour - group colour, and all thresholds,
+ * should be unaffected
+ */
+ af.changeColour_actionPerformed(JalviewColourScheme.Turn.toString());
+ assertTrue(av.getGlobalColourScheme() instanceof TurnColourScheme);
+ assertTrue(av.getResidueShading().conservationApplied());
+ assertEquals(av.getResidueShading().getConservationInc(), 20);
+ assertEquals(av.getResidueShading().getThreshold(), 10);
+ assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
+ assertTrue(sg.getGroupColourScheme().conservationApplied());
+ assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
+ assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
+
+ /*
+ * Now change alignment colour with Apply Colour To All Groups
+ * - group colour should change, but not colour thresholds
+ */
+ af.applyToAllGroups_actionPerformed(true);
+ af.changeColour_actionPerformed(JalviewColourScheme.Helix.toString());
+ assertTrue(av.getGlobalColourScheme() instanceof HelixColourScheme);
+ assertTrue(av.getResidueShading().conservationApplied());
+ assertEquals(av.getResidueShading().getConservationInc(), 20);
+ assertEquals(av.getResidueShading().getThreshold(), 10);
+ assertTrue(sg.getColourScheme() instanceof HelixColourScheme);
+ assertTrue(sg.getGroupColourScheme().conservationApplied());
+ assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
+ assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
+ }
+
+ /**
+ * Test residue colouring with various options
+ * <ol>
+ * <li>no PID or Conservation threshold</li>
+ * <li>colour by Conservation applied</li>
+ * <li>colour by Conservation removed</li>
+ * <li>colour above PID - various values</li>
+ * <li>colour above PID removed</li>
+ * <li>Above PID plus By Conservation combined</li>
+ * <li>remove Above PID to leave just By Conservation</li>
+ * <li>re-add Above PID</li>
+ * <li>remove By Conservation to leave just Above PID</li>
+ * <li>remove Above PID to leave original colours</li>
+ * </ol>
+ */
+ @Test(groups = "Functional")
+ public void testColourThresholdActions()
+ {
+ AlignViewport av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+
+ /*
+ * Colour alignment by Helix Propensity, no thresholds
+ */
+ af.applyToAllGroups_actionPerformed(false);
+ af.changeColour_actionPerformed(JalviewColourScheme.Helix.toString());
+ assertTrue(av.getGlobalColourScheme() instanceof HelixColourScheme);
+ assertFalse(av.getResidueShading().conservationApplied());
+ assertEquals(av.getResidueShading().getThreshold(), 0);
+
+ /*
+ * inspect the colour of
+ * FER_CAPAN.9(I), column 14 (14 base 0)
+ * FER_CAPAN.10(SER), column 16 (15 base 0)
+ */
+ SequenceI ferCapan = al.findName("FER_CAPAN");
+ ResidueShaderI rs = av.getResidueShading();
+ Color c = rs.findColour('I', 14, ferCapan);
+ Color i_original = new Color(138, 117, 138);
+ assertEquals(c, i_original);
+ c = rs.findColour('S', 15, ferCapan);
+ Color s_original = new Color(54, 201, 54);
+ assertEquals(c, s_original);
+
+ /*
+ * colour by conservation with increment 10
+ */
+ af.conservationMenuItem_actionPerformed(true);
+ SliderPanel sp = SliderPanel.getSliderPanel();
+ assertTrue(sp.isForConservation());
+ assertEquals(sp.getValue(), 30); // initial slider setting
+ sp.valueChanged(10);
+ assertSame(rs, av.getResidueShading());
+ c = rs.findColour('I', 14, ferCapan);
+ Color i_faded = new Color(196, 186, 196);
+ assertEquals(c, i_faded);
+ c = rs.findColour('S', 15, ferCapan);
+ Color s_faded = new Color(144, 225, 144);
+ assertEquals(c, s_faded);
+
+ /*
+ * deselect By Conservation - colour should revert
+ */
+ af.conservationMenuItem_actionPerformed(false);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_original);
+
+ /*
+ * now Above PID, threshold = 0%
+ * should be no change
+ */
+ af.abovePIDThreshold_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertFalse(sp.isForConservation());
+ assertEquals(sp.getValue(), 0); // initial slider setting
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, i_original);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_original);
+
+ /*
+ * Above PID, threshold = 1%
+ * 15.I becomes White because no match to consensus (V)
+ * 16.S remains coloured as matches 66.66% consensus
+ */
+ sp.valueChanged(1);
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, Color.white);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_original);
+
+ /*
+ * threshold 66% - no further change yet...
+ */
+ sp.valueChanged(66);
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, Color.white);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_original);
+
+ /*
+ * threshold 67% - now both residues are white
+ */
+ sp.valueChanged(67);
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, Color.white);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, Color.white);
+
+ /*
+ * deselect Above PID - colours should revert
+ */
+ af.abovePIDThreshold_actionPerformed(false);
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, i_original);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_original);
+
+ /*
+ * Now combine Above 50% PID and By Conservation 10%
+ * 15.I is White because no match to consensus (V)
+ * 16.S is coloured but faded
+ */
+ af.abovePIDThreshold_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertFalse(sp.isForConservation());
+ sp.valueChanged(50);
+ af.conservationMenuItem_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertTrue(sp.isForConservation());
+ sp.valueChanged(10);
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, Color.white);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_faded);
+
+ /*
+ * turn off Above PID - should just leave Conservation fading as before
+ */
+ af.abovePIDThreshold_actionPerformed(false);
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, i_faded);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_faded);
+
+ /*
+ * Now add Above 50% PID to conservation colouring
+ * - should give the same as PID followed by conservation (above)
+ */
+ af.abovePIDThreshold_actionPerformed(true);
+ SliderPanel.getSliderPanel().valueChanged(50);
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, Color.white);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_faded);
+
+ /*
+ * turn off By Conservation
+ * should leave I white, S original (unfaded) colour
+ */
+ af.conservationMenuItem_actionPerformed(false);
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, Color.white);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_original);
+
+ /*
+ * finally turn off Above PID to leave original colours
+ */
+ af.abovePIDThreshold_actionPerformed(false);
+ c = rs.findColour('I', 14, ferCapan);
+ assertEquals(c, i_original);
+ c = rs.findColour('S', 15, ferCapan);
+ assertEquals(c, s_original);
+ }
+
+ /**
+ * Verify that making a New View transfers alignment and group colour schemes,
+ * including any thresholds, to the new view. Because New View is performed by
+ * saving and reloading a 'project' file, this is similar to verifying a
+ * project save and reload.
+ *
+ * @see Jalview2xmlTests#testStoreAndRecoverColourThresholds()
+ */
+ @Test(groups = "Functional")
+ public void testNewView_colourThresholds()
+ {
+ AlignViewport av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+
+ /*
+ * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
+ */
+ af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
+ assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
+ af.abovePIDThreshold_actionPerformed(true);
+ SliderPanel sp = SliderPanel.getSliderPanel();
+ assertFalse(sp.isForConservation());
+ sp.valueChanged(10);
+ af.conservationMenuItem_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertTrue(sp.isForConservation());
+ sp.valueChanged(20);
+ ResidueShaderI rs = av.getResidueShading();
+ assertEquals(rs.getThreshold(), 10);
+ assertTrue(rs.conservationApplied());
+ assertEquals(rs.getConservationInc(), 20);
+
+ /*
+ * create a group with Strand colouring, 30% Conservation
+ * and 40% PID threshold
+ */
+ SequenceGroup sg = new SequenceGroup();
+ sg.addSequence(al.getSequenceAt(0), false);
+ sg.setStartRes(15);
+ sg.setEndRes(25);
+ av.setSelectionGroup(sg);
+ PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
+ popupMenu.changeColour_actionPerformed(JalviewColourScheme.Strand
+ .toString());
+ assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
+ assertEquals(al.getGroups().size(), 1);
+ assertSame(al.getGroups().get(0), sg);
+ popupMenu.conservationMenuItem_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertTrue(sp.isForConservation());
+ sp.valueChanged(30);
+ popupMenu.abovePIDColour_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertFalse(sp.isForConservation());
+ sp.valueChanged(40);
+ rs = sg.getGroupColourScheme();
+ assertTrue(rs.conservationApplied());
+ assertEquals(rs.getConservationInc(), 30);
+ assertEquals(rs.getThreshold(), 40);
+
+ /*
+ * set slider panel focus to the background alignment
+ */
+ af.conservationMenuItem_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertTrue(sp.isForConservation());
+ assertEquals(sp.getTitle(), MessageManager.formatMessage(
+ "label.conservation_colour_increment",
+ new String[] { "Background" }));
+
+ /*
+ * make a new View, verify alignment and group colour schemes
+ */
+ af.newView_actionPerformed(null);
+ assertEquals(af.alignPanel.getViewName(), "View 1");
+ AlignViewport av2 = af.getViewport();
+ assertNotSame(av, av2);
+ rs = av2.getResidueShading();
+ assertNotSame(av.getResidueShading(), rs);
+ assertEquals(rs.getThreshold(), 10);
+ assertTrue(rs.conservationApplied());
+ assertEquals(rs.getConservationInc(), 20);
+ assertEquals(av2.getAlignment().getGroups().size(), 1);
+ sg = av2.getAlignment().getGroups().get(0);
+ rs = sg.getGroupColourScheme();
+ assertTrue(rs.conservationApplied());
+ assertEquals(rs.getConservationInc(), 30);
+ assertEquals(rs.getThreshold(), 40);
+
+ /*
+ * check the Conservation SliderPanel (still open) is linked to
+ * and updates the new view (JAL-2385)
+ */
+ sp = SliderPanel.getSliderPanel();
+ assertTrue(sp.isForConservation());
+ assertEquals(sp.getTitle(), MessageManager.formatMessage(
+ "label.conservation_colour_increment",
+ new String[] { "View 1" }));
+ sp.valueChanged(22);
+ assertEquals(av2.getResidueShading().getConservationInc(), 22);
}
}
import jalview.datamodel.SearchResults;
import jalview.datamodel.SearchResultsI;
import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
@BeforeClass(alwaysRun = true)
public static void setUpBeforeClass() throws Exception
{
- Jalview.main(new String[] { "-props", "test/jalview/testProps.jvprops" });
+ Jalview.main(new String[] { "-nonews", "-props",
+ "test/jalview/testProps.jvprops" });
}
@BeforeMethod(alwaysRun = true)
public void testSetGlobalColourScheme()
{
/*
- * test for JAL-2283 don't inadvertently turn on colour by conservation
+ * test for JAL-2283: don't inadvertently turn on colour by conservation
*/
- Cache.applicationProperties.setProperty("DEFAULT_COLOUR_PROT", "NONE");
+ Cache.applicationProperties.setProperty("DEFAULT_COLOUR_PROT", "None");
Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
Boolean.TRUE.toString());
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
ColourSchemeI cs = new PIDColourScheme();
af.getViewport().setGlobalColourScheme(cs);
- assertFalse(cs.conservationApplied());
+ assertFalse(af.getViewport().getResidueShading()
+ .conservationApplied());
}
@Test(groups = { "Functional" })
af.getViewport().setSearchResults(null);
assertFalse(af.getViewport().hasSearchResults());
}
+
+ /**
+ * Verify that setting the selection group has the side-effect of setting the
+ * context on the group, unless it already has one
+ */
+ @Test(groups = { "Functional" })
+ public void testSetSelectionGroup()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport av = af.getViewport();
+ SequenceGroup sg1 = new SequenceGroup();
+ SequenceGroup sg2 = new SequenceGroup();
+
+ av.setSelectionGroup(sg1);
+ assertSame(sg1.getContext(), av.getAlignment()); // context set
+
+ sg2.setContext(sg1);
+ av.setSelectionGroup(sg2);
+ assertSame(sg2.getContext(), sg1); // unchanged
+ }
}
types = AnnotationChooser.getAnnotationTypes(
parentPanel.getAlignment(), false);
- assertEquals("Not six annotation types", 6, types.size());
+ assertEquals("Not six annotation types", 7, types.size());
assertTrue("IUPRED missing", types.contains("IUPRED"));
assertTrue("JMol missing", types.contains("JMol"));
assertTrue("Beauty missing", types.contains("Beauty"));
assertTrue("Consensus missing", types.contains("Consensus"));
assertTrue("Quality missing", types.contains("Quality"));
assertTrue("Conservation missing", types.contains("Conservation"));
+ assertTrue("Occupancy missing", types.contains("Occupancy"));
}
/**
AlignmentAnnotation[] anns = parentPanel.getAlignment()
.getAlignmentAnnotation();
- assertTrue(anns[5].visible); // JMol for seq3
- assertTrue(anns[7].visible); // JMol for seq1
+ int autocalc = countAutocalc(anns);
+ assertTrue(anns[autocalc + 2].visible); // JMol for seq3
+ assertTrue(anns[autocalc + 4].visible); // JMol for seq1
setSelected(getTypeCheckbox("JMol"), true);
assertTrue(anns[0].visible); // Conservation
assertTrue(anns[1].visible); // Quality
assertTrue(anns[2].visible); // Consensus
- assertTrue(anns[3].visible); // IUPred for seq0
- assertTrue(anns[4].visible); // Beauty
- assertFalse(anns[5].visible); // JMol for seq3 - not selected but hidden
- assertTrue(anns[6].visible); // IUPRED for seq2
- assertFalse(anns[7].visible); // JMol for seq1 - selected and hidden
+ assertTrue(anns[3].visible); // Occupancy
+ assertTrue(anns[4].visible); // IUPred for seq0
+ assertTrue(anns[5].visible); // Beauty
+ assertFalse(anns[6].visible); // JMol for seq3 - not selected but hidden
+ assertTrue(anns[7].visible); // IUPRED for seq2
+ assertFalse(anns[8].visible); // JMol for seq1 - selected and hidden
}
/**
AlignmentAnnotation[] anns = parentPanel.getAlignment()
.getAlignmentAnnotation();
- assertTrue(anns[7].visible); // JMol for seq1
+ int autocalc = countAutocalc(anns);
+ assertTrue(anns[autocalc + 4].visible); // JMol for seq1
setSelected(getTypeCheckbox("JMol"), true);
assertTrue(anns[0].visible); // Conservation
assertTrue(anns[1].visible); // Quality
assertTrue(anns[2].visible); // Consensus
- assertTrue(anns[3].visible); // IUPred for seq0
- assertTrue(anns[4].visible); // Beauty
- assertTrue(anns[5].visible); // JMol for seq3 not in selection group
- assertTrue(anns[6].visible); // IUPRED for seq2
- assertFalse(anns[7].visible); // JMol for seq1 in selection group
+ assertTrue(anns[3].visible); // Occupancy
+ assertTrue(anns[4].visible); // IUPred for seq0
+ assertTrue(anns[5].visible); // Beauty
+ assertTrue(anns[6].visible); // JMol for seq3 not in selection group
+ assertTrue(anns[7].visible); // IUPRED for seq2
+ assertFalse(anns[8].visible); // JMol for seq1 in selection group
}
/**
// select JMol - all hidden
setSelected(typeCheckbox, true);
- assertFalse(anns[5].visible); // JMol for seq3
- assertFalse(anns[7].visible); // JMol for seq1
+ int autocalc = countAutocalc(anns);
+ assertFalse(anns[autocalc + 2].visible); // JMol for seq3
+ assertFalse(anns[autocalc + 4].visible); // JMol for seq1
// deselect JMol - all unhidden
setSelected(typeCheckbox, false);
- assertTrue(anns[0].visible); // Conservation
- assertTrue(anns[1].visible); // Quality
- assertTrue(anns[2].visible); // Consensus
- assertTrue(anns[3].visible); // IUPred for seq0
- assertTrue(anns[4].visible); // Beauty
- assertTrue(anns[5].visible); // JMol for seq3
- assertTrue(anns[6].visible); // IUPRED for seq2
- assertTrue(anns[7].visible); // JMol for seq1
+ for (AlignmentAnnotation ann : anns)
+ {
+ assertTrue(ann.visible);
+ }
+ }
+
+ /**
+ * Returns a count of autocalculated annotations in the set provided
+ *
+ * @param anns
+ * @return
+ */
+ private int countAutocalc(AlignmentAnnotation[] anns)
+ {
+ int count = 0;
+ for (AlignmentAnnotation ann : anns)
+ {
+ if (ann.autoCalculated)
+ {
+ count++;
+ }
+ }
+ return count;
}
/**
setSelected(allSequencesCheckbox, true);
setSelected(hideCheckbox, true);
setSelected(getTypeCheckbox("JMol"), true);
- assertFalse(anns[5].visible); // JMol for seq3
- assertFalse(anns[7].visible); // JMol for seq1
+ int autocalc = countAutocalc(anns);
+ assertFalse(anns[autocalc + 2].visible); // JMol for seq3
+ assertFalse(anns[autocalc + 4].visible); // JMol for seq1
// ...now show them...
setSelected(showCheckbox, true);
- assertTrue(anns[0].visible); // Conservation
- assertTrue(anns[1].visible); // Quality
- assertTrue(anns[2].visible); // Consensus
- assertTrue(anns[3].visible); // IUPred for seq0
- assertTrue(anns[4].visible); // Beauty
- assertTrue(anns[5].visible); // JMol for seq3
- assertTrue(anns[6].visible); // IUPRED for seq2
- assertTrue(anns[7].visible); // JMol for seq1
+ for (AlignmentAnnotation ann : anns)
+ {
+ assertTrue(ann.visible);
+ }
}
/**
setSelected(hideCheckbox, true);
setSelected(getTypeCheckbox("JMol"), true);
- assertTrue(anns[5].visible); // JMol for seq3
- assertFalse(anns[7].visible); // JMol for seq1
+ int autocalc = countAutocalc(anns);
+ assertTrue(anns[autocalc + 2].visible); // JMol for seq3
+ assertFalse(anns[autocalc + 4].visible); // JMol for seq1
// ...now show them...
setSelected(showCheckbox, true);
- assertTrue(anns[0].visible); // Conservation
- assertTrue(anns[1].visible); // Quality
- assertTrue(anns[2].visible); // Consensus
- assertTrue(anns[3].visible); // IUPred for seq0
- assertTrue(anns[4].visible); // Beauty
- assertTrue(anns[5].visible); // JMol for seq3
- assertTrue(anns[6].visible); // IUPRED for seq2
- assertTrue(anns[7].visible); // JMol for seq1
+ for (AlignmentAnnotation ann : anns)
+ {
+ assertTrue(ann.visible);
+ }
}
/**
final Checkbox typeCheckbox = getTypeCheckbox("JMol");
// select JMol - all shown
setSelected(typeCheckbox, true);
- assertTrue(anns[5].visible); // JMol for seq3
- assertTrue(anns[7].visible); // JMol for seq1
+ int autocalc = countAutocalc(anns);
+ assertTrue(anns[autocalc + 2].visible); // JMol for seq3
+ assertTrue(anns[autocalc + 4].visible); // JMol for seq1
// deselect JMol - all hidden
setSelected(typeCheckbox, false);
assertTrue(anns[0].visible); // Conservation
assertTrue(anns[1].visible); // Quality
assertTrue(anns[2].visible); // Consensus
- assertTrue(anns[3].visible); // IUPred for seq0
- assertTrue(anns[4].visible); // Beauty
- assertFalse(anns[5].visible); // JMol for seq3
- assertTrue(anns[6].visible); // IUPRED for seq2
- assertFalse(anns[7].visible); // JMol for seq1
+ assertTrue(anns[3].visible); // Occupancy
+ assertTrue(anns[4].visible); // IUPred for seq0
+ assertTrue(anns[5].visible); // Beauty
+ assertFalse(anns[6].visible); // JMol for seq3
+ assertTrue(anns[7].visible); // IUPRED for seq2
+ assertFalse(anns[8].visible); // JMol for seq1
}
/**
// select JMol - should remain visible
setSelected(getTypeCheckbox("JMol"), true);
- assertTrue(anns[5].visible); // JMol for seq3
- assertTrue(anns[7].visible); // JMol for seq1
+ int autocalc = countAutocalc(anns);
+ assertTrue(anns[autocalc + 2].visible); // JMol for seq3
+ assertTrue(anns[autocalc + 4].visible); // JMol for seq1
// deselect JMol - should be hidden for selected sequences only
setSelected(getTypeCheckbox("JMol"), false);
assertTrue(anns[0].visible); // Conservation
assertTrue(anns[1].visible); // Quality
assertTrue(anns[2].visible); // Consensus
- assertTrue(anns[3].visible); // IUPred for seq0
- assertTrue(anns[4].visible); // Beauty
- assertTrue(anns[5].visible); // JMol for seq3 not in selection group
- assertTrue(anns[6].visible); // IUPRED for seq2
- assertFalse(anns[7].visible); // JMol for seq1 in selection group
+ assertTrue(anns[3].visible); // Occupancy
+ assertTrue(anns[4].visible); // IUPred for seq0
+ assertTrue(anns[5].visible); // Beauty
+ assertTrue(anns[6].visible); // JMol for seq3 not in selection group
+ assertTrue(anns[7].visible); // IUPRED for seq2
+ assertFalse(anns[8].visible); // JMol for seq1 in selection group
}
/**
AlignmentAnnotation[] anns = parentPanel.getAlignment()
.getAlignmentAnnotation();
- // remember 3 annotations to skip (Conservation/Quality/Consensus)
- assertFalse(testee.isInActionScope(anns[3]));
- assertFalse(testee.isInActionScope(anns[4]));
- assertFalse(testee.isInActionScope(anns[5]));
- assertTrue(testee.isInActionScope(anns[6]));
- assertTrue(testee.isInActionScope(anns[7]));
+ int autocalc = countAutocalc(anns);
+ assertFalse(testee.isInActionScope(anns[autocalc]));
+ assertFalse(testee.isInActionScope(anns[autocalc + 1]));
+ assertFalse(testee.isInActionScope(anns[autocalc + 2]));
+ assertTrue(testee.isInActionScope(anns[autocalc + 3]));
+ assertTrue(testee.isInActionScope(anns[autocalc + 4]));
}
/**
AlignmentAnnotation[] anns = parentPanel.getAlignment()
.getAlignmentAnnotation();
- // remember 3 annotations to skip (Conservation/Quality/Consensus)
- assertTrue(testee.isInActionScope(anns[3]));
- assertTrue(testee.isInActionScope(anns[4]));
- assertTrue(testee.isInActionScope(anns[5]));
- assertFalse(testee.isInActionScope(anns[6]));
- assertFalse(testee.isInActionScope(anns[7]));
+ int autocalc = countAutocalc(anns);
+ assertTrue(testee.isInActionScope(anns[autocalc]));
+ assertTrue(testee.isInActionScope(anns[autocalc + 1]));
+ assertTrue(testee.isInActionScope(anns[autocalc + 2]));
+ assertFalse(testee.isInActionScope(anns[autocalc + 3]));
+ assertFalse(testee.isInActionScope(anns[autocalc + 4]));
}
/**
assertTrue(anns[0].visible); // Conservation
assertTrue(anns[1].visible); // Quality
assertTrue(anns[2].visible); // Consensus
- assertFalse(anns[3].visible); // IUPRED
- assertTrue(anns[4].visible); // Beauty (not seq-related)
- assertFalse(anns[5].visible); // JMol
- assertFalse(anns[6].visible); // IUPRED
- assertFalse(anns[7].visible); // JMol
+ assertTrue(anns[3].visible); // Occupancy
+ assertFalse(anns[4].visible); // IUPRED
+ assertTrue(anns[5].visible); // Beauty (not seq-related)
+ assertFalse(anns[6].visible); // JMol
+ assertFalse(anns[7].visible); // IUPRED
+ assertFalse(anns[8].visible); // JMol
// reset - should all be visible
testee.resetOriginalState();
assertEquals(4, showOptions.length); // includes 'All' and separator
assertEquals(4, hideOptions.length);
- assertEquals("All", ((JMenuItem) showOptions[0]).getText());
+ String all = MessageManager.getString("label.all");
+ assertEquals(all, ((JMenuItem) showOptions[0]).getText());
assertTrue(showOptions[1] instanceof JPopupMenu.Separator);
assertEquals(JSeparator.HORIZONTAL,
((JSeparator) showOptions[1]).getOrientation());
assertEquals("SSP", ((JMenuItem) showOptions[3]).getText());
assertEquals("JPred", ((JMenuItem) showOptions[3]).getToolTipText());
- assertEquals("All", ((JMenuItem) hideOptions[0]).getText());
+ assertEquals(all, ((JMenuItem) hideOptions[0]).getText());
assertTrue(hideOptions[1] instanceof JPopupMenu.Separator);
assertEquals(JSeparator.HORIZONTAL,
((JSeparator) hideOptions[1]).getOrientation());
assertEquals(2, showOptions.length); // includes 'All' and separator
assertEquals(4, hideOptions.length);
- assertEquals("All", ((JMenuItem) showOptions[0]).getText());
+ String all = MessageManager.getString("label.all");
+ assertEquals(all, ((JMenuItem) showOptions[0]).getText());
assertTrue(showOptions[1] instanceof JPopupMenu.Separator);
assertEquals(JSeparator.HORIZONTAL,
((JSeparator) showOptions[1]).getOrientation());
- assertEquals("All", ((JMenuItem) hideOptions[0]).getText());
+ assertEquals(all, ((JMenuItem) hideOptions[0]).getText());
assertTrue(hideOptions[1] instanceof JPopupMenu.Separator);
assertEquals(JSeparator.HORIZONTAL,
((JSeparator) hideOptions[1]).getOrientation());
assertEquals(4, showOptions.length); // includes 'All' and separator
assertEquals(2, hideOptions.length);
- assertEquals("All", ((JMenuItem) showOptions[0]).getText());
+ String all = MessageManager.getString("label.all");
+ assertEquals(all, ((JMenuItem) showOptions[0]).getText());
assertTrue(showOptions[1] instanceof JPopupMenu.Separator);
assertEquals(JSeparator.HORIZONTAL,
((JSeparator) showOptions[1]).getOrientation());
assertEquals("Temp", ((JMenuItem) showOptions[3]).getText());
assertEquals("PDB2", ((JMenuItem) showOptions[3]).getToolTipText());
- assertEquals("All", ((JMenuItem) hideOptions[0]).getText());
+ assertEquals(all, ((JMenuItem) hideOptions[0]).getText());
assertTrue(hideOptions[1] instanceof JPopupMenu.Separator);
assertEquals(JSeparator.HORIZONTAL,
((JSeparator) hideOptions[1]).getOrientation());
}
}
- public static AlignmentI readAlignmentFile(File f)
+ AlignmentI readAlignmentFile(File f)
{
System.out.println("Reading file: " + f);
String ff = f.getPath();
* - label for IO class used to write and read back in the data from
* f
*/
-
- // @Test(groups ={ "Functional" })
- public static void testAnnotationFileIO(String testname, File f,
+ void testAnnotationFileIO(String testname, File f,
File annotFile)
{
System.out.println("Test: " + testname + "\nReading annotation file '"
--- /dev/null
+package jalview.io;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Iterator;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class FileFormatsTest
+{
+ @AfterMethod(alwaysRun = true)
+ public void tearDown()
+ {
+ FileFormats.getInstance().reset();
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp()
+ {
+ FileFormats.getInstance().reset();
+ }
+
+ @Test(groups = "Functional")
+ public void testIsIdentifiable()
+ {
+ FileFormats formats = FileFormats.getInstance();
+ assertTrue(formats.isIdentifiable(formats.forName(FileFormat.Fasta
+ .getName())));
+ assertTrue(formats.isIdentifiable(formats.forName(FileFormat.MMCif
+ .getName())));
+ assertTrue(formats.isIdentifiable(formats.forName(FileFormat.Jnet
+ .getName())));
+ assertFalse(formats.isIdentifiable(formats.forName(FileFormat.Jalview
+ .getName())));
+ assertFalse(formats.isIdentifiable(null));
+
+ /*
+ * remove and re-add a format: it is still 'identifiable'
+ */
+ formats.deregisterFileFormat(FileFormat.Fasta.getName());
+ assertNull(formats.forName(FileFormat.Fasta.getName()));
+ formats.registerFileFormat(FileFormat.Fasta);
+ assertSame(FileFormat.Fasta,
+ formats.forName(FileFormat.Fasta.getName()));
+ assertTrue(formats.isIdentifiable(FileFormat.Fasta));
+ }
+
+ @Test(groups = "Functional")
+ public void testGetReadableFormats()
+ {
+ String expected = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GFF or Jalview features, PDB, mmCIF, Jalview]";
+ FileFormats formats = FileFormats.getInstance();
+ assertEquals(formats.getReadableFormats().toString(), expected);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetWritableFormats()
+ {
+ String expected = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP]";
+ FileFormats formats = FileFormats.getInstance();
+ assertEquals(formats.getWritableFormats(true).toString(), expected);
+ expected = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP, Jalview]";
+ assertEquals(formats.getWritableFormats(false).toString(), expected);
+ }
+
+ @Test(groups = "Functional")
+ public void testDeregisterFileFormat()
+ {
+ String writable = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP]";
+ String readable = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GFF or Jalview features, PDB, mmCIF, Jalview]";
+ FileFormats formats = FileFormats.getInstance();
+ assertEquals(formats.getWritableFormats(true).toString(), writable);
+ assertEquals(formats.getReadableFormats().toString(), readable);
+
+ formats.deregisterFileFormat(FileFormat.Fasta.getName());
+ writable = "[PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP]";
+ readable = "[PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GFF or Jalview features, PDB, mmCIF, Jalview]";
+ assertEquals(formats.getWritableFormats(true).toString(), writable);
+ assertEquals(formats.getReadableFormats().toString(), readable);
+
+ /*
+ * re-register the format: it gets added to the end of the list
+ */
+ formats.registerFileFormat(FileFormat.Fasta);
+ writable = "[PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP, Fasta]";
+ readable = "[PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GFF or Jalview features, PDB, mmCIF, Jalview, Fasta]";
+ assertEquals(formats.getWritableFormats(true).toString(), writable);
+ assertEquals(formats.getReadableFormats().toString(), readable);
+ }
+
+ @Test(groups = "Functional")
+ public void testForName()
+ {
+ FileFormats formats = FileFormats.getInstance();
+ for (FileFormatI ff : FileFormat.values())
+ {
+ assertSame(ff, formats.forName(ff.getName()));
+ assertSame(ff, formats.forName(ff.getName().toUpperCase()));
+ assertSame(ff, formats.forName(ff.getName().toLowerCase()));
+ }
+ assertNull(formats.forName(null));
+ assertNull(formats.forName("rubbish"));
+ }
+
+ @Test(groups = "Functional")
+ public void testRegisterFileFormat()
+ {
+ FileFormats formats = FileFormats.getInstance();
+ assertSame(FileFormat.MMCif,
+ formats.forName(FileFormat.MMCif.getName()));
+ assertTrue(formats.isIdentifiable(FileFormat.MMCif));
+
+ /*
+ * deregister mmCIF format
+ */
+ formats.deregisterFileFormat(FileFormat.MMCif.getName());
+ assertNull(formats.forName(FileFormat.MMCif.getName()));
+
+ /*
+ * re-register mmCIF format
+ * it is reinstated (still 'identifiable')
+ */
+ formats.registerFileFormat(FileFormat.MMCif);
+ assertSame(FileFormat.MMCif,
+ formats.forName(FileFormat.MMCif.getName()));
+ assertTrue(formats.isIdentifiable(FileFormat.MMCif));
+ // repeating does nothing
+ formats.registerFileFormat(FileFormat.MMCif);
+ assertSame(FileFormat.MMCif,
+ formats.forName(FileFormat.MMCif.getName()));
+ }
+
+ @Test(groups = "Functional")
+ public void testGetFormats()
+ {
+ /*
+ * verify the list of file formats registered matches the enum values
+ */
+ FileFormats instance = FileFormats.getInstance();
+ Iterator<FileFormatI> formats = instance.getFormats()
+ .iterator();
+ FileFormatI[] builtIn = FileFormat.values();
+
+ for (FileFormatI ff : builtIn)
+ {
+ assertSame(ff, formats.next());
+ }
+ assertFalse(formats.hasNext());
+
+ /*
+ * remove the first format, check it is no longer in
+ * the list of formats
+ */
+ String firstFormatName = instance.getFormats().iterator().next()
+ .getName();
+ instance.deregisterFileFormat(firstFormatName);
+ assertNotEquals(instance.getFormats().iterator().next().getName(),
+ firstFormatName);
+ }
+}
static Object[][] getFormats()
{
List<FileFormatI> both = new ArrayList<FileFormatI>();
- for (FileFormat format : FileFormat.values())
+ for (FileFormatI format : FileFormats.getInstance().getFormats())
{
if (format.isReadable() && format.isWritable()
&& format.isTextFormat())
null, true, true, false, 21, 29);
ColourSchemeI scheme = ColourSchemeMapper.getJalviewColourScheme(
"zappo", seqGrp);
- seqGrp.cs = scheme;
+ seqGrp.cs.setColourScheme(scheme);
seqGrp.setShowNonconserved(false);
seqGrp.setDescription(null);
*/
package jalview.io;
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertFalse;
-import static org.testng.AssertJUnit.assertNotNull;
-import static org.testng.AssertJUnit.assertSame;
-import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
import jalview.gui.AlignmentPanel;
import jalview.gui.Desktop;
import jalview.gui.Jalview2XML;
import jalview.gui.JvOptionPane;
+import jalview.gui.PopupMenu;
+import jalview.gui.SliderPanel;
+import jalview.renderer.ResidueShaderI;
import jalview.schemes.AnnotationColourGradient;
+import jalview.schemes.BuriedColourScheme;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.JalviewColourScheme;
+import jalview.schemes.RNAHelicesColour;
+import jalview.schemes.StrandColourScheme;
import jalview.schemes.TCoffeeColourScheme;
import jalview.structure.StructureImportSettings;
import jalview.viewmodel.AlignmentViewport;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Jalview2xmlTests extends Jalview2xmlBase
{
+ @Override
@BeforeClass(alwaysRun = true)
public void setUpJvOptionPane()
{
String inFile = "examples/RF00031_folded.stk";
String tfile = File.createTempFile("JalviewTest", ".jvp")
.getAbsolutePath();
- AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
- inFile, DataSourceType.FILE);
- assertTrue("Didn't read input file " + inFile, af != null);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Didn't read input file " + inFile);
int olddsann = countDsAnn(af.getViewport());
- assertTrue("Didn't find any dataset annotations", olddsann > 0);
- af.rnahelicesColour_actionPerformed(null);
+ assertTrue(olddsann > 0, "Didn't find any dataset annotations");
+ af.changeColour_actionPerformed(JalviewColourScheme.RNAHelices
+ .toString());
assertTrue(
- "Couldn't apply RNA helices colourscheme",
- af.getViewport().getGlobalColourScheme() instanceof jalview.schemes.RNAHelicesColour);
- assertTrue("Failed to store as a project.",
- af.saveAlignment(tfile, FileFormat.Jalview));
+ af.getViewport().getGlobalColourScheme() instanceof RNAHelicesColour,
+ "Couldn't apply RNA helices colourscheme");
+ assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
+ "Failed to store as a project.");
af.closeMenuItem_actionPerformed(true);
af = null;
- af = new FileLoader().LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
- assertTrue("Failed to import new project", af != null);
+ af = new FileLoader()
+ .LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
+ assertNotNull(af, "Failed to import new project");
int newdsann = countDsAnn(af.getViewport());
- assertTrue(
+ assertEquals(olddsann, newdsann,
"Differing numbers of dataset sequence annotation\nOriginally "
- + olddsann + " and now " + newdsann,
- olddsann == newdsann);
+ + olddsann + " and now " + newdsann);
System.out
.println("Read in same number of annotations as originally present ("
+ olddsann + ")");
assertTrue(
- "RNA helices colourscheme was not applied on import.",
- af.getViewport().getGlobalColourScheme() instanceof jalview.schemes.RNAHelicesColour);
+
+ af.getViewport().getGlobalColourScheme() instanceof RNAHelicesColour,
+ "RNA helices colourscheme was not applied on import.");
}
@Test(groups = { "Functional" })
String inFile = "examples/uniref50.fa", inAnnot = "examples/uniref50.score_ascii";
String tfile = File.createTempFile("JalviewTest", ".jvp")
.getAbsolutePath();
- AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
- inFile, DataSourceType.FILE);
- assertNotNull("Didn't read input file " + inFile, af);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Didn't read input file " + inFile);
af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
- assertSame("Didn't set T-coffee colourscheme", af.getViewport()
- .getGlobalColourScheme().getClass(), TCoffeeColourScheme.class);
- assertNotNull("Recognise T-Coffee score from string",
- ColourSchemeProperty.getColour(af.getViewport()
- .getAlignment(), ColourSchemeProperty.getColourName(af
- .getViewport().getGlobalColourScheme())));
-
- assertTrue("Failed to store as a project.",
- af.saveAlignment(tfile, FileFormat.Jalview));
+ assertSame(af.getViewport().getGlobalColourScheme().getClass(),
+ TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
+ assertNotNull(ColourSchemeProperty.getColourScheme(af.getViewport()
+ .getAlignment(), af.getViewport().getGlobalColourScheme()
+ .getSchemeName()), "Recognise T-Coffee score from string");
+
+ assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
+ "Failed to store as a project.");
af.closeMenuItem_actionPerformed(true);
af = null;
- af = new FileLoader().LoadFileWaitTillLoaded(tfile,
- DataSourceType.FILE);
- assertNotNull("Failed to import new project", af);
- assertSame("Didn't set T-coffee colourscheme for imported project.", af
- .getViewport().getGlobalColourScheme().getClass(),
- TCoffeeColourScheme.class);
+ af = new FileLoader()
+ .LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
+ assertNotNull(af, "Failed to import new project");
+ assertSame(af.getViewport().getGlobalColourScheme().getClass(),
+ TCoffeeColourScheme.class,
+ "Didn't set T-coffee colourscheme for imported project.");
System.out
.println("T-Coffee score shading successfully recovered from project.");
}
String inFile = "examples/uniref50.fa", inAnnot = "examples/testdata/uniref50_iupred.jva";
String tfile = File.createTempFile("JalviewTest", ".jvp")
.getAbsolutePath();
- AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile, DataSourceType.FILE);
- assertNotNull("Didn't read input file " + inFile, af);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ DataSourceType.FILE);
+ assertNotNull(af, "Didn't read input file " + inFile);
af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
AlignmentAnnotation[] aa = af.getViewport().getAlignment()
.getSequenceAt(0).getAnnotation("IUPredWS (Short)");
assertTrue(
- "Didn't find any IUPred annotation to use to shade alignment.",
- aa != null && aa.length > 0);
+
+ aa != null && aa.length > 0,
+ "Didn't find any IUPred annotation to use to shade alignment.");
AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
AnnotationColourGradient.ABOVE_THRESHOLD);
AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0],
SequenceGroup sg = new SequenceGroup();
sg.setStartRes(57);
sg.setEndRes(92);
- sg.cs = gcs;
+ sg.cs.setColourScheme(gcs);
af.getViewport().getAlignment().addGroup(sg);
sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
af.alignPanel.alignmentChanged();
- assertTrue("Failed to store as a project.",
- af.saveAlignment(tfile, FileFormat.Jalview));
+ assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
+ "Failed to store as a project.");
af.closeMenuItem_actionPerformed(true);
af = null;
- af = new FileLoader().LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
- assertTrue("Failed to import new project", af != null);
+ af = new FileLoader()
+ .LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
+ assertNotNull(af, "Failed to import new project");
// check for group and alignment colourschemes
ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups()
- .get(0).cs;
- assertNotNull("Didn't recover global colourscheme", _rcs);
- assertTrue("Didn't recover annotation colour global scheme",
- _rcs instanceof AnnotationColourGradient);
+ .get(0).getColourScheme();
+ assertNotNull(_rcs, "Didn't recover global colourscheme");
+ assertTrue(_rcs instanceof AnnotationColourGradient,
+ "Didn't recover annotation colour global scheme");
AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
- assertTrue("Annotation colourscheme wasn't sequence associated",
- __rcs.isSeqAssociated());
+ assertTrue(__rcs.isSeqAssociated(),
+ "Annotation colourscheme wasn't sequence associated");
boolean diffseqcols = false, diffgseqcols = false;
SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize
&& (!diffseqcols || !diffgseqcols); p++)
{
- if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0]) != _rcs
- .findColour(sqs[5].getCharAt(p), p, sqs[5]))
+ if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
+ .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
{
diffseqcols = true;
}
}
- assertTrue("Got Different sequence colours", diffseqcols);
+ assertTrue(diffseqcols, "Got Different sequence colours");
System.out
.println("Per sequence colourscheme (Background) successfully applied and recovered.");
- assertNotNull("Didn't recover group colourscheme", _rgcs);
- assertTrue("Didn't recover annotation colour group colourscheme",
- _rgcs instanceof AnnotationColourGradient);
+ assertNotNull(_rgcs, "Didn't recover group colourscheme");
+ assertTrue(_rgcs instanceof AnnotationColourGradient,
+ "Didn't recover annotation colour group colourscheme");
__rcs = (AnnotationColourGradient) _rgcs;
- assertTrue("Group Annotation colourscheme wasn't sequence associated",
- __rcs.isSeqAssociated());
+ assertTrue(__rcs.isSeqAssociated(),
+ "Group Annotation colourscheme wasn't sequence associated");
for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize
&& (!diffseqcols || !diffgseqcols); p++)
{
- if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1]) != _rgcs
- .findColour(sqs[2].getCharAt(p), p, sqs[2]))
+ if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null, 0f) != _rgcs
+ .findColour(sqs[2].getCharAt(p), p, sqs[2], null, 0f))
{
diffgseqcols = true;
}
}
- assertTrue("Got Different group sequence colours", diffgseqcols);
+ assertTrue(diffgseqcols, "Got Different group sequence colours");
System.out
.println("Per sequence (Group) colourscheme successfully applied and recovered.");
}
.getAlignFrames().length;
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", DataSourceType.FILE);
- assertNotNull("Didn't read in the example file correctly.", af);
- assertTrue("Didn't gather the views in the example file.",
- Desktop.getAlignFrames().length == 1 + origCount);
+ assertNotNull(af, "Didn't read in the example file correctly.");
+ assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
+ "Didn't gather the views in the example file.");
}
StructureImportSettings.setVisibleChainAnnotation(true);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", DataSourceType.FILE);
- assertNotNull("Didn't read in the example file correctly.", af);
+ assertNotNull(af, "Didn't read in the example file correctly.");
AlignmentViewPanel sps = null;
for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
{
break;
}
}
- assertNotNull("Couldn't find the structure view", sps);
+ assertNotNull(sps, "Couldn't find the structure view");
AlignmentAnnotation refan = null;
for (AlignmentAnnotation ra : sps.getAlignment()
.getAlignmentAnnotation())
break;
}
}
- assertNotNull("Annotation secondary structure not found.", refan);
+ assertNotNull(refan, "Annotation secondary structure not found.");
SequenceI sq = sps.getAlignment().findName("1A70|");
- assertNotNull("Couldn't find 1a70 null chain", sq);
+ assertNotNull(sq, "Couldn't find 1a70 null chain");
// compare the manually added temperature factor annotation
// to the track automatically transferred from the pdb structure on load
- assertNotNull("1a70 has no annotation", sq.getDatasetSequence()
- .getAnnotation());
+ assertNotNull(sq.getDatasetSequence().getAnnotation(),
+ "1a70 has no annotation");
for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
{
AlignmentAnnotation alaa;
try
{
assertTrue(
- "Mismatch at alignment position " + p,
(alaa.annotations[p] == null && refan.annotations[p] == null)
- || alaa.annotations[p].value == refan.annotations[p].value);
+ || alaa.annotations[p].value == refan.annotations[p].value,
+ "Mismatch at alignment position " + p);
} catch (NullPointerException q)
{
Assert.fail("Mismatch of alignment annotations at position "
{
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", DataSourceType.FILE);
- assertNotNull("Didn't read in the example file correctly.", af);
+ assertNotNull(af, "Didn't read in the example file correctly.");
AlignmentViewPanel sps = null, groups = null;
for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
{
groups = ap;
}
}
- assertNotNull("Couldn't find the structure view", sps);
- assertNotNull("Couldn't find the MAFFT view", groups);
+ assertNotNull(sps, "Couldn't find the structure view");
+ assertNotNull(groups, "Couldn't find the MAFFT view");
ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
// check FileLoader returned a reference to the one alignFrame that is
// actually on the Desktop
- assertTrue(
- "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window",
- af == Desktop.getAlignFrameFor(af.getViewport()));
+ assertSame(
+ af,
+ Desktop.getAlignFrameFor(af.getViewport()),
+ "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
Desktop.explodeViews(af);
{
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
}
- af = new FileLoader().LoadFileWaitTillLoaded(
- tfile.getAbsolutePath(), DataSourceType.FILE);
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
+ DataSourceType.FILE);
Assert.assertNotNull(af);
Assert.assertEquals(
Desktop.getAlignFrames().length,
Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length);
Assert.assertEquals(
- oldviews,
- Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length);
+ Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length,
+ oldviews);
}
/**
Desktop.instance.closeAll_actionPerformed(null);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", DataSourceType.FILE);
- assertNotNull("Didn't read in the example file correctly.", af);
+ assertNotNull(af, "Didn't read in the example file correctly.");
String afid = af.getViewport().getSequenceSetId();
// remember reference sequence for each panel
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
}
- af = new FileLoader().LoadFileWaitTillLoaded(
- tfile.getAbsolutePath(), DataSourceType.FILE);
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
+ DataSourceType.FILE);
afid = af.getViewport().getSequenceSetId();
for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
Desktop.instance.closeAll_actionPerformed(null);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
- assertNotNull("Didn't read in the example file correctly.", af);
+ assertNotNull(af, "Didn't read in the example file correctly.");
String afid = af.getViewport().getSequenceSetId();
// make a second view of the alignment
af.newView_actionPerformed(null);
assertSame(repSeq, sg.getSeqrep());
assertTrue(sg.getSequences().contains(repSeq));
assertTrue(sg.getSequences().contains(precedingSeq));
- assertTrue("alignment has groups", alignment.getGroups().isEmpty());
+ assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
.getHiddenRepSequences();
assertNotNull(hiddenRepSeqsMap);
{
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
}
-
- af = new FileLoader().LoadFileWaitTillLoaded(
- tfile.getAbsolutePath(), DataSourceType.FILE);
+
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
+ DataSourceType.FILE);
afid = af.getViewport().getSequenceSetId();
for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
AlignmentI alignment = ap.getAlignment();
List<SequenceGroup> groups = alignment.getGroups();
assertNotNull(groups);
- assertTrue("Alignment has groups", groups.isEmpty());
+ assertTrue(groups.isEmpty(), "Alignment has groups");
Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
.getHiddenRepSequences();
- assertNotNull("No hidden represented sequences", hiddenRepSeqsMap);
+ assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
assertEquals(1, hiddenRepSeqsMap.size());
assertEquals(repSeqs.get(viewName).getDisplayId(true),
hiddenRepSeqsMap.keySet().iterator().next()
List<String> hidden = hiddenSeqNames.get(ap.getViewName());
HiddenSequences hs = alignment.getHiddenSequences();
assertEquals(
+ hidden.size(),
+ hs.getSize(),
"wrong number of restored hidden sequences in "
- + ap.getViewName(), hidden.size(), hs.getSize());
+ + ap.getViewName());
}
}
String exampleFile = "examples/3W5V.pdb";
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
DataSourceType.FILE);
- assertNotNull("Didn't read in the example file correctly.", af);
+ assertNotNull(af, "Didn't read in the example file correctly.");
String afid = af.getViewport().getSequenceSetId();
AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
"Recovered PDBEntry should have a non-null file entry");
}
}
+
+ /**
+ * Configure an alignment and a sub-group each with distinct colour schemes,
+ * Conservation and PID thresholds, and confirm these are restored from the
+ * saved project.
+ *
+ * @throws IOException
+ */
+ @Test(groups = { "Functional" })
+ public void testStoreAndRecoverColourThresholds() throws IOException
+ {
+ Desktop.instance.closeAll_actionPerformed(null);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+
+ AlignViewport av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+
+ /*
+ * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
+ */
+ af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
+ assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
+ af.abovePIDThreshold_actionPerformed(true);
+ SliderPanel sp = SliderPanel.getSliderPanel();
+ assertFalse(sp.isForConservation());
+ sp.valueChanged(10);
+ af.conservationMenuItem_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertTrue(sp.isForConservation());
+ sp.valueChanged(20);
+ ResidueShaderI rs = av.getResidueShading();
+ assertEquals(rs.getThreshold(), 10);
+ assertTrue(rs.conservationApplied());
+ assertEquals(rs.getConservationInc(), 20);
+
+ /*
+ * create a group with Strand colouring, 30% Conservation
+ * and 40% PID threshold
+ */
+ SequenceGroup sg = new SequenceGroup();
+ sg.addSequence(al.getSequenceAt(0), false);
+ sg.setStartRes(15);
+ sg.setEndRes(25);
+ av.setSelectionGroup(sg);
+ PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
+ popupMenu.changeColour_actionPerformed(JalviewColourScheme.Strand
+ .toString());
+ assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
+ assertEquals(al.getGroups().size(), 1);
+ assertSame(al.getGroups().get(0), sg);
+ popupMenu.conservationMenuItem_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertTrue(sp.isForConservation());
+ sp.valueChanged(30);
+ popupMenu.abovePIDColour_actionPerformed(true);
+ sp = SliderPanel.getSliderPanel();
+ assertFalse(sp.isForConservation());
+ sp.valueChanged(40);
+ assertTrue(sg.getGroupColourScheme().conservationApplied());
+ assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
+ assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
+
+ /*
+ * save project, close windows, reload project, verify
+ */
+ File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
+ ".jvp");
+ tfile.deleteOnExit();
+ new Jalview2XML(false).saveState(tfile);
+ Desktop.instance.closeAll_actionPerformed(null);
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
+ DataSourceType.FILE);
+ Assert.assertNotNull(af, "Failed to reload project");
+
+ /*
+ * verify alignment (background) colouring
+ */
+ rs = af.getViewport().getResidueShading();
+ assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
+ assertEquals(rs.getThreshold(), 10);
+ assertTrue(rs.conservationApplied());
+ assertEquals(rs.getConservationInc(), 20);
+
+ /*
+ * verify group colouring
+ */
+ assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
+ rs = af.getViewport().getAlignment().getGroups().get(0)
+ .getGroupColourScheme();
+ assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
+ assertEquals(rs.getThreshold(), 40);
+ assertTrue(rs.conservationApplied());
+ assertEquals(rs.getConservationInc(), 30);
+ }
}
public class JalviewFileViewTest
{
- @Test
+ @Test(groups = "Functional")
public void testGetImageIcon()
{
JalviewFileView jfv = new JalviewFileView();
assertNull(jfv.getImageIcon("images/file.png"));
}
- @Test
+ @Test(groups = "Functional")
public void testGetExtension()
{
assertEquals(JalviewFileView.getExtension(new File("text.txt")), "txt");
"/a/longer/file/path/text")));
}
- @Test
+ @Test(groups = "Functional")
public void testGetTypeDescription()
{
JalviewFileView jfw = new JalviewFileView();
--- /dev/null
+package jalview.math;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.util.Arrays;
+import java.util.Random;
+
+import org.testng.annotations.Test;
+import org.testng.internal.junit.ArrayAsserts;
+
+public class MatrixTest
+{
+ final static double DELTA = 0.0001d;
+
+ @Test(groups = "Timing")
+ public void testPreMultiply_timing()
+ {
+ int rows = 500;
+ int cols = 1000;
+ double[][] d1 = new double[rows][cols];
+ double[][] d2 = new double[cols][rows];
+ Matrix m1 = new Matrix(d1);
+ Matrix m2 = new Matrix(d2);
+ long start = System.currentTimeMillis();
+ m1.preMultiply(m2);
+ long elapsed = System.currentTimeMillis() - start;
+ System.out.println(rows + "x" + cols
+ + " multiplications of double took " + elapsed + "ms");
+ }
+
+ @Test(groups = "Functional")
+ public void testPreMultiply()
+ {
+ Matrix m1 = new Matrix(new double[][] { { 2, 3, 4 } }); // 1x3
+ Matrix m2 = new Matrix(new double[][] { { 5 }, { 6 }, { 7 } }); // 3x1
+
+ /*
+ * 1x3 times 3x1 is 1x1
+ * 2x5 + 3x6 + 4*7 = 56
+ */
+ MatrixI m3 = m2.preMultiply(m1);
+ assertEquals(m3.height(), 1);
+ assertEquals(m3.width(), 1);
+ assertEquals(m3.getValue(0, 0), 56d);
+
+ /*
+ * 3x1 times 1x3 is 3x3
+ */
+ m3 = m1.preMultiply(m2);
+ assertEquals(m3.height(), 3);
+ assertEquals(m3.width(), 3);
+ assertEquals(Arrays.toString(m3.getRow(0)), "[10.0, 15.0, 20.0]");
+ assertEquals(Arrays.toString(m3.getRow(1)), "[12.0, 18.0, 24.0]");
+ assertEquals(Arrays.toString(m3.getRow(2)), "[14.0, 21.0, 28.0]");
+ }
+
+ @Test(
+ groups = "Functional",
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testPreMultiply_tooManyColumns()
+ {
+ Matrix m1 = new Matrix(new double[][] { { 2, 3, 4 }, { 3, 4, 5 } }); // 2x3
+
+ /*
+ * 2x3 times 2x3 invalid operation -
+ * multiplier has more columns than multiplicand has rows
+ */
+ m1.preMultiply(m1);
+ fail("Expected exception");
+ }
+
+ @Test(
+ groups = "Functional",
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testPreMultiply_tooFewColumns()
+ {
+ Matrix m1 = new Matrix(new double[][] { { 2, 3, 4 }, { 3, 4, 5 } }); // 2x3
+
+ /*
+ * 3x2 times 3x2 invalid operation -
+ * multiplier has more columns than multiplicand has row
+ */
+ m1.preMultiply(m1);
+ fail("Expected exception");
+ }
+
+
+ private boolean matrixEquals(Matrix m1, Matrix m2) {
+ if (m1.width() != m2.width() || m1.height() != m2.height())
+ {
+ return false;
+ }
+ for (int i = 0; i < m1.height(); i++)
+ {
+ if (!Arrays.equals(m1.getRow(i), m2.getRow(i)))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Test(groups = "Functional")
+ public void testPostMultiply()
+ {
+ /*
+ * Square matrices
+ * (2 3) . (10 100)
+ * (4 5) (1000 10000)
+ * =
+ * (3020 30200)
+ * (5040 50400)
+ */
+ MatrixI m1 = new Matrix(new double[][] { { 2, 3 }, { 4, 5 } });
+ MatrixI m2 = new Matrix(new double[][] { { 10, 100 }, { 1000, 10000 } });
+ MatrixI m3 = m1.postMultiply(m2);
+ assertEquals(Arrays.toString(m3.getRow(0)), "[3020.0, 30200.0]");
+ assertEquals(Arrays.toString(m3.getRow(1)), "[5040.0, 50400.0]");
+
+ /*
+ * also check m2.preMultiply(m1) - should be same as m1.postMultiply(m2)
+ */
+ m3 = m2.preMultiply(m1);
+ assertEquals(Arrays.toString(m3.getRow(0)), "[3020.0, 30200.0]");
+ assertEquals(Arrays.toString(m3.getRow(1)), "[5040.0, 50400.0]");
+
+ /*
+ * m1 has more rows than columns
+ * (2).(10 100 1000) = (20 200 2000)
+ * (3) (30 300 3000)
+ */
+ m1 = new Matrix(new double[][] { { 2 }, { 3 } });
+ m2 = new Matrix(new double[][] { { 10, 100, 1000 } });
+ m3 = m1.postMultiply(m2);
+ assertEquals(m3.height(), 2);
+ assertEquals(m3.width(), 3);
+ assertEquals(Arrays.toString(m3.getRow(0)), "[20.0, 200.0, 2000.0]");
+ assertEquals(Arrays.toString(m3.getRow(1)), "[30.0, 300.0, 3000.0]");
+ m3 = m2.preMultiply(m1);
+ assertEquals(m3.height(), 2);
+ assertEquals(m3.width(), 3);
+ assertEquals(Arrays.toString(m3.getRow(0)), "[20.0, 200.0, 2000.0]");
+ assertEquals(Arrays.toString(m3.getRow(1)), "[30.0, 300.0, 3000.0]");
+
+ /*
+ * m1 has more columns than rows
+ * (2 3 4) . (5 4) = (56 25)
+ * (6 3)
+ * (7 2)
+ * [0, 0] = 2*5 + 3*6 + 4*7 = 56
+ * [0, 1] = 2*4 + 3*3 + 4*2 = 25
+ */
+ m1 = new Matrix(new double[][] { { 2, 3, 4 } });
+ m2 = new Matrix(new double[][] { { 5, 4 }, { 6, 3 }, { 7, 2 } });
+ m3 = m1.postMultiply(m2);
+ assertEquals(m3.height(), 1);
+ assertEquals(m3.width(), 2);
+ assertEquals(m3.getRow(0)[0], 56d);
+ assertEquals(m3.getRow(0)[1], 25d);
+
+ /*
+ * and check premultiply equivalent
+ */
+ m3 = m2.preMultiply(m1);
+ assertEquals(m3.height(), 1);
+ assertEquals(m3.width(), 2);
+ assertEquals(m3.getRow(0)[0], 56d);
+ assertEquals(m3.getRow(0)[1], 25d);
+ }
+
+ @Test(groups = "Functional")
+ public void testCopy()
+ {
+ Random r = new Random();
+ int rows = 5;
+ int cols = 11;
+ double[][] in = new double[rows][cols];
+
+ for (int i = 0; i < rows; i++)
+ {
+ for (int j = 0; j < cols; j++)
+ {
+ in[i][j] = r.nextDouble();
+ }
+ }
+ Matrix m1 = new Matrix(in);
+ Matrix m2 = (Matrix) m1.copy();
+ assertTrue(matrixEquals(m1, m2));
+ }
+
+ /**
+ * main method extracted from Matrix
+ *
+ * @param args
+ */
+ public static void main(String[] args) throws Exception
+ {
+ int n = Integer.parseInt(args[0]);
+ double[][] in = new double[n][n];
+
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ in[i][j] = Math.random();
+ }
+ }
+
+ Matrix origmat = new Matrix(in);
+
+ // System.out.println(" --- Original matrix ---- ");
+ // / origmat.print(System.out);
+ // System.out.println();
+ // System.out.println(" --- transpose matrix ---- ");
+ MatrixI trans = origmat.transpose();
+
+ // trans.print(System.out);
+ // System.out.println();
+ // System.out.println(" --- OrigT * Orig ---- ");
+ MatrixI symm = trans.postMultiply(origmat);
+
+ // symm.print(System.out);
+ // System.out.println();
+ // Copy the symmetric matrix for later
+ // Matrix origsymm = symm.copy();
+
+ // This produces the tridiagonal transformation matrix
+ // long tstart = System.currentTimeMillis();
+ symm.tred();
+
+ // long tend = System.currentTimeMillis();
+
+ // System.out.println("Time take for tred = " + (tend-tstart) + "ms");
+ // System.out.println(" ---Tridiag transform matrix ---");
+ // symm.print(System.out);
+ // System.out.println();
+ // System.out.println(" --- D vector ---");
+ // symm.printD(System.out);
+ // System.out.println();
+ // System.out.println(" --- E vector ---");
+ // symm.printE(System.out);
+ // System.out.println();
+ // Now produce the diagonalization matrix
+ // tstart = System.currentTimeMillis();
+ symm.tqli();
+ // tend = System.currentTimeMillis();
+
+ // System.out.println("Time take for tqli = " + (tend-tstart) + " ms");
+ // System.out.println(" --- New diagonalization matrix ---");
+ // symm.print(System.out);
+ // System.out.println();
+ // System.out.println(" --- D vector ---");
+ // symm.printD(System.out);
+ // System.out.println();
+ // System.out.println(" --- E vector ---");
+ // symm.printE(System.out);
+ // System.out.println();
+ // System.out.println(" --- First eigenvector --- ");
+ // double[] eigenv = symm.getColumn(0);
+ // for (int i=0; i < eigenv.length;i++) {
+ // Format.print(System.out,"%15.4f",eigenv[i]);
+ // }
+ // System.out.println();
+ // double[] neigenv = origsymm.vectorPostMultiply(eigenv);
+ // for (int i=0; i < neigenv.length;i++) {
+ // Format.print(System.out,"%15.4f",neigenv[i]/symm.d[0]);
+ // }
+ // System.out.println();
+ }
+
+ @Test(groups = "Timing")
+ public void testSign()
+ {
+ assertEquals(Matrix.sign(-1, -2), -1d);
+ assertEquals(Matrix.sign(-1, 2), 1d);
+ assertEquals(Matrix.sign(-1, 0), 1d);
+ assertEquals(Matrix.sign(1, -2), -1d);
+ assertEquals(Matrix.sign(1, 2), 1d);
+ assertEquals(Matrix.sign(1, 0), 1d);
+ }
+
+ /**
+ * Helper method to make values for a sparse, pseudo-random symmetric matrix
+ *
+ * @param rows
+ * @param cols
+ * @param occupancy
+ * one in 'occupancy' entries will be non-zero
+ * @return
+ */
+ public double[][] getSparseValues(int rows, int cols, int occupancy)
+ {
+ Random r = new Random(1729);
+
+ /*
+ * generate whole number values between -12 and +12
+ * (to mimic score matrices used in Jalview)
+ */
+ double[][] d = new double[rows][cols];
+ int m = 0;
+ for (int i = 0; i < rows; i++)
+ {
+ if (++m % occupancy == 0)
+ {
+ d[i][i] = r.nextInt() % 13; // diagonal
+ }
+ for (int j = 0; j < i; j++)
+ {
+ if (++m % occupancy == 0)
+ {
+ d[i][j] = r.nextInt() % 13;
+ d[j][i] = d[i][j];
+ }
+ }
+ }
+ return d;
+
+ }
+
+ /**
+ * Verify that the results of method tred() are the same if the calculation is
+ * redone
+ */
+ @Test(groups = "Functional")
+ public void testTred_reproducible()
+ {
+ /*
+ * make a pseudo-random symmetric matrix as required for tred/tqli
+ */
+ int rows = 10;
+ int cols = rows;
+ double[][] d = getSparseValues(rows, cols, 3);
+
+ /*
+ * make a copy of the values so m1, m2 are not
+ * sharing arrays!
+ */
+ double[][] d1 = new double[rows][cols];
+ for (int row = 0; row < rows; row++)
+ {
+ for (int col = 0; col < cols; col++)
+ {
+ d1[row][col] = d[row][col];
+ }
+ }
+ Matrix m1 = new Matrix(d);
+ Matrix m2 = new Matrix(d1);
+ assertMatricesMatch(m1, m2); // sanity check
+ m1.tred();
+ m2.tred();
+ assertMatricesMatch(m1, m2);
+ }
+
+ private void assertMatricesMatch(MatrixI m1, MatrixI m2)
+ {
+ if (m1.height() != m2.height())
+ {
+ fail("height mismatch");
+ }
+ if (m1.width() != m2.width())
+ {
+ fail("width mismatch");
+ }
+ for (int row = 0; row < m1.height(); row++)
+ {
+ for (int col = 0; col < m1.width(); col++)
+ {
+ double v2 = m2.getValue(row, col);
+ double v1 = m1.getValue(row, col);
+ if (Math.abs(v1 - v2) > DELTA)
+ {
+ fail(String.format("At [%d, %d] %f != %f", row, col, v1, v2));
+ }
+ }
+ }
+ ArrayAsserts.assertArrayEquals(m1.getD(), m2.getD(), 0.00001d);
+ ArrayAsserts.assertArrayEquals(m1.getE(), m2.getE(), 0.00001d);
+ }
+}
--- /dev/null
+package jalview.math;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.util.Random;
+
+import org.testng.annotations.Test;
+import org.testng.internal.junit.ArrayAsserts;
+
+public class SparseMatrixTest
+{
+ final static double DELTA = 0.0001d;
+
+ Random r = new Random(1729);
+
+ @Test(groups = "Functional")
+ public void testConstructor()
+ {
+ MatrixI m1 = new SparseMatrix(
+ new double[][] { { 2, 0, 4 }, { 0, 6, 0 } });
+ assertEquals(m1.getValue(0, 0), 2d);
+ assertEquals(m1.getValue(0, 1), 0d);
+ assertEquals(m1.getValue(0, 2), 4d);
+ assertEquals(m1.getValue(1, 0), 0d);
+ assertEquals(m1.getValue(1, 1), 6d);
+ assertEquals(m1.getValue(1, 2), 0d);
+ }
+
+ @Test(groups = "Functional")
+ public void testTranspose()
+ {
+ MatrixI m1 = new SparseMatrix(
+ new double[][] { { 2, 0, 4 }, { 5, 6, 0 } });
+ MatrixI m2 = m1.transpose();
+ assertTrue(m2 instanceof SparseMatrix);
+ assertEquals(m2.height(), 3);
+ assertEquals(m2.width(), 2);
+ assertEquals(m2.getValue(0, 0), 2d);
+ assertEquals(m2.getValue(0, 1), 5d);
+ assertEquals(m2.getValue(1, 0), 0d);
+ assertEquals(m2.getValue(1, 1), 6d);
+ assertEquals(m2.getValue(2, 0), 4d);
+ assertEquals(m2.getValue(2, 1), 0d);
+ }
+ @Test(groups = "Functional")
+ public void testPreMultiply()
+ {
+ MatrixI m1 = new SparseMatrix(new double[][] { { 2, 3, 4 } }); // 1x3
+ MatrixI m2 = new SparseMatrix(new double[][] { { 5 }, { 6 }, { 7 } }); // 3x1
+
+ /*
+ * 1x3 times 3x1 is 1x1
+ * 2x5 + 3x6 + 4*7 = 56
+ */
+ MatrixI m3 = m2.preMultiply(m1);
+ assertFalse(m3 instanceof SparseMatrix);
+ assertEquals(m3.height(), 1);
+ assertEquals(m3.width(), 1);
+ assertEquals(m3.getValue(0, 0), 56d);
+
+ /*
+ * 3x1 times 1x3 is 3x3
+ */
+ m3 = m1.preMultiply(m2);
+ assertEquals(m3.height(), 3);
+ assertEquals(m3.width(), 3);
+ assertEquals(m3.getValue(0, 0), 10d);
+ assertEquals(m3.getValue(0, 1), 15d);
+ assertEquals(m3.getValue(0, 2), 20d);
+ assertEquals(m3.getValue(1, 0), 12d);
+ assertEquals(m3.getValue(1, 1), 18d);
+ assertEquals(m3.getValue(1, 2), 24d);
+ assertEquals(m3.getValue(2, 0), 14d);
+ assertEquals(m3.getValue(2, 1), 21d);
+ assertEquals(m3.getValue(2, 2), 28d);
+ }
+
+ @Test(
+ groups = "Functional",
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testPreMultiply_tooManyColumns()
+ {
+ Matrix m1 = new SparseMatrix(
+ new double[][] { { 2, 3, 4 }, { 3, 4, 5 } }); // 2x3
+
+ /*
+ * 2x3 times 2x3 invalid operation -
+ * multiplier has more columns than multiplicand has rows
+ */
+ m1.preMultiply(m1);
+ fail("Expected exception");
+ }
+
+ @Test(
+ groups = "Functional",
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testPreMultiply_tooFewColumns()
+ {
+ Matrix m1 = new SparseMatrix(
+ new double[][] { { 2, 3, 4 }, { 3, 4, 5 } }); // 2x3
+
+ /*
+ * 3x2 times 3x2 invalid operation -
+ * multiplier has more columns than multiplicand has row
+ */
+ m1.preMultiply(m1);
+ fail("Expected exception");
+ }
+
+ @Test(groups = "Functional")
+ public void testPostMultiply()
+ {
+ /*
+ * Square matrices
+ * (2 3) . (10 100)
+ * (4 5) (1000 10000)
+ * =
+ * (3020 30200)
+ * (5040 50400)
+ */
+ MatrixI m1 = new SparseMatrix(new double[][] { { 2, 3 }, { 4, 5 } });
+ MatrixI m2 = new SparseMatrix(new double[][] { { 10, 100 },
+ { 1000, 10000 } });
+ MatrixI m3 = m1.postMultiply(m2);
+ assertEquals(m3.getValue(0, 0), 3020d);
+ assertEquals(m3.getValue(0, 1), 30200d);
+ assertEquals(m3.getValue(1, 0), 5040d);
+ assertEquals(m3.getValue(1, 1), 50400d);
+
+ /*
+ * also check m2.preMultiply(m1) - should be same as m1.postMultiply(m2)
+ */
+ MatrixI m4 = m2.preMultiply(m1);
+ assertMatricesMatch(m3, m4, 0.00001d);
+
+ /*
+ * m1 has more rows than columns
+ * (2).(10 100 1000) = (20 200 2000)
+ * (3) (30 300 3000)
+ */
+ m1 = new SparseMatrix(new double[][] { { 2 }, { 3 } });
+ m2 = new SparseMatrix(new double[][] { { 10, 100, 1000 } });
+ m3 = m1.postMultiply(m2);
+ assertEquals(m3.height(), 2);
+ assertEquals(m3.width(), 3);
+ assertEquals(m3.getValue(0, 0), 20d);
+ assertEquals(m3.getValue(0, 1), 200d);
+ assertEquals(m3.getValue(0, 2), 2000d);
+ assertEquals(m3.getValue(1, 0), 30d);
+ assertEquals(m3.getValue(1, 1), 300d);
+ assertEquals(m3.getValue(1, 2), 3000d);
+
+ m4 = m2.preMultiply(m1);
+ assertMatricesMatch(m3, m4, 0.00001d);
+
+ /*
+ * m1 has more columns than rows
+ * (2 3 4) . (5 4) = (56 25)
+ * (6 3)
+ * (7 2)
+ * [0, 0] = 2*5 + 3*6 + 4*7 = 56
+ * [0, 1] = 2*4 + 3*3 + 4*2 = 25
+ */
+ m1 = new SparseMatrix(new double[][] { { 2, 3, 4 } });
+ m2 = new SparseMatrix(new double[][] { { 5, 4 }, { 6, 3 }, { 7, 2 } });
+ m3 = m1.postMultiply(m2);
+ assertEquals(m3.height(), 1);
+ assertEquals(m3.width(), 2);
+ assertEquals(m3.getValue(0, 0), 56d);
+ assertEquals(m3.getValue(0, 1), 25d);
+
+ /*
+ * and check premultiply equivalent
+ */
+ m4 = m2.preMultiply(m1);
+ assertMatricesMatch(m3, m4, 0.00001d);
+ }
+
+ @Test(groups = "Timing")
+ public void testSign()
+ {
+ assertEquals(Matrix.sign(-1, -2), -1d);
+ assertEquals(Matrix.sign(-1, 2), 1d);
+ assertEquals(Matrix.sign(-1, 0), 1d);
+ assertEquals(Matrix.sign(1, -2), -1d);
+ assertEquals(Matrix.sign(1, 2), 1d);
+ assertEquals(Matrix.sign(1, 0), 1d);
+ }
+
+ /**
+ * Verify that the results of method tred() are the same for SparseMatrix as
+ * they are for Matrix (i.e. a regression test rather than an absolute test of
+ * correctness of results)
+ */
+ @Test(groups = "Functional")
+ public void testTred_matchesMatrix()
+ {
+ /*
+ * make a pseudo-random symmetric matrix as required for tred/tqli
+ */
+ int rows = 10;
+ int cols = rows;
+ double[][] d = getSparseValues(rows, cols, 3);
+
+ /*
+ * make a copy of the values so m1, m2 are not
+ * sharing arrays!
+ */
+ double[][] d1 = new double[rows][cols];
+ for (int row = 0; row < rows; row++)
+ {
+ for (int col = 0; col < cols; col++)
+ {
+ d1[row][col] = d[row][col];
+ }
+ }
+ Matrix m1 = new Matrix(d);
+ Matrix m2 = new SparseMatrix(d1);
+ assertMatricesMatch(m1, m2, 0.00001d); // sanity check
+ m1.tred();
+ m2.tred();
+ assertMatricesMatch(m1, m2, 0.00001d);
+ }
+
+ private void assertMatricesMatch(MatrixI m1, MatrixI m2, double delta)
+ {
+ if (m1.height() != m2.height())
+ {
+ fail("height mismatch");
+ }
+ if (m1.width() != m2.width())
+ {
+ fail("width mismatch");
+ }
+ for (int row = 0; row < m1.height(); row++)
+ {
+ for (int col = 0; col < m1.width(); col++)
+ {
+ double v2 = m2.getValue(row, col);
+ double v1 = m1.getValue(row, col);
+ if (Math.abs(v1 - v2) > DELTA)
+ {
+ fail(String.format("At [%d, %d] %f != %f", row, col, v1, v2));
+ }
+ }
+ }
+ ArrayAsserts.assertArrayEquals(m1.getD(), m2.getD(), delta);
+ ArrayAsserts.assertArrayEquals(m1.getE(), m2.getE(), 0.00001d);
+ }
+
+ @Test
+ public void testGetValue()
+ {
+ double[][] d = new double[][] { { 0, 0, 1, 0, 0 }, { 2, 3, 0, 0, 0 },
+ { 4, 0, 0, 0, 5 } };
+ MatrixI m = new SparseMatrix(d);
+ for (int row = 0; row < 3; row++)
+ {
+ for (int col = 0; col < 5; col++)
+ {
+ assertEquals(m.getValue(row, col), d[row][col],
+ String.format("At [%d, %d]", row, col));
+ }
+ }
+ }
+
+ /**
+ * Verify that the results of method tqli() are the same for SparseMatrix as
+ * they are for Matrix (i.e. a regression test rather than an absolute test of
+ * correctness of results)
+ *
+ * @throws Exception
+ */
+ @Test(groups = "Functional")
+ public void testTqli_matchesMatrix() throws Exception
+ {
+ /*
+ * make a pseudo-random symmetric matrix as required for tred
+ */
+ int rows = 6;
+ int cols = rows;
+ double[][] d = getSparseValues(rows, cols, 3);
+
+ /*
+ * make a copy of the values so m1, m2 are not
+ * sharing arrays!
+ */
+ double[][] d1 = new double[rows][cols];
+ for (int row = 0; row < rows; row++)
+ {
+ for (int col = 0; col < cols; col++)
+ {
+ d1[row][col] = d[row][col];
+ }
+ }
+ Matrix m1 = new Matrix(d);
+ Matrix m2 = new SparseMatrix(d1);
+
+ // have to do tred() before doing tqli()
+ m1.tred();
+ m2.tred();
+ assertMatricesMatch(m1, m2, 0.00001d);
+
+ m1.tqli();
+ m2.tqli();
+ assertMatricesMatch(m1, m2, 0.00001d);
+ }
+
+ /**
+ * Helper method to make values for a sparse, pseudo-random symmetric matrix
+ *
+ * @param rows
+ * @param cols
+ * @param occupancy
+ * one in 'occupancy' entries will be non-zero
+ * @return
+ */
+ public double[][] getSparseValues(int rows, int cols, int occupancy)
+ {
+ /*
+ * generate whole number values between -12 and +12
+ * (to mimic score matrices used in Jalview)
+ */
+ double[][] d = new double[rows][cols];
+ int m = 0;
+ for (int i = 0; i < rows; i++)
+ {
+ if (++m % occupancy == 0)
+ {
+ d[i][i] = r.nextInt() % 13; // diagonal
+ }
+ for (int j = 0; j < i; j++)
+ {
+ if (++m % occupancy == 0)
+ {
+ d[i][j] = r.nextInt() % 13;
+ d[j][i] = d[i][j];
+ }
+ }
+ }
+ return d;
+
+ }
+
+ /**
+ * Test that verifies that the result of preMultiply is a SparseMatrix if more
+ * than 80% zeroes, else a Matrix
+ */
+ @Test(groups = "Functional")
+ public void testPreMultiply_sparseProduct()
+ {
+ MatrixI m1 = new SparseMatrix(new double[][] { { 1 }, { 0 }, { 0 },
+ { 0 }, { 0 } }); // 5x1
+ MatrixI m2 = new SparseMatrix(new double[][] { { 1, 1, 1, 1 } }); // 1x4
+
+ /*
+ * m1.m2 makes a row of 4 1's, and 4 rows of zeros
+ * 20% non-zero so not 'sparse'
+ */
+ MatrixI m3 = m2.preMultiply(m1);
+ assertFalse(m3 instanceof SparseMatrix);
+
+ /*
+ * replace a 1 with a 0 in the product:
+ * it is now > 80% zero so 'sparse'
+ */
+ m2 = new SparseMatrix(new double[][] { { 1, 1, 1, 0 } });
+ m3 = m2.preMultiply(m1);
+ assertTrue(m3 instanceof SparseMatrix);
+ }
+
+ @Test(groups = "Functional")
+ public void testFillRatio()
+ {
+ SparseMatrix m1 = new SparseMatrix(new double[][] { { 2, 0, 4, 1, 0 },
+ { 0, 6, 0, 0, 0 } });
+ assertEquals(m1.getFillRatio(), 0.4f);
+ }
+
+ /**
+ * Verify that the results of method tred() are the same if the calculation is
+ * redone
+ */
+ @Test(groups = "Functional")
+ public void testTred_reproducible()
+ {
+ /*
+ * make a pseudo-random symmetric matrix as required for tred/tqli
+ */
+ int rows = 10;
+ int cols = rows;
+ double[][] d = getSparseValues(rows, cols, 3);
+
+ /*
+ * make a copy of the values so m1, m2 are not
+ * sharing arrays!
+ */
+ double[][] d1 = new double[rows][cols];
+ for (int row = 0; row < rows; row++)
+ {
+ for (int col = 0; col < cols; col++)
+ {
+ d1[row][col] = d[row][col];
+ }
+ }
+ Matrix m1 = new SparseMatrix(d);
+ Matrix m2 = new SparseMatrix(d1);
+ assertMatricesMatch(m1, m2, 1.0e16); // sanity check
+ m1.tred();
+ m2.tred();
+ assertMatricesMatch(m1, m2, 0.00001d);
+ }
+}
\ No newline at end of file
--- /dev/null
+package jalview.renderer;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.analysis.Conservation;
+import jalview.datamodel.Profile;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.Profiles;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.schemes.PIDColourScheme;
+
+import java.awt.Color;
+import java.util.Collections;
+
+import org.testng.annotations.Test;
+
+public class ResidueShaderTest
+{
+
+ @Test(groups = "Functional")
+ public void testAboveThreshold()
+ {
+ /*
+ * make up profiles for this alignment:
+ * AR-Q
+ * AR--
+ * SR-T
+ * SR-T
+ */
+ ProfileI[] profiles = new ProfileI[4];
+ profiles[0] = new Profile(4, 0, 2, "AS");
+ profiles[1] = new Profile(4, 0, 4, "R");
+ profiles[2] = new Profile(4, 4, 0, "");
+ profiles[3] = new Profile(4, 1, 2, "T");
+ ResidueShader ccs = new ResidueShader(new PIDColourScheme());
+ ccs.setConsensus(new Profiles(profiles));
+
+ /*
+ * no threshold
+ */
+ ccs.setThreshold(0, true);
+ assertTrue(ccs.aboveThreshold('a', 0));
+ assertTrue(ccs.aboveThreshold('S', 0));
+ assertTrue(ccs.aboveThreshold('W', 0));
+ assertTrue(ccs.aboveThreshold('R', 1));
+ assertTrue(ccs.aboveThreshold('W', 2));
+ assertTrue(ccs.aboveThreshold('t', 3));
+ assertTrue(ccs.aboveThreshold('Q', 3));
+
+ /*
+ * with threshold, include gaps
+ */
+ ccs.setThreshold(60, false);
+ assertFalse(ccs.aboveThreshold('a', 0));
+ assertFalse(ccs.aboveThreshold('S', 0));
+ assertTrue(ccs.aboveThreshold('R', 1));
+ assertFalse(ccs.aboveThreshold('W', 2));
+ assertFalse(ccs.aboveThreshold('t', 3)); // 50% < 60%
+
+ /*
+ * with threshold, ignore gaps
+ */
+ ccs.setThreshold(60, true);
+ assertFalse(ccs.aboveThreshold('a', 0));
+ assertFalse(ccs.aboveThreshold('S', 0));
+ assertTrue(ccs.aboveThreshold('R', 1));
+ assertFalse(ccs.aboveThreshold('W', 2));
+ assertTrue(ccs.aboveThreshold('t', 3)); // 67% > 60%
+ }
+
+ /**
+ * Test colour bleaching based on conservation score and conservation slider.
+ * Scores of 10 or 11 should leave colours unchanged. Gap is always white.
+ */
+ @Test(groups = "Functional")
+ public void testApplyConservation()
+ {
+ ResidueShader ccs = new ResidueShader(new PIDColourScheme());
+
+ // no conservation present - no fading
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 12));
+
+ /*
+ * stub Conservation to return a given consensus string
+ */
+ final String consSequence = "0123456789+*-";
+ Conservation cons = new Conservation(null,
+ Collections.<SequenceI> emptyList(), 0, 0)
+ {
+ @Override
+ public SequenceI getConsSequence()
+ {
+ return new Sequence("seq", consSequence);
+ }
+ };
+ ccs.setConservation(cons);
+
+ // column out of range:
+ assertEquals(Color.RED,
+ ccs.applyConservation(Color.RED, consSequence.length()));
+
+ /*
+ * with 100% threshold, 'fade factor' is
+ * (11-score)/10 * 100/20 = (11-score)/2
+ * which is >= 1 for all scores i.e. all fade to white except +, *
+ */
+ ccs.setConservationInc(100);
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 0));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 1));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 2));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 3));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 4));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 5));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 6));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 7));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 8));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 9));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 10));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 11));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 12));
+
+ /*
+ * with 0% threshold, there should be no fading
+ */
+ ccs.setConservationInc(0);
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 0));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 1));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 2));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 3));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 4));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 5));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 6));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 7));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 8));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 9));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 10));
+ assertEquals(Color.RED, ccs.applyConservation(Color.RED, 11));
+ assertEquals(Color.WHITE, ccs.applyConservation(Color.RED, 12)); // gap
+
+ /*
+ * with 40% threshold, 'fade factor' is
+ * (11-score)/10 * 40/20 = (11-score)/5
+ * which is {>1, >1, >1, >1, >1, >1, 1, 0.8, 0.6, 0.4} for score 0-9
+ * e.g. score 7 colour fades 80% of the way to white (255, 255, 255)
+ */
+ ccs.setConservationInc(40);
+ Color colour = new Color(155, 105, 55);
+ assertEquals(Color.WHITE, ccs.applyConservation(colour, 0));
+ assertEquals(Color.WHITE, ccs.applyConservation(colour, 1));
+ assertEquals(Color.WHITE, ccs.applyConservation(colour, 2));
+ assertEquals(Color.WHITE, ccs.applyConservation(colour, 3));
+ assertEquals(Color.WHITE, ccs.applyConservation(colour, 4));
+ assertEquals(Color.WHITE, ccs.applyConservation(colour, 5));
+ assertEquals(Color.WHITE, ccs.applyConservation(colour, 6));
+ assertEquals(new Color(235, 225, 215), ccs.applyConservation(colour, 7));
+ assertEquals(new Color(215, 195, 175), ccs.applyConservation(colour, 8));
+ assertEquals(new Color(195, 165, 135), ccs.applyConservation(colour, 9));
+ assertEquals(colour, ccs.applyConservation(colour, 10));
+ assertEquals(colour, ccs.applyConservation(colour, 11));
+ assertEquals(Color.WHITE, ccs.applyConservation(colour, 12));
+ }
+
+}
--- /dev/null
+package jalview.renderer;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.renderer.ScaleRenderer.ScaleMark;
+
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+public class ScaleRendererTest
+{
+ @Test(groups = "Functional")
+ public void testCalculateMarks()
+ {
+ String data = ">Seq/20-45\nABCDEFGHIJKLMNOPQRSTUVWXYS\n";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(data,
+ DataSourceType.PASTE);
+ AlignViewport av = af.getViewport();
+
+ /*
+ * scale has minor ticks at 5 and 15, major at 10 and 20
+ * (these are base 1, ScaleMark holds base 0 values)
+ */
+ List<ScaleMark> marks = new ScaleRenderer().calculateMarks(av, 0, 25);
+ assertEquals(marks.size(), 4);
+
+ assertFalse(marks.get(0).major);
+ assertEquals(marks.get(0).column, 4);
+ assertNull(marks.get(0).text);
+
+ assertTrue(marks.get(1).major);
+ assertEquals(marks.get(1).column, 9);
+ assertEquals(marks.get(1).text, "10");
+
+ assertFalse(marks.get(2).major);
+ assertEquals(marks.get(2).column, 14);
+ assertNull(marks.get(2).text);
+
+ assertTrue(marks.get(3).major);
+ assertEquals(marks.get(3).column, 19);
+ assertEquals(marks.get(3).text, "20");
+
+ /*
+ * now hide columns 9-11 and 18-20 (base 1)
+ * scale marks are now in the same columns as before, but
+ * with column numbering adjusted for hidden columns
+ */
+ av.hideColumns(8, 10);
+ av.hideColumns(17, 19);
+ marks = new ScaleRenderer().calculateMarks(av, 0, 25);
+ assertEquals(marks.size(), 4);
+ assertFalse(marks.get(0).major);
+ assertEquals(marks.get(0).column, 4);
+ assertNull(marks.get(0).text);
+ assertTrue(marks.get(1).major);
+ assertEquals(marks.get(1).column, 9);
+ assertEquals(marks.get(1).text, "13"); // +3 hidden columns
+ assertFalse(marks.get(2).major);
+ assertEquals(marks.get(2).column, 14);
+ assertNull(marks.get(2).text);
+ assertTrue(marks.get(3).major);
+ assertEquals(marks.get(3).column, 19);
+ assertEquals(marks.get(3).text, "26"); // +6 hidden columns
+ }
+}
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.Assert.assertEquals;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+
+public class Blosum62ColourSchemeTest
+{
+ /**
+ * Test the method that determines colour as:
+ * <ul>
+ * <li>white if there is no consensus</li>
+ * <li>white if 'residue' is a gap</li>
+ * <li>dark blue if residue matches consensus (or joint consensus)</li>
+ * <li>else, total the residue's Blosum score with the consensus residue(s)</li>
+ * <ul>
+ * <li>if positive, light blue, else white</li>
+ * </ul>
+ * <ul>
+ */
+ @Test
+ public void testFindColour()
+ {
+ ColourSchemeI blosum = new Blosum62ColourScheme();
+ Color lightBlue = new Color(204, 204, 255);
+ Color darkBlue = new Color(154, 154, 255);
+
+ /*
+ * findColour does not use column, sequence or pid score
+ * we assume consensus residue is computed as upper case
+ */
+ assertEquals(blosum.findColour('A', 0, null, "A", 0f), darkBlue);
+ assertEquals(blosum.findColour('a', 0, null, "A", 0f), darkBlue);
+
+ /*
+ * L has a Blosum score of
+ * -1 with A
+ * -4 with B
+ * 0 with F
+ * 2 with I
+ * -1 with T
+ * 1 with V
+ * etc
+ */
+ assertEquals(blosum.findColour('L', 0, null, "A", 0f), Color.white); // -1
+ assertEquals(blosum.findColour('L', 0, null, "B", 0f), Color.white); // -4
+ assertEquals(blosum.findColour('L', 0, null, "F", 0f), Color.white); // 0
+ assertEquals(blosum.findColour('L', 0, null, "I", 0f), lightBlue); // 2
+ assertEquals(blosum.findColour('L', 0, null, "TV", 0f), Color.white); // 0
+ assertEquals(blosum.findColour('L', 0, null, "IV", 0f), lightBlue); // 3
+ assertEquals(blosum.findColour('L', 0, null, "IT", 0f), lightBlue); // 1
+ assertEquals(blosum.findColour('L', 0, null, "IAT", 0f), Color.white); // 0
+ }
+}
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.datamodel.AlignmentI;
+import jalview.gui.AlignFrame;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+
+public class ClustalxColourSchemeTest
+{
+ // @formatter:off
+ private static final String FASTA =
+ ">seq1\nAAANNNRQ\n" +
+ ">seq2\nAAANNNRQ\n" +
+ ">seq3\nAAANNNRQ\n" +
+ ">seq4\nAAANNNRQ\n" +
+ ">seq5\nAAANYYKQ\n" +
+ ">seq6\nAAANYYKQ\n" +
+ ">seq7\nAVKWYYKQ\n" +
+ ">seq8\nKKKWYYQQ\n" +
+ ">seq9\nKKKWWYQQ\n" +
+ ">seq0\nKKKWWWQW\n";
+ // @formatter:on
+
+ @Test(groups = "Functional")
+ public void testFindColour()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(FASTA,
+ DataSourceType.PASTE);
+ AlignmentI al = af.getViewport().getAlignment();
+ ClustalxColourScheme cs = new ClustalxColourScheme(al, null);
+
+ /*
+ * column 1 is 70% A which is above Clustalx threshold of 60%
+ */
+ Color clustalBlue = new Color(0.5f, 0.7f, 0.9f);
+ assertEquals(cs.findColour('A', 0, al.getSequenceAt(0)), clustalBlue);
+
+ /*
+ * column 2 is 70% A or V which is above Clustalx threshold for group
+ */
+ assertEquals(cs.findColour('A', 0, al.getSequenceAt(1)), clustalBlue);
+
+ /*
+ * column 3 is 60% A which is not above Clustalx threshold
+ * the Ks in the other rows are not in the same Clustalx group
+ */
+ assertEquals(cs.findColour('A', 2, al.getSequenceAt(1)), Color.white);
+
+ /*
+ * column 4 is 60% N which is above Clustalx threshold of 50%
+ */
+ Color clustalGreen = new Color(0.1f, 0.8f, 0.1f);
+ assertEquals(cs.findColour('N', 3, al.getSequenceAt(1)), clustalGreen);
+
+ /*
+ * column 5 is 40% N and 40% Y which fails to pass the threshold of
+ * 50% N or 85% either
+ */
+ assertEquals(cs.findColour('N', 4, al.getSequenceAt(1)), Color.white);
+
+ /*
+ * column 6 is 40% N and 50% Y which fails to pass the threshold of
+ * 85% for either
+ */
+ assertEquals(cs.findColour('N', 5, al.getSequenceAt(1)), Color.white);
+
+ /*
+ * column 7 is 40% R and 30% K which combine to make > 60%
+ */
+ Color clustalRed = new Color(0.9f, 0.2f, 0.1f);
+ assertEquals(cs.findColour('R', 6, al.getSequenceAt(1)), clustalRed);
+ assertEquals(cs.findColour('K', 6, al.getSequenceAt(7)), clustalRed);
+
+ /*
+ * column 8 is >85% Q which qualifies K and R to be red
+ */
+ assertEquals(cs.findColour('R', 7, al.getSequenceAt(1)), clustalRed);
+ assertEquals(cs.findColour('K', 7, al.getSequenceAt(1)), clustalRed);
+
+ // TODO more test cases; check if help documentation matches implementation
+ }
+
+ // @formatter:on
+
+ /**
+ * Test for colour calculation when the consensus percentage ignores gapped
+ * sequences
+ */
+ @Test(groups = "Functional")
+ public void testFindColour_ignoreGaps()
+ {
+ /*
+ * CCC
+ * CCC
+ * -CC
+ * first column is 66% C (blue) including gaps
+ * or 100% C ignoring gaps
+ */
+ String fasta = ">seq1\nCCC\n>seq2\nccc\n>seq3\n-CC\n";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(fasta,
+ DataSourceType.PASTE);
+ AlignmentI al = af.getViewport().getAlignment();
+ ClustalxColourScheme cs = new ClustalxColourScheme(al, null);
+
+ /*
+ * column 1 is 66% C which is above Clustalx threshold of 60%
+ */
+ Color clustalBlue = ClustalxColourScheme.ClustalColour.BLUE.colour;
+ assertEquals(cs.findColour('C', 0, al.getSequenceAt(0)), clustalBlue);
+
+ /*
+ * set directly to ignore gaps
+ */
+ cs.setIncludeGaps(false);
+ Color clustalPink = ClustalxColourScheme.ClustalColour.PINK.colour;
+ assertEquals(cs.findColour('C', 0, al.getSequenceAt(0)), clustalPink);
+
+ /*
+ * set ignore gaps on the viewport...
+ */
+ cs.setIncludeGaps(true);
+ assertEquals(cs.findColour('C', 0, al.getSequenceAt(0)), clustalBlue);
+ af.getViewport().setIgnoreGapsConsensus(true, af.alignPanel);
+ // next test fails: colour scheme does not read ignore gaps flag from
+ // viewport
+ // assertEquals(cs.findColour('C', 0, al.getSequenceAt(0)), clustalPink);
+ }
+}
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+
+public class ColourSchemePropertyTest
+{
+ @Test(groups = "Functional")
+ public void testGetColourName()
+ {
+ SequenceI seq = new Sequence("Seq1", "abcd");
+ AlignmentI al = new Alignment(new SequenceI[] { seq });
+ ColourSchemeI cs = new ClustalxColourScheme(al, null);
+ assertEquals(ColourSchemeProperty.getColourName(cs), "Clustal");
+ cs = new Blosum62ColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs), "Blosum62");
+ cs = new PIDColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs), "% Identity");
+ cs = new HydrophobicColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs), "Hydrophobic");
+ cs = new ZappoColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs), "Zappo");
+ cs = new TaylorColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs), "Taylor");
+ cs = new HelixColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs),
+ "Helix Propensity");
+ cs = new StrandColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs),
+ "Strand Propensity");
+ cs = new TurnColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs), "Turn Propensity");
+ cs = new BuriedColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs), "Buried Index");
+ cs = new NucleotideColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs), "Nucleotide");
+ cs = new PurinePyrimidineColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs),
+ "Purine/Pyrimidine");
+ cs = new TCoffeeColourScheme(al);
+ assertEquals(ColourSchemeProperty.getColourName(cs), "T-Coffee Scores");
+ cs = new RNAHelicesColour(al);
+ assertEquals(ColourSchemeProperty.getColourName(cs), "RNA Helices");
+ cs = new RNAInteractionColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs),
+ "RNA Interaction type");
+ cs = new UserColourScheme();
+ assertEquals(ColourSchemeProperty.getColourName(cs), "User Defined");
+
+ /*
+ * UserColourScheme may have a bespoke name
+ */
+ ((UserColourScheme) cs).setName("stripy");
+ assertEquals(ColourSchemeProperty.getColourName(cs), "stripy");
+ ((UserColourScheme) cs).setName("");
+ assertEquals(ColourSchemeProperty.getColourName(cs), "User Defined");
+ ((UserColourScheme) cs).setName(null);
+ assertEquals(ColourSchemeProperty.getColourName(cs), "User Defined");
+
+ assertEquals(ColourSchemeProperty.getColourName(null), "None");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetColourScheme()
+ {
+ SequenceI seq = new Sequence("Seq1", "abcd");
+ AlignmentI al = new Alignment(new SequenceI[] { seq });
+ // the strings here correspond to JalviewColourScheme.toString() values
+ ColourSchemeI cs = ColourSchemeProperty.getColourScheme(al, "Clustal");
+ assertTrue(cs instanceof ClustalxColourScheme);
+ // not case-sensitive
+ cs = ColourSchemeProperty.getColourScheme(al, "CLUSTAL");
+ assertTrue(cs instanceof ClustalxColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "clustal");
+ assertTrue(cs instanceof ClustalxColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Blosum62");
+ assertTrue(cs instanceof Blosum62ColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "% Identity");
+ assertTrue(cs instanceof PIDColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Zappo");
+ assertTrue(cs instanceof ZappoColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Taylor");
+ assertTrue(cs instanceof TaylorColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Hydrophobic");
+ assertTrue(cs instanceof HydrophobicColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Helix Propensity");
+ assertTrue(cs instanceof HelixColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Strand Propensity");
+ assertTrue(cs instanceof StrandColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Turn Propensity");
+ assertTrue(cs instanceof TurnColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Buried Index");
+ assertTrue(cs instanceof BuriedColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Nucleotide");
+ assertTrue(cs instanceof NucleotideColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "Purine/Pyrimidine");
+ assertTrue(cs instanceof PurinePyrimidineColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "T-Coffee Scores");
+ assertTrue(cs instanceof TCoffeeColourScheme);
+ cs = ColourSchemeProperty.getColourScheme(al, "RNA Helices");
+ assertTrue(cs instanceof RNAHelicesColour);
+ // 'None' is a special value
+ assertNull(ColourSchemeProperty.getColourScheme(al, "None"));
+ assertNull(ColourSchemeProperty.getColourScheme(al, "none"));
+ // default is to convert the name into a fixed colour
+ cs = ColourSchemeProperty.getColourScheme(al, "elephants");
+ assertTrue(cs instanceof UserColourScheme);
+
+ /*
+ * explicit aa colours
+ */
+ UserColourScheme ucs = (UserColourScheme) ColourSchemeProperty
+ .getColourScheme(al,
+ "R,G=red;C=blue;c=green;Q=10,20,30;S,T=11ffdd");
+ assertEquals(ucs.findColour('H'), Color.white);
+ assertEquals(ucs.findColour('R'), Color.red);
+ assertEquals(ucs.findColour('r'), Color.red);
+ assertEquals(ucs.findColour('G'), Color.red);
+ assertEquals(ucs.findColour('C'), Color.blue);
+ assertEquals(ucs.findColour('c'), Color.green);
+ assertEquals(ucs.findColour('Q'), new Color(10, 20, 30));
+ assertEquals(ucs.findColour('S'), new Color(0x11ffdd));
+ assertEquals(ucs.findColour('T'), new Color(0x11ffdd));
+ }
+}
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.SequenceRenderer;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.schemes.ClustalxColourScheme.ClustalColour;
+
+import java.awt.Color;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ColourSchemesTest
+{
+ /*
+ * a colour scheme that alternates Taylor and Zappo
+ * colouring by column
+ */
+ class Stripy extends ResidueColourScheme
+ {
+ private ResidueColourScheme odd;
+
+ private ResidueColourScheme even;
+
+ private Stripy()
+ {
+ }
+
+ /**
+ * constructor given colours for odd and even columns
+ *
+ * @param odd
+ * @param even
+ */
+ private Stripy(ColourSchemeI cs1, ColourSchemeI cs2)
+ {
+ odd = (ResidueColourScheme) cs1;
+ even = (ResidueColourScheme) cs2;
+ }
+
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI sg,
+ Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
+ {
+ final ColourSchemeI cs1 = ColourSchemes.getInstance()
+ .getColourScheme(JalviewColourScheme.Taylor.toString(),
+ (AnnotatedCollectionI) null);
+ final ColourSchemeI cs2 = ColourSchemes.getInstance()
+ .getColourScheme(JalviewColourScheme.Zappo.toString(),
+ (AnnotatedCollectionI) null);
+ return new Stripy(cs1, cs2);
+ }
+
+ @Override
+ public Color findColour(char c, int j, SequenceI seq)
+ {
+ if (j % 2 == 1)
+ {
+ return odd.findColour(c, j, seq);
+ }
+ else
+ {
+ return even.findColour(c, j, seq);
+ }
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return "stripy";
+ }
+ };
+
+ /*
+ * a colour scheme that is Clustal but using AWT colour equivalents
+ */
+ class MyClustal extends ResidueColourScheme
+ {
+ ClustalxColourScheme delegate;
+
+ private MyClustal()
+ {
+ }
+
+ private MyClustal(AnnotatedCollectionI sg,
+ Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
+ {
+ delegate = new ClustalxColourScheme(sg, hiddenRepSequences);
+ }
+
+ @Override
+ public Color findColour(char c, int j, SequenceI seq)
+ {
+ Color col = delegate.findColour(c, j, seq);
+ Color result = col;
+ if (col.equals(ClustalColour.BLUE.colour))
+ {
+ result = Color.blue;
+ }
+ else if (col.equals(ClustalColour.CYAN.colour))
+ {
+ result = Color.cyan;
+ }
+ else if (col.equals(ClustalColour.GREEN.colour))
+ {
+ result = Color.green;
+ }
+ else if (col.equals(ClustalColour.MAGENTA.colour))
+ {
+ result = Color.magenta;
+ }
+ else if (col.equals(ClustalColour.ORANGE.colour))
+ {
+ result = Color.orange;
+ }
+ else if (col.equals(ClustalColour.PINK.colour))
+ {
+ result = Color.pink;
+ }
+ else if (col.equals(ClustalColour.RED.colour))
+ {
+ result = Color.red;
+ }
+ else if (col.equals(ClustalColour.YELLOW.colour))
+ {
+ result = Color.yellow;
+ }
+ return result;
+ }
+
+ @Override
+ public ColourSchemeI getInstance(AnnotatedCollectionI sg,
+ Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
+ {
+ return new MyClustal(sg, hiddenRepSequences);
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return "MyClustal";
+ }
+
+ }
+
+ @BeforeClass(alwaysRun = true)
+ public static void setUpBeforeClass() throws Exception
+ {
+ /*
+ * use read-only test properties file
+ */
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ Jalview.main(new String[] { "-nonews" });
+ }
+
+ @AfterClass(alwaysRun = true)
+ public static void tearDownAfterClass() throws Exception
+ {
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetColourSchemes()
+ {
+ /*
+ * this just verifies that built-in colour schemes are loaded into ColourSchemes
+ * in the order in which they are declared in the JalviewColourScheme enum
+ * (this also determines their order in Colour menus)
+ */
+ Iterator<ColourSchemeI> schemes = ColourSchemes.getInstance().getColourSchemes().iterator();
+ JalviewColourScheme[] jalviewSchemes = JalviewColourScheme.values();
+ int i = 0;
+ while (schemes.hasNext() && i < jalviewSchemes.length)
+ {
+ assertTrue(schemes.next().getSchemeName()
+ .equals(jalviewSchemes[i].toString()));
+ i++;
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testGetColourScheme()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ ">seq1\nAGLRTWQU", DataSourceType.PASTE);
+ ColourSchemes schemes = ColourSchemes.getInstance();
+
+ AnnotatedCollectionI al = af.getViewport().getAlignment();
+
+ for (JalviewColourScheme cs : JalviewColourScheme.values())
+ {
+ ColourSchemeI registered = schemes.getColourScheme(cs.toString(), al);
+ assertSame(registered.getClass(), cs.getSchemeClass());
+ }
+ af.closeMenuItem_actionPerformed(true);
+ }
+
+ @Test(groups = "Functional")
+ public void testRegisterColourScheme()
+ {
+ ColourSchemes.getInstance().registerColourScheme(new Stripy());
+ ColourSchemes.getInstance().registerColourScheme(new MyClustal());
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ /*
+ * set a breakpoint here to see and play with the newly registered
+ * colour schemes in the AlignFrame colour menu
+ */
+ SequenceRenderer sr = new SequenceRenderer(af.getViewport());
+ SequenceI seq = af.getViewport().getAlignment().findName("FER_CAPAA");
+
+ /*
+ * set and check Taylor colours
+ */
+ af.changeColour_actionPerformed(JalviewColourScheme.Taylor.toString());
+ Color taylor1 = sr.getResidueBoxColour(seq, 88); // E 255,0,102
+ Color taylor2 = sr.getResidueBoxColour(seq, 89); // A 204,255,0
+ Color taylor3 = sr.getResidueBoxColour(seq, 90); // G 255,153,0
+ assertEquals(taylor1, new Color(255, 0, 102));
+ assertEquals(taylor2, new Color(204, 255, 0));
+ assertEquals(taylor3, new Color(255, 153, 0));
+
+ /*
+ * set and check Zappo colours
+ */
+ af.changeColour_actionPerformed(JalviewColourScheme.Zappo.toString());
+ Color zappo1 = sr.getResidueBoxColour(seq, 88); // E red
+ Color zappo2 = sr.getResidueBoxColour(seq, 89); // A pink
+ Color zappo3 = sr.getResidueBoxColour(seq, 90); // G magenta
+ assertEquals(zappo1, Color.red);
+ assertEquals(zappo2, Color.pink);
+ assertEquals(zappo3, Color.magenta);
+
+ /*
+ * set 'stripy' colours - odd columns are Taylor and even are Zappo
+ */
+ af.changeColour_actionPerformed("stripy");
+ Color stripy1 = sr.getResidueBoxColour(seq, 88);
+ Color stripy2 = sr.getResidueBoxColour(seq, 89);
+ Color stripy3 = sr.getResidueBoxColour(seq, 90);
+ assertEquals(stripy1, zappo1);
+ assertEquals(stripy2, taylor2);
+ assertEquals(stripy3, zappo3);
+
+ /*
+ * set and check Clustal colours
+ */
+ af.changeColour_actionPerformed(JalviewColourScheme.Clustal.toString());
+ Color clustal1 = sr.getResidueBoxColour(seq, 88);
+ Color clustal2 = sr.getResidueBoxColour(seq, 89);
+ Color clustal3 = sr.getResidueBoxColour(seq, 90);
+ assertEquals(clustal1, ClustalColour.MAGENTA.colour);
+ assertEquals(clustal2, ClustalColour.BLUE.colour);
+ assertEquals(clustal3, ClustalColour.ORANGE.colour);
+
+ /*
+ * set 'MyClustal' colours - uses AWT colour equivalents
+ */
+ af.changeColour_actionPerformed("MyClustal");
+ Color myclustal1 = sr.getResidueBoxColour(seq, 88);
+ Color myclustal2 = sr.getResidueBoxColour(seq, 89);
+ Color myclustal3 = sr.getResidueBoxColour(seq, 90);
+ assertEquals(myclustal1, Color.MAGENTA);
+ assertEquals(myclustal2, Color.BLUE);
+ assertEquals(myclustal3, Color.ORANGE);
+ }
+
+ /**
+ * Tests for check if scheme name exists. Built-in scheme names are the
+ * toString() values of enum JalviewColourScheme.
+ */
+ @Test(groups = "Functional")
+ public void testNameExists()
+ {
+ ColourSchemes cs = ColourSchemes.getInstance();
+ assertFalse(cs.nameExists(null));
+ assertFalse(cs.nameExists(""));
+ assertTrue(cs.nameExists("Clustal"));
+ assertTrue(cs.nameExists("CLUSTAL"));
+ assertFalse(cs.nameExists("CLUSTAL "));
+ assertTrue(cs.nameExists("% Identity"));
+ assertFalse(cs.nameExists("PID"));
+ }
+}
import jalview.datamodel.SequenceFeature;
import jalview.gui.JvOptionPane;
+import jalview.util.ColorUtils;
import jalview.util.Format;
import java.awt.Color;
fc.setColourByLabel(true);
SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
null);
- Color expected = UserColourScheme.createColourFromName("desc");
+ Color expected = ColorUtils.createColourFromName("desc");
assertEquals(expected, fc.getColor(sf));
}
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+
+public class JalviewColourSchemeTest
+{
+ @Test(groups = "Functional")
+ public void testGetSchemeClass()
+ {
+ assertTrue(JalviewColourScheme.Clustal.getSchemeClass() == ClustalxColourScheme.class);
+ assertTrue(JalviewColourScheme.Blosum62.getSchemeClass() == Blosum62ColourScheme.class);
+ assertTrue(JalviewColourScheme.PID.getSchemeClass() == PIDColourScheme.class);
+ assertTrue(JalviewColourScheme.Hydrophobic.getSchemeClass() == HydrophobicColourScheme.class);
+ assertTrue(JalviewColourScheme.Zappo.getSchemeClass() == ZappoColourScheme.class);
+ assertTrue(JalviewColourScheme.Taylor.getSchemeClass() == TaylorColourScheme.class);
+ assertTrue(JalviewColourScheme.Helix.getSchemeClass() == HelixColourScheme.class);
+ assertTrue(JalviewColourScheme.Strand.getSchemeClass() == StrandColourScheme.class);
+ assertTrue(JalviewColourScheme.Turn.getSchemeClass() == TurnColourScheme.class);
+ assertTrue(JalviewColourScheme.Buried.getSchemeClass() == BuriedColourScheme.class);
+ assertTrue(JalviewColourScheme.Nucleotide.getSchemeClass() == NucleotideColourScheme.class);
+ assertTrue(JalviewColourScheme.PurinePyrimidine.getSchemeClass() == PurinePyrimidineColourScheme.class);
+ assertTrue(JalviewColourScheme.TCoffee.getSchemeClass() == TCoffeeColourScheme.class);
+ assertTrue(JalviewColourScheme.RNAHelices.getSchemeClass() == RNAHelicesColour.class);
+ }
+
+ @Test(groups = "Functional")
+ public void testToString()
+ {
+ assertEquals(JalviewColourScheme.Clustal.toString(), "Clustal");
+ assertEquals(JalviewColourScheme.Blosum62.toString(), "Blosum62");
+ assertEquals(JalviewColourScheme.PID.toString(), "% Identity");
+ assertEquals(JalviewColourScheme.Zappo.toString(), "Zappo");
+ assertEquals(JalviewColourScheme.Taylor.toString(), "Taylor");
+ assertEquals(JalviewColourScheme.Hydrophobic.toString(), "Hydrophobic");
+ assertEquals(JalviewColourScheme.Helix.toString(), "Helix Propensity");
+ assertEquals(JalviewColourScheme.Strand.toString(), "Strand Propensity");
+ assertEquals(JalviewColourScheme.Turn.toString(), "Turn Propensity");
+ assertEquals(JalviewColourScheme.Buried.toString(), "Buried Index");
+ assertEquals(JalviewColourScheme.Nucleotide.toString(), "Nucleotide");
+ assertEquals(JalviewColourScheme.PurinePyrimidine.toString(),
+ "Purine/Pyrimidine");
+ assertEquals(JalviewColourScheme.TCoffee.toString(), "T-Coffee Scores");
+ assertEquals(JalviewColourScheme.RNAHelices.toString(), "RNA Helices");
+ }
+}
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+
+public class PIDColourSchemeTest
+{
+ static final Color white = Color.white;
+
+ static final Color over40 = new Color(204, 204, 255);
+
+ static final Color over60 = new Color(153, 153, 255);
+
+ static final Color over80 = new Color(100, 100, 255);
+
+ /**
+ * Test findColour for cases:
+ * <ul>
+ * <li>gap: white</li>
+ * <li>no match to consensus: white</li>
+ * <li>match consensus with pid > 80%: 100,100,255</li>
+ * <li>match consensus with pid > 60%: 153, 153, 255</li>
+ * <li>match consensus with pid > 40%: 204, 204, 255</li>
+ * <li>match consensus with pid <= 40%: white</li>
+ * <li>joint consensus matching</li>
+ * <li>case insensitive matching</li>
+ * <ul>
+ */
+ @Test(groups = "Functional")
+ public void testFindColour()
+ {
+ ColourSchemeI scheme = new PIDColourScheme();
+
+ /*
+ * doesn't use column or sequence
+ * we assume consensus residue is computed as upper case
+ */
+ assertEquals(scheme.findColour('A', 0, null, "A", 0f), white);
+ assertEquals(scheme.findColour('A', 0, null, "A", 40f), white);
+ assertEquals(scheme.findColour('A', 0, null, "A", 40.1f), over40);
+ assertEquals(scheme.findColour('A', 0, null, "A", 60f), over40);
+ assertEquals(scheme.findColour('A', 0, null, "A", 60.1f), over60);
+ assertEquals(scheme.findColour('A', 0, null, "A", 80f), over60);
+ assertEquals(scheme.findColour('A', 0, null, "A", 80.1f), over80);
+ assertEquals(scheme.findColour('A', 0, null, "A", 100f), over80);
+ assertEquals(scheme.findColour('A', 0, null, "KFV", 100f), white);
+
+ assertEquals(scheme.findColour('a', 0, null, "A", 80f), over60);
+ assertEquals(scheme.findColour('A', 0, null, "AC", 80f), over60);
+ assertEquals(scheme.findColour('A', 0, null, "KCA", 80f), over60);
+ }
+
+ /**
+ * Test that changing the 'ignore gaps in consensus' in the viewport (an
+ * option on the annotation label popup menu) results in a change to the
+ * colouring
+ */
+ @Test(groups = "Functional")
+ public void testFindColour_ignoreGaps()
+ {
+ /*
+ * AAAAA
+ * AAAAA
+ * -CCCC
+ * FFFFF
+ *
+ * first column consensus is A
+ * first column PID is 50%, or 67% ignoring gaps
+ */
+ String seqs = ">seq1\nAAAAA\n>seq2\nAAAAA\n>seq3\n-CCCC\n>seq4\nFFFFF\n";
+
+ /*
+ * load data and wait for consensus to be computed
+ */
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqs,
+ DataSourceType.PASTE);
+ AlignViewport viewport = af.getViewport();
+ viewport.setIgnoreGapsConsensus(false, af.alignPanel);
+ while (viewport.getConsensusSeq() == null)
+ {
+ synchronized (this)
+ {
+ try
+ {
+ wait(50);
+ } catch (InterruptedException e)
+ {
+ }
+ }
+ }
+ af.changeColour_actionPerformed(JalviewColourScheme.PID.toString());
+
+ SequenceI seq = viewport.getAlignment().getSequenceAt(0);
+
+ /*
+ * including gaps, A should be coloured for 50% consensus
+ */
+ Color c = viewport
+ .getResidueShading().findColour('A', 0, seq);
+ assertEquals(c, over40);
+
+ /*
+ * now choose to ignore gaps; colour should be for 67%
+ */
+ viewport.setIgnoreGapsConsensus(true, af.alignPanel);
+ c = viewport
+ .getResidueShading().findColour('A', 0, seq);
+ assertEquals(c, over60);
+ }
+}
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
-import jalview.datamodel.Profile;
-import jalview.datamodel.ProfileI;
-import jalview.datamodel.Profiles;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
import jalview.gui.JvOptionPane;
-
-import java.awt.Color;
+import jalview.io.TCoffeeScoreFile;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class ResidueColourSchemeTest
{
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+
+ }
@BeforeClass(alwaysRun = true)
public void setUpJvOptionPane()
}
@Test(groups = "Functional")
- public void testAboveThreshold()
+ public void testIsApplicableTo()
{
+ SequenceI pep1 = new Sequence("pep1", "APQTWLS");
+ SequenceI pep2 = new Sequence("pep2", "AILFQYG");
+ SequenceI dna1 = new Sequence("dna1", "ACTGAC");
+ SequenceI dna2 = new Sequence("dna2", "TCCAAG");
+ AlignmentI peptide = new Alignment(new SequenceI[] { pep1, pep2 });
+ AlignmentI nucleotide = new Alignment(new SequenceI[] { dna1, dna2 });
+
/*
- * make up profiles for this alignment:
- * AR-Q
- * AR--
- * SR-T
- * SR-T
+ * peptide-specific colour schemes
*/
- ProfileI[] profiles = new ProfileI[4];
- profiles[0] = new Profile(4, 0, 2, "AS");
- profiles[1] = new Profile(4, 0, 4, "R");
- profiles[2] = new Profile(4, 4, 0, "");
- profiles[3] = new Profile(4, 1, 2, "T");
- ResidueColourScheme rcs = new ResidueColourScheme();
- rcs.setConsensus(new Profiles(profiles));
-
+ assertTrue(new ClustalxColourScheme(peptide, null)
+ .isApplicableTo(peptide));
+ assertFalse(new ClustalxColourScheme(nucleotide, null)
+ .isApplicableTo(nucleotide));
+ assertTrue(new Blosum62ColourScheme().isApplicableTo(peptide));
+ assertFalse(new Blosum62ColourScheme().isApplicableTo(nucleotide));
+ assertTrue(new BuriedColourScheme().isApplicableTo(peptide));
+ assertFalse(new BuriedColourScheme().isApplicableTo(nucleotide));
+ assertTrue(new HelixColourScheme().isApplicableTo(peptide));
+ assertFalse(new HelixColourScheme().isApplicableTo(nucleotide));
+ assertTrue(new HydrophobicColourScheme().isApplicableTo(peptide));
+ assertFalse(new HydrophobicColourScheme().isApplicableTo(nucleotide));
+ assertTrue(new StrandColourScheme().isApplicableTo(peptide));
+ assertFalse(new StrandColourScheme().isApplicableTo(nucleotide));
+ assertTrue(new TaylorColourScheme().isApplicableTo(peptide));
+ assertFalse(new TaylorColourScheme().isApplicableTo(nucleotide));
+ assertTrue(new TurnColourScheme().isApplicableTo(peptide));
+ assertFalse(new TurnColourScheme().isApplicableTo(nucleotide));
+ assertTrue(new ZappoColourScheme().isApplicableTo(peptide));
+ assertFalse(new ZappoColourScheme().isApplicableTo(nucleotide));
+
+ /*
+ * nucleotide-specific colour schemes
+ */
+ assertFalse(new NucleotideColourScheme().isApplicableTo(peptide));
+ assertTrue(new NucleotideColourScheme().isApplicableTo(nucleotide));
+ assertFalse(new PurinePyrimidineColourScheme().isApplicableTo(peptide));
+ assertTrue(new PurinePyrimidineColourScheme()
+ .isApplicableTo(nucleotide));
+ assertFalse(new RNAInteractionColourScheme().isApplicableTo(peptide));
+ assertTrue(new RNAInteractionColourScheme().isApplicableTo(nucleotide));
+
/*
- * no threshold
+ * indifferent
*/
- rcs.setThreshold(0, true);
- assertTrue(rcs.aboveThreshold('a', 0));
- assertTrue(rcs.aboveThreshold('S', 0));
- assertFalse(rcs.aboveThreshold('W', 0));
- assertTrue(rcs.aboveThreshold('R', 1));
- assertFalse(rcs.aboveThreshold('W', 2));
- assertTrue(rcs.aboveThreshold('t', 3));
- assertFalse(rcs.aboveThreshold('Q', 3));
+ assertTrue(new UserColourScheme().isApplicableTo(peptide));
+ assertTrue(new UserColourScheme().isApplicableTo(nucleotide));
+ assertTrue(new ScoreColourScheme(new int[] {}, new double[] {}, 0, 0d)
+ .isApplicableTo(peptide));
+ assertTrue(new ScoreColourScheme(new int[] {}, new double[] {}, 0, 0d)
+ .isApplicableTo(nucleotide));
+ ResidueColourScheme rcs = new PIDColourScheme();
+ assertTrue(rcs.isApplicableTo(peptide));
+ assertTrue(rcs.isApplicableTo(nucleotide));
+ assertTrue(new PIDColourScheme().isApplicableTo(peptide));
+ assertTrue(new PIDColourScheme().isApplicableTo(nucleotide));
+ assertTrue(new FollowerColourScheme().isApplicableTo(peptide));
+ assertTrue(new FollowerColourScheme().isApplicableTo(nucleotide));
/*
- * with threshold, include gaps
+ * TCoffee colour requires the presence of TCoffee score annotation
*/
- rcs.setThreshold(60, false);
- assertFalse(rcs.aboveThreshold('a', 0));
- assertFalse(rcs.aboveThreshold('S', 0));
- assertTrue(rcs.aboveThreshold('R', 1));
- assertFalse(rcs.aboveThreshold('W', 2));
- assertFalse(rcs.aboveThreshold('t', 3)); // 50% < 60%
+ assertFalse(new TCoffeeColourScheme(peptide).isApplicableTo(peptide));
+ assertFalse(new TCoffeeColourScheme(nucleotide)
+ .isApplicableTo(nucleotide));
+ AlignmentAnnotation aa = new AlignmentAnnotation("T-COFFEE", "", null);
+ aa.setCalcId(TCoffeeScoreFile.TCOFFEE_SCORE);
+ peptide.addAnnotation(aa);
+ aa = new AlignmentAnnotation("T-COFFEE", "", null);
+ aa.setCalcId(TCoffeeScoreFile.TCOFFEE_SCORE);
+ nucleotide.addAnnotation(aa);
+ assertTrue(new TCoffeeColourScheme(peptide).isApplicableTo(peptide));
+ assertTrue(new TCoffeeColourScheme(nucleotide)
+ .isApplicableTo(nucleotide));
/*
- * with threshold, ignore gaps
+ * RNAHelices requires the presence of rna secondary structure
*/
- rcs.setThreshold(60, true);
- assertFalse(rcs.aboveThreshold('a', 0));
- assertFalse(rcs.aboveThreshold('S', 0));
- assertTrue(rcs.aboveThreshold('R', 1));
- assertFalse(rcs.aboveThreshold('W', 2));
- assertTrue(rcs.aboveThreshold('t', 3)); // 67% > 60%
+ assertFalse(new RNAHelicesColour(peptide).isApplicableTo(peptide));
+ assertFalse(new RNAHelicesColour(nucleotide).isApplicableTo(nucleotide));
+ // add secondary structure (small but perfectly formed)
+ Annotation[] ss = new Annotation[2];
+ ss[0] = new Annotation("", "", '{', 0f);
+ ss[1] = new Annotation("", "", '}', 0f);
+ nucleotide.addAnnotation(new AlignmentAnnotation("SS", "", ss));
+ assertTrue(new RNAHelicesColour(nucleotide).isApplicableTo(nucleotide));
}
- /**
- * Test colour bleaching based on conservation score and conservation slider.
- * Scores of 10 or 11 should leave colours unchanged. Gap is always white.
- */
@Test(groups = "Functional")
- public void testApplyConservation()
+ public void testIsApplicableTo_dynamicColourScheme()
{
- ResidueColourScheme rcs = new ResidueColourScheme();
-
- // no conservation present - no fading
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 12));
-
- // cheat by setting conservation sequence directly
- // rather than calculating it - good enough for this test
- String consensus = "0123456789+*-";
- rcs.conservation = consensus.toCharArray();
-
- // column out of range:
- assertEquals(Color.RED,
- rcs.applyConservation(Color.RED, consensus.length()));
-
+ SequenceI pep1 = new Sequence("pep1", "APQTWLS");
+ SequenceI pep2 = new Sequence("pep2", "AILFQYG");
+ AlignmentI peptide = new Alignment(new SequenceI[] { pep1, pep2 });
+
/*
- * with 100% threshold, 'fade factor' is
- * (11-score)/10 * 100/20 = (11-score)/2
- * which is >= 1 for all scores i.e. all fade to white except +, *
+ * demonstrate that we can 'plug in' a colour scheme with specified
+ * criteria for applicability; here, that there are more than 2 sequences
*/
- rcs.setConservationInc(100);
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 0));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 1));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 2));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 3));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 4));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 5));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 6));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 7));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 8));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 9));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12));
+ ColourSchemeI cs = new UserColourScheme()
+ {
+ @Override
+ public boolean isApplicableTo(AnnotatedCollectionI ac)
+ {
+ AlignmentI al = ac.getContext() == null ? (AlignmentI) ac
+ : (AlignmentI) ac.getContext();
+ return al.getSequences().size() > 2;
+ }
+ };
+ assertFalse(cs.isApplicableTo(peptide));
+ peptide.addSequence(pep1);
+ assertTrue(cs.isApplicableTo(peptide));
+ }
- /*
- * with 0% threshold, there should be no fading
- */
- rcs.setConservationInc(0);
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 0));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 1));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 2));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 3));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 4));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 5));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 6));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 7));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 8));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 9));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
- assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
- assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12)); // gap
+ @Test(groups = "Functional")
+ public void testGetName()
+ {
+ SequenceI pep1 = new Sequence("pep1", "APQTWLS");
+ AlignmentI peptide = new Alignment(new SequenceI[] { pep1 });
- /*
- * with 40% threshold, 'fade factor' is
- * (11-score)/10 * 40/20 = (11-score)/5
- * which is {>1, >1, >1, >1, >1, >1, 1, 0.8, 0.6, 0.4} for score 0-9
- * e.g. score 7 colour fades 80% of the way to white (255, 255, 255)
- */
- rcs.setConservationInc(40);
- Color colour = new Color(155, 105, 55);
- assertEquals(Color.WHITE, rcs.applyConservation(colour, 0));
- assertEquals(Color.WHITE, rcs.applyConservation(colour, 1));
- assertEquals(Color.WHITE, rcs.applyConservation(colour, 2));
- assertEquals(Color.WHITE, rcs.applyConservation(colour, 3));
- assertEquals(Color.WHITE, rcs.applyConservation(colour, 4));
- assertEquals(Color.WHITE, rcs.applyConservation(colour, 5));
- assertEquals(Color.WHITE, rcs.applyConservation(colour, 6));
- assertEquals(new Color(235, 225, 215), rcs.applyConservation(colour, 7));
- assertEquals(new Color(215, 195, 175), rcs.applyConservation(colour, 8));
- assertEquals(new Color(195, 165, 135), rcs.applyConservation(colour, 9));
- assertEquals(colour, rcs.applyConservation(colour, 10));
- assertEquals(colour, rcs.applyConservation(colour, 11));
- assertEquals(Color.WHITE, rcs.applyConservation(colour, 12));
+ assertEquals("Blosum62", new Blosum62ColourScheme().getSchemeName());
+ assertEquals("Buried Index", new BuriedColourScheme().getSchemeName());
+ assertEquals("Helix Propensity", new HelixColourScheme().getSchemeName());
+ assertEquals("Hydrophobic", new HydrophobicColourScheme().getSchemeName());
+ assertEquals("Strand Propensity", new StrandColourScheme().getSchemeName());
+ assertEquals("Taylor", new TaylorColourScheme().getSchemeName());
+ assertEquals("Turn Propensity", new TurnColourScheme().getSchemeName());
+ assertEquals("Zappo", new ZappoColourScheme().getSchemeName());
+ assertEquals("Nucleotide", new NucleotideColourScheme().getSchemeName());
+ assertEquals("Purine/Pyrimidine",
+ new PurinePyrimidineColourScheme().getSchemeName());
+ assertEquals("RNA Interaction type",
+ new RNAInteractionColourScheme().getSchemeName());
+ assertEquals("User Defined", new UserColourScheme().getSchemeName());
+ assertEquals("Score", new ScoreColourScheme(new int[] {},
+ new double[] {}, 0, 0d).getSchemeName());
+ assertEquals("% Identity", new PIDColourScheme().getSchemeName());
+ assertEquals("Follower", new FollowerColourScheme().getSchemeName());
+ assertEquals("T-Coffee Scores",
+ new TCoffeeColourScheme(peptide).getSchemeName());
+ assertEquals("RNA Helices",
+ new RNAHelicesColour(peptide).getSchemeName());
}
}
import java.util.Map;
import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
public class ScoreMatrixPrinter
{
JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
}
- @Test(groups = { "Functional" })
public void printAllMatrices()
{
for (Map.Entry<String, ScoreModelI> sm : ResidueProperties.scoreMatrices
}
}
- @Test(groups = { "Functional" })
public void printHTMLMatrices()
{
for (Map.Entry<String, ScoreModelI> _sm : ResidueProperties.scoreMatrices
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.math.MatrixI;
+
+import org.testng.annotations.Test;
+
+public class ScoreMatrixTest
+{
+ @Test(groups = "Functional")
+ public void testSymmetric()
+ {
+ verifySymmetric(ResidueProperties.getScoreMatrix("BLOSUM62"));
+ verifySymmetric(ResidueProperties.getScoreMatrix("PAM250"));
+ verifySymmetric(ResidueProperties.getScoreMatrix("DNA"));
+ }
+
+ private void verifySymmetric(ScoreMatrix sm)
+ {
+ int[][] m = sm.getMatrix();
+ int rows = m.length;
+ for (int row = 0; row < rows; row++)
+ {
+ assertEquals(m[row].length, rows);
+ for (int col = 0; col < rows; col++)
+ {
+ assertEquals(m[row][col], m[col][row], String.format("%s [%s, %s]",
+ sm.getName(), ResidueProperties.aa[row],
+ ResidueProperties.aa[col]));
+ }
+ }
+
+ /*
+ * also check the score matrix is sized for
+ * the number of symbols scored, plus gap
+ */
+ assertEquals(rows, (sm.isDNA() ? ResidueProperties.maxNucleotideIndex
+ : ResidueProperties.maxProteinIndex) + 1);
+ }
+
+ /**
+ * A test that just asserts the expected values in the Blosum62 score matrix
+ */
+ @Test(groups = "Functional")
+ public void testBlosum62_values()
+ {
+ ScoreMatrix sm = ResidueProperties.getScoreMatrix("BLOSUM62");
+
+ /*
+ * verify expected scores against ARNDCQEGHILKMFPSTWYVBZX
+ * scraped from https://www.ncbi.nlm.nih.gov/Class/FieldGuide/BLOSUM62.txt
+ */
+ verifyValues(sm, 'A', new int[] { 4, -1, -2, -2, 0, -1, -1, 0, -2, -1,
+ -1, -1, -1, -2, -1, 1, 0, -3, -2, 0, -2, -1, 0 });
+ verifyValues(sm, 'R', new int[] { -1, 5, 0, -2, -3, 1, 0, -2, 0, -3,
+ -2, 2, -1, -3, -2, -1, -1, -3, -2, -3, -1, 0, -1 });
+ verifyValues(sm, 'N', new int[] { -2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3,
+ 0, -2, -3, -2, 1, 0, -4, -2, -3, 3, 0, -1 });
+ verifyValues(sm, 'D', new int[] { -2, -2, 1, 6, -3, 0, 2, -1, -1, -3,
+ -4, -1, -3, -3, -1, 0, -1, -4, -3, -3, 4, 1, -1 });
+ verifyValues(sm, 'C', new int[] { 0, -3, -3, -3, 9, -3, -4, -3, -3, -1,
+ -1, -3, -1, -2, -3, -1, -1, -2, -2, -1, -3, -3, -2 });
+ verifyValues(sm, 'Q', new int[] { -1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2,
+ 1, 0, -3, -1, 0, -1, -2, -1, -2, 0, 3, -1 });
+ verifyValues(sm, 'E', new int[] { -1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3,
+ 1, -2, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1 });
+ verifyValues(sm, 'G', new int[] { 0, -2, 0, -1, -3, -2, -2, 6, -2, -4,
+ -4, -2, -3, -3, -2, 0, -2, -2, -3, -3, -1, -2, -1 });
+ verifyValues(sm, 'H', new int[] { -2, 0, 1, -1, -3, 0, 0, -2, 8, -3,
+ -3, -1, -2, -1, -2, -1, -2, -2, 2, -3, 0, 0, -1 });
+ verifyValues(sm, 'I', new int[] { -1, -3, -3, -3, -1, -3, -3, -4, -3,
+ 4, 2, -3, 1, 0, -3, -2, -1, -3, -1, 3, -3, -3, -1 });
+ verifyValues(sm, 'L', new int[] { -1, -2, -3, -4, -1, -2, -3, -4, -3,
+ 2, 4, -2, 2, 0, -3, -2, -1, -2, -1, 1, -4, -3, -1 });
+ verifyValues(sm, 'K', new int[] { -1, 2, 0, -1, -3, 1, 1, -2, -1, -3,
+ -2, 5, -1, -3, -1, 0, -1, -3, -2, -2, 0, 1, -1 });
+ verifyValues(sm, 'M', new int[] { -1, -1, -2, -3, -1, 0, -2, -3, -2, 1,
+ 2, -1, 5, 0, -2, -1, -1, -1, -1, 1, -3, -1, -1 });
+ verifyValues(sm, 'F', new int[] { -2, -3, -3, -3, -2, -3, -3, -3, -1,
+ 0, 0, -3, 0, 6, -4, -2, -2, 1, 3, -1, -3, -3, -1 });
+ verifyValues(sm, 'P', new int[] { -1, -2, -2, -1, -3, -1, -1, -2, -2,
+ -3, -3, -1, -2, -4, 7, -1, -1, -4, -3, -2, -2, -1, -2 });
+ verifyValues(sm, 'S', new int[] { 1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2,
+ 0, -1, -2, -1, 4, 1, -3, -2, -2, 0, 0, 0 });
+ verifyValues(sm, 'T', new int[] { 0, -1, 0, -1, -1, -1, -1, -2, -2, -1,
+ -1, -1, -1, -2, -1, 1, 5, -2, -2, 0, -1, -1, 0 });
+ verifyValues(sm, 'W', new int[] { -3, -3, -4, -4, -2, -2, -3, -2, -2,
+ -3, -2, -3, -1, 1, -4, -3, -2, 11, 2, -3, -4, -3, -2 });
+ verifyValues(sm, 'Y', new int[] { -2, -2, -2, -3, -2, -1, -2, -3, 2,
+ -1, -1, -2, -1, 3, -3, -2, -2, 2, 7, -1, -3, -2, -1 });
+ verifyValues(sm, 'V', new int[] { 0, -3, -3, -3, -1, -2, -2, -3, -3, 3,
+ 1, -2, 1, -1, -2, -2, 0, -3, -1, 4, -3, -2, -1 });
+ verifyValues(sm, 'B', new int[] { -2, -1, 3, 4, -3, 0, 1, -1, 0, -3,
+ -4, 0, -3, -3, -2, 0, -1, -4, -3, -3, 4, 1, -1 });
+ verifyValues(sm, 'Z', new int[] { -1, 0, 0, 1, -3, 3, 4, -2, 0, -3, -3,
+ 1, -1, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1 });
+ verifyValues(sm, 'X', new int[] { 0, -1, -1, -1, -2, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -2, 0, 0, -2, -1, -1, -1, -1, -1 });
+ }
+ /**
+ * Helper method to check pairwise scores for one residue
+ *
+ * @param sm
+ * @param res
+ * @param expected
+ * score values against 'res', in ResidueProperties.aaIndex order
+ */
+ private void verifyValues(ScoreMatrix sm, char res, int[] expected)
+ {
+ for (int j = 0; j < expected.length; j++)
+ {
+ char c2 = ResidueProperties.aa[j].charAt(0);
+ assertEquals(sm.getPairwiseScore(res, c2), expected[j],
+ String.format("%s->%s", res, c2));
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testComputePairwiseScores()
+ {
+ String[] seqs = new String[] { "FKL", "R-D", "QIA", "GWC" };
+ ScoreMatrix sm = ResidueProperties.getScoreMatrix("BLOSUM62");
+
+ MatrixI pairwise = sm.computePairwiseScores(seqs);
+
+ /*
+ * should be NxN where N = number of sequences
+ */
+ assertEquals(pairwise.height(), 4);
+ assertEquals(pairwise.width(), 4);
+
+ /*
+ * should be symmetrical (because BLOSUM62 is)
+ */
+ for (int i = 0; i < pairwise.height(); i++)
+ {
+ for (int j = 0; j < pairwise.width(); j++)
+ {
+ assertEquals(pairwise.getValue(i, j), pairwise.getValue(j, i),
+ "Not symmetric");
+ }
+ }
+ /*
+ * verify expected BLOSUM dot product scores
+ */
+ // F.F + K.K + L.L = 6 + 5 + 4 = 15
+ assertEquals(pairwise.getValue(0, 0), 15d);
+ // R.R + -.- + D.D = 5 + 1 + 6 = 12
+ assertEquals(pairwise.getValue(1, 1), 12d);
+ // Q.Q + I.I + A.A = 5 + 4 + 4 = 13
+ assertEquals(pairwise.getValue(2, 2), 13d);
+ // G.G + W.W + C.C = 6 + 11 + 9 = 26
+ assertEquals(pairwise.getValue(3, 3), 26d);
+ // F.R + K.- + L.D = -3 + -4 + -4 = -11
+ assertEquals(pairwise.getValue(0, 1), -11d);
+ // F.Q + K.I + L.A = -3 + -3 + -1 = -7
+ assertEquals(pairwise.getValue(0, 2), -7d);
+ // F.G + K.W + L.C = -3 + -3 + -1 = -7
+ assertEquals(pairwise.getValue(0, 3), -7d);
+ // R.Q + -.I + D.A = 1 + -4 + -2 = -5
+ assertEquals(pairwise.getValue(1, 2), -5d);
+ // R.G + -.W + D.C = -2 + -4 + -3 = -9
+ assertEquals(pairwise.getValue(1, 3), -9d);
+ // Q.G + I.W + A.C = -2 + -3 + 0 = -5
+ assertEquals(pairwise.getValue(2, 3), -5d);
+ }
+}
package jalview.schemes;
import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNull;
-import static org.testng.AssertJUnit.assertSame;
import jalview.gui.JvOptionPane;
}
@Test(groups = "Functional")
- public void testGetColourFromString()
+ public void testParseAppletParameter()
{
- /*
- * by colour name - if known to AWT, and included in
- *
- * @see ColourSchemeProperty.getAWTColorFromName()
- */
- assertSame(Color.RED, UserColourScheme.getColourFromString("red"));
- assertSame(Color.RED, UserColourScheme.getColourFromString("Red"));
- assertSame(Color.RED, UserColourScheme.getColourFromString(" RED "));
+ UserColourScheme cs = new UserColourScheme("white");
+ cs.parseAppletParameter("D,E=red; K,R,H=0022FF; c=10 , 20,30");
+ assertEquals(Color.RED, cs.findColour('D'));
+ assertEquals(Color.RED, cs.findColour('d'));
+ assertEquals(Color.RED, cs.findColour('E'));
+ assertEquals(Color.RED, cs.findColour('e'));
+ Color c1 = new Color(0x0022ff);
+ assertEquals(c1, cs.findColour('K'));
+ assertEquals(c1, cs.findColour('R'));
+ assertEquals(c1, cs.findColour('h'));
+ Color c2 = new Color(10, 20, 30);
+ assertEquals(c2, cs.findColour('c'));
- /*
- * by RGB hex code
- */
- String hexColour = Integer.toHexString(Color.RED.getRGB() & 0xffffff);
- assertEquals(Color.RED, UserColourScheme.getColourFromString(hexColour));
- // 'hex' prefixes _not_ wanted here
- assertNull(UserColourScheme.getColourFromString("0x" + hexColour));
- assertNull(UserColourScheme.getColourFromString("#" + hexColour));
-
- /*
- * by RGB triplet
- */
- String rgb = String.format("%d,%d,%d", Color.red.getRed(),
- Color.red.getGreen(), Color.red.getBlue());
- assertEquals(Color.RED, UserColourScheme.getColourFromString(rgb));
+ cs = new UserColourScheme("white");
+ cs.parseAppletParameter("D,E=red; K,R,H=0022FF; c=10 , 20,30;t=orange;lowercase=blue;s=pink");
+ assertEquals(Color.RED, cs.findColour('D'));
+ assertEquals(Color.blue, cs.findColour('d'));
+ assertEquals(Color.RED, cs.findColour('E'));
+ assertEquals(Color.blue, cs.findColour('e'));
+ assertEquals(c1, cs.findColour('K'));
+ assertEquals(c1, cs.findColour('R'));
+ assertEquals(Color.blue, cs.findColour('h'));
+ assertEquals(c2, cs.findColour('c'));
+ // 'lowercase' sets all lower-case not already set to the given colour
+ assertEquals(Color.orange, cs.findColour('t'));
+ assertEquals(Color.blue, cs.findColour('k'));
+ assertEquals(Color.blue, cs.findColour('a'));
+ assertEquals(Color.pink, cs.findColour('s'));
+ }
- /*
- * odds and ends
- */
- assertNull(UserColourScheme.getColourFromString(null));
- assertNull(UserColourScheme.getColourFromString("rubbish"));
- assertEquals(Color.WHITE, UserColourScheme.getColourFromString("-1"));
- assertNull(UserColourScheme.getColourFromString(String
- .valueOf(Integer.MAX_VALUE)));
+ @Test(groups = "Functional")
+ public void testToAppletParameter()
+ {
+ UserColourScheme cs = new UserColourScheme(
+ "E,D=red; K,R,H=0022FF; c=10 , 20,30");
+ String param = cs.toAppletParameter();
+ assertEquals("D,E=ff0000;H,K,R=0022ff;c=0a141e", param);
}
}
--- /dev/null
+package jalview.structure;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+public class AtomSpecTest
+{
+ @Test
+ public void testFromChimeraAtomSpec()
+ {
+ AtomSpec as = AtomSpec.fromChimeraAtomspec("#1:12.B");
+ assertEquals(as.getModelNumber(), 1);
+ assertEquals(as.getPdbResNum(), 12);
+ assertEquals(as.getChain(), "B");
+ assertNull(as.getPdbFile());
+
+ // no model - default to zero
+ as = AtomSpec.fromChimeraAtomspec(":13.C");
+ assertEquals(as.getModelNumber(), 0);
+ assertEquals(as.getPdbResNum(), 13);
+ assertEquals(as.getChain(), "C");
+ assertNull(as.getPdbFile());
+
+ // model.submodel
+ as = AtomSpec.fromChimeraAtomspec("#3.2:15");
+ assertEquals(as.getModelNumber(), 3);
+ assertEquals(as.getPdbResNum(), 15);
+ assertEquals(as.getChain(), "");
+ assertNull(as.getPdbFile());
+
+ String spec = "3:12.B";
+ try
+ {
+ as = AtomSpec.fromChimeraAtomspec(spec);
+ fail("Expected exception for " + spec);
+ } catch (IllegalArgumentException e)
+ {
+ // ok
+ }
+
+ spec = "#3:12-14.B";
+ try
+ {
+ as = AtomSpec.fromChimeraAtomspec(spec);
+ fail("Expected exception for " + spec);
+ } catch (IllegalArgumentException e)
+ {
+ // ok
+ }
+
+ spec = "";
+ try
+ {
+ as = AtomSpec.fromChimeraAtomspec(spec);
+ fail("Expected exception for " + spec);
+ } catch (IllegalArgumentException e)
+ {
+ // ok
+ }
+
+ spec = null;
+ try
+ {
+ as = AtomSpec.fromChimeraAtomspec(spec);
+ fail("Expected exception for " + spec);
+ } catch (NullPointerException e)
+ {
+ // ok
+ }
+ }
+}
--- /dev/null
+package jalview.structure;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+public class StructureMappingTest
+{
+ @Test(groups = "Functional")
+ public void testgetPDBResNumRanges()
+ {
+ HashMap<Integer, int[]> map = new HashMap<Integer, int[]>();
+
+ StructureMapping mapping = new StructureMapping(null, null, null, null,
+ map, null);
+
+ List<int[]> ranges = mapping.getPDBResNumRanges(1, 2);
+ assertTrue(ranges.isEmpty());
+
+ map.put(1, new int[] { 12, 20 }); // 1 maps to 12
+ ranges = mapping.getPDBResNumRanges(2, 3);
+ assertTrue(ranges.isEmpty());
+ ranges = mapping.getPDBResNumRanges(1, 2);
+ assertEquals(ranges.size(), 1);
+ assertEquals(ranges.get(0)[0], 12);
+ assertEquals(ranges.get(0)[1], 12);
+
+ map.put(2, new int[] { 13, 20 }); // 2 maps to 13
+ ranges = mapping.getPDBResNumRanges(1, 2);
+ assertEquals(ranges.size(), 1);
+ assertEquals(ranges.get(0)[0], 12);
+ assertEquals(ranges.get(0)[1], 13);
+
+ map.put(3, new int[] { 15, 20 }); // 3 maps to 15 - break
+ ranges = mapping.getPDBResNumRanges(1, 5);
+ assertEquals(ranges.size(), 2);
+ assertEquals(ranges.get(0)[0], 12);
+ assertEquals(ranges.get(0)[1], 13);
+ assertEquals(ranges.get(1)[0], 15);
+ assertEquals(ranges.get(1)[1], 15);
+ }
+}
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureRenderer;
+import jalview.api.SequenceRenderer;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.PDBEntry.Type;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.gui.JvOptionPane;
import jalview.io.DataSourceType;
+import jalview.schemes.ColourSchemeI;
import jalview.structure.AtomSpec;
+import jalview.structure.StructureMappingcommandSet;
import jalview.structure.StructureSelectionManager;
import jalview.structures.models.AAStructureBindingModel.SuperposeData;
+import java.awt.Color;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.List;
import org.testng.annotations.BeforeClass;
{
return null;
}
+
+ @Override
+ public void setJalviewColourScheme(ColourSchemeI cs)
+ {
+ }
+
+ @Override
+ public String superposeStructures(AlignmentI[] als, int[] alm,
+ ColumnSelection[] alc)
+ {
+ return null;
+ }
+
+ @Override
+ public void setBackgroundColour(Color col)
+ {
+ }
+
+ @Override
+ protected StructureMappingcommandSet[] getColourBySequenceCommands(
+ String[] files, SequenceRenderer sr, FeatureRenderer fr,
+ AlignViewportI viewport)
+ {
+ return null;
+ }
+
+ @Override
+ public FeatureRenderer getFeatureRenderer(AlignmentViewPanel alignment)
+ {
+ return null;
+ }
+
+ @Override
+ public SequenceRenderer getSequenceRenderer(
+ AlignmentViewPanel alignment)
+ {
+ return null;
+ }
+
+ @Override
+ protected void colourBySequence(
+ StructureMappingcommandSet[] colourBySequenceCommands)
+ {
+ }
+
+ @Override
+ public void colourByChain()
+ {
+ }
+
+ @Override
+ public void colourByCharge()
+ {
+ }
};
}
structs[i] = testee.new SuperposeData(al.getWidth());
}
/*
- * initialise array of 'superposable columns' to true (would be false for
+ * initialise BitSet of 'superposable columns' to true (would be false for
* hidden columns)
*/
- boolean[] matched = new boolean[al.getWidth()];
- Arrays.fill(matched, true);
+ BitSet matched = new BitSet();
+ for (int i = 0; i < al.getWidth(); i++)
+ {
+ matched.set(i);
+ }
int refStructure = testee
.findSuperposableResidues(al, matched, structs);
/*
* only ungapped, structure-mapped columns are superposable
*/
- assertFalse(matched[0]); // gap in first sequence
- assertTrue(matched[1]);
- assertFalse(matched[2]); // gap in third sequence
- assertFalse(matched[3]); // gap in fourth sequence
- assertTrue(matched[4]);
- assertTrue(matched[5]); // gap in second sequence
+ assertFalse(matched.get(0)); // gap in first sequence
+ assertTrue(matched.get(1));
+ assertFalse(matched.get(2)); // gap in third sequence
+ assertFalse(matched.get(3)); // gap in fourth sequence
+ assertTrue(matched.get(4));
+ assertTrue(matched.get(5)); // gap in second sequence
assertEquals("1YCS", structs[0].pdbId);
assertEquals("3A6S", structs[1].pdbId);
structs[i] = testee.new SuperposeData(al.getWidth());
}
/*
- * initialise array of 'superposable columns' to true (would be false for
+ * initialise BitSet of 'superposable columns' to true (would be false for
* hidden columns)
*/
- boolean[] matched = new boolean[al.getWidth()];
- Arrays.fill(matched, true);
+ BitSet matched = new BitSet();
+ for (int i = 0; i < al.getWidth(); i++)
+ {
+ matched.set(i);
+ }
+
// treat column 5 of the alignment as hidden
- matched[4] = false;
+ matched.clear(4);
int refStructure = testee
.findSuperposableResidues(al, matched, structs);
assertEquals(0, refStructure);
// only ungapped, structure-mapped columns are not superposable
- assertFalse(matched[0]);
- assertTrue(matched[1]);
- assertFalse(matched[2]);
- assertFalse(matched[3]);
- assertFalse(matched[4]); // superposable, but hidden, column
- assertTrue(matched[5]);
+ assertFalse(matched.get(0));
+ assertTrue(matched.get(1));
+ assertFalse(matched.get(2));
+ assertFalse(matched.get(3));
+ assertFalse(matched.get(4)); // superposable, but hidden, column
+ assertTrue(matched.get(5));
}
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.applet.AppletUrlProviderFactory;
+import jalview.util.UrlConstants;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class AppletUrlProviderFactoryTest {
+
+ @Test(groups = { "Functional" })
+ public void testCreateUrlProvider()
+ {
+ final String defaultUrl = UrlConstants.DEFAULT_STRING.substring(
+ UrlConstants.DEFAULT_STRING.indexOf(UrlConstants.SEP) + 1,
+ UrlConstants.DEFAULT_STRING.length());
+ Map<String, String> urlList = new HashMap<String, String>()
+ {
+ {
+ put("Test1", "http://identifiers.org/uniprot/$DB_ACCESSION$");
+ put("Test2", defaultUrl);
+ }
+ };
+
+ UrlProviderFactoryI factory = new AppletUrlProviderFactory("Test2",
+ urlList);
+ UrlProviderI prov = factory.createUrlProvider();
+
+ // default url correctly set
+ Assert.assertEquals(prov.getPrimaryUrlId(), "Test2");
+ Assert.assertEquals(prov.getPrimaryUrl("FER_CAPAN"),
+ defaultUrl.replace("$SEQUENCE_ID$",
+ "FER_CAPAN"));
+
+ List<UrlLinkDisplay> allLinks = prov.getLinksForTable();
+
+ // 2 links in provider
+ Assert.assertEquals(allLinks.size(), 2);
+
+ // first link set correctly
+ Assert.assertEquals(allLinks.get(0).getId(), "Test1");
+ Assert.assertEquals(allLinks.get(0).getDescription(), "Test1");
+ Assert.assertEquals(allLinks.get(0).getUrl(),
+ "http://identifiers.org/uniprot/$DB_ACCESSION$");
+ Assert.assertFalse(allLinks.get(0).getIsPrimary());
+ Assert.assertTrue(allLinks.get(0).getIsSelected());
+
+ // second link set correctly
+ Assert.assertEquals(allLinks.get(1).getId(), "Test2");
+ Assert.assertEquals(allLinks.get(1).getDescription(), "Test2");
+ Assert.assertEquals(allLinks.get(1).getUrl(), defaultUrl);
+ Assert.assertTrue(allLinks.get(1).getIsPrimary());
+ Assert.assertTrue(allLinks.get(1).getIsSelected());
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.util.UrlConstants;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Vector;
+
+import org.testng.annotations.Test;
+
+public class CustomUrlProviderTest
+{
+
+ private static final String cachedList = "TEST|http://someurl.blah/$DB_ACCESSION$|"
+ + "ANOTHER|http://test/t$SEQUENCE_ID$|"
+ + "TEST2|http://address/$SEQUENCE_ID$|SRS|"
+ + "http://theSRSlink/$SEQUENCE_ID$";
+
+ private static final String unselectedList = "NON1|http://x/y/$DB_ACCESSION$|"
+ + "NON2|http://a/b/c/$DB_ACCESSION";
+
+ private static final HashMap<String, String> urlMap = new HashMap<String, String>()
+ {
+ {
+ put("TEST","http://someurl.blah/$DB_ACCESSION$");
+ put("ANOTHER","http://test/t$SEQUENCE_ID$");
+ put("TEST2", "http://address/$SEQUENCE_ID$");
+ put("SRS", "http://theSRSlink/$SEQUENCE_ID$");
+ }
+ };
+
+ private static final HashMap<String, String> unselUrlMap = new HashMap<String, String>()
+ {
+ {
+ put("NON1", "http://x/y/$DB_ACCESSION$");
+ put("NON2", "http://a/b/c/$DB_ACCESSION");
+ }
+ };
+
+ private static final String[] dlinks = {
+ "TEST|http://someurl.blah/$DB_ACCESSION$",
+ "ANOTHER|http://test/t$SEQUENCE_ID$",
+ "TEST2|http://address/$SEQUENCE_ID$",
+ UrlConstants.DEFAULT_STRING };
+
+ private static final String[] unselDlinks = {
+ "NON1|http://x/y/$DB_ACCESSION$", "NON2|http://a/b/c/$DB_ACCESSION" };
+
+ private static final Vector<String> displayLinks = new Vector<String>(
+ Arrays.asList(dlinks));
+
+ private static final Vector<String> unselDisplayLinks = new Vector<String>(
+ Arrays.asList(unselDlinks));
+
+ private static final String[] dlinks2 = { "a|http://x.y.z/$SEQUENCE_ID$" };
+
+ private static final Vector<String> displayLinks2 = new Vector<String>(
+ Arrays.asList(dlinks2));
+
+ private static final String[] list1 = { "a" };
+
+ private static final String[] list2 = { "http://x.y.z/$SEQUENCE_ID$" };
+
+ private static final Vector<String> names = new Vector<String>(
+ Arrays.asList(list1));
+
+ private static final Vector<String> urls = new Vector<String>(
+ Arrays.asList(list2));
+
+ /*
+ * Test default url is set and returned correctly
+ */
+ @Test(groups = { "Functional" })
+ public void testDefaultUrl()
+ {
+ UrlProviderI customProv = new CustomUrlProvider(cachedList,
+ unselectedList);
+
+ // default url can be set
+ assertTrue(customProv.setPrimaryUrl("ANOTHER"));
+
+ // supplied replacement id must be more than 4 chars
+ String result = customProv.getPrimaryUrl("123");
+ assertEquals(null, result);
+
+ // default url can be retrieved given a sequence id
+ result = customProv.getPrimaryUrl("seqid");
+ assertEquals("http://test/tseqid", result);
+
+ // if there is no default url it sets the default to null
+ assertFalse(customProv.setPrimaryUrl("No default"));
+ result = customProv.getPrimaryUrl("testid");
+ assertEquals(null, result);
+
+ // choosing the default picks the DEFAULT_STRING option
+ customProv.choosePrimaryUrl();
+ result = customProv.getPrimaryUrl("seqid");
+ assertEquals(
+ UrlConstants.DEFAULT_STRING.split("\\|")[1].split("\\$")[0]
+ + "seqid",
+ result);
+ }
+
+ /*
+ * Test urls are set and returned correctly
+ */
+ @Test(groups = { "Functional" })
+ public void testUrlLinks()
+ {
+ // creation from cached url list works + old links upgraded
+ UrlProviderI customProv = new CustomUrlProvider(cachedList,
+ unselectedList);
+ assertTrue(displayLinks.containsAll(customProv.getLinksForMenu()));
+
+ // creation from map works + old links upgraded
+ UrlProviderI customProv2 = new CustomUrlProvider(urlMap, unselUrlMap);
+ assertTrue(displayLinks.containsAll(customProv2.getLinksForMenu()));
+
+ // writing url links as a string works
+ // because UrlProvider does not guarantee order of links, we can't just
+ // compare the output of writeUrlsAsString to a string, hence the hoops here
+ String result = customProv.writeUrlsAsString(true);
+ UrlProviderI up = new CustomUrlProvider(result, "");
+ assertTrue(displayLinks.containsAll(up.getLinksForMenu()));
+
+ result = customProv.writeUrlsAsString(false);
+ up = new CustomUrlProvider("", result);
+ assertTrue(unselDisplayLinks.containsAll(up.getLinksForMenu()));
+
+ result = customProv2.writeUrlsAsString(true);
+ UrlProviderI up2 = new CustomUrlProvider(result, "");
+ assertTrue(displayLinks.containsAll(up2.getLinksForMenu()));
+
+ result = customProv2.writeUrlsAsString(false);
+ up2 = new CustomUrlProvider("", result);
+ assertTrue(displayLinks.containsAll(up2.getLinksForMenu()));
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.desktop.DesktopUrlProviderFactory;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class DesktopUrlProviderFactoryTest
+{
+ private static final String testIdOrgString = "{\"Local\": [{\"id\":\"MIR:00000002\",\"name\":\"ChEBI\",\"pattern\":\"^CHEBI:\\d+$\","
+ + "\"definition\":\"Chemical Entities of Biological Interest (ChEBI)\",\"prefix\":\"chebi\","
+ + "\"url\":\"http://identifiers.org/chebi\"},{\"id\":\"MIR:00000005\",\"name\":\"UniProt Knowledgebase\","
+ + "\"pattern\":\"^([A-N,R-Z][0-9]([A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(\\.\\d+)?$\","
+ + "\"definition\":\"The UniProt Knowledgebase (UniProtKB)\",\"prefix\":\"uniprot\",\"url\":\"http://identifiers.org/uniprot\"},"
+ + "{\"id\":\"MIR:00000011\",\"name\":\"InterPro\",\"pattern\":\"^IPR\\d{6}$\",\"definition\":\"InterPro\",\"prefix\":\"interpro\","
+ + "\"url\":\"http://identifiers.org/interpro\"},"
+ + "{\"id\":\"MIR:00000372\",\"name\":\"ENA\",\"pattern\":\"^[A-Z]+[0-9]+(\\.\\d+)?$\",\"definition\":\"The European Nucleotide Archive (ENA),\""
+ + "\"prefix\":\"ena.embl\",\"url\":\"http://identifiers.org/ena.embl\"}]}";
+
+ @BeforeMethod(alwaysRun = true)
+ public void setup()
+ {
+ // make a dummy identifiers.org download file
+ File temp = null;
+
+ try
+ {
+ temp = File.createTempFile("tempfile", ".tmp");
+ temp.deleteOnExit();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
+ bw.write(testIdOrgString);
+ bw.close();
+ } catch (IOException e)
+ {
+ System.out
+ .println("Error initialising DesktopUrlProviderFactoryTest test: "
+ + e.getMessage());
+ }
+
+ IdOrgSettings.setDownloadLocation(temp.getPath());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testCreateUrlProvider()
+ {
+ String defaultUrlString = "Test1";
+ String defaultUrl = "http://blah.blah/$SEQUENCE_ID$";
+ String cachedUrlList = "MIR:00000005|MIR:00000011|Test1|http://blah.blah/$SEQUENCE_ID$|"
+ + "Test2|http://test2/$DB_ACCESSION$|Test3|http://test3/$SEQUENCE_ID$";
+ String userUrlList = "MIR:00000372|Test4|httpL//another.url/$SEQUENCE_ID$";
+
+ DesktopUrlProviderFactory factory = new DesktopUrlProviderFactory(
+ defaultUrlString, cachedUrlList, userUrlList);
+ UrlProviderI prov = factory.createUrlProvider();
+
+ // default url correctly set
+ Assert.assertEquals(prov.getPrimaryUrlId(), "Test1");
+ Assert.assertEquals(prov.getPrimaryUrl("FER_CAPAN"),
+ defaultUrl.replace("$SEQUENCE_ID$", "FER_CAPAN"));
+
+ List<String> menulinks = prov.getLinksForMenu();
+ List<UrlLinkDisplay> allLinks = prov.getLinksForTable();
+
+ // 8 links in provider - 4 from id file, 4 custom links
+ Assert.assertEquals(allLinks.size(), 8);
+
+ // 5 links in menu (cachedUrlList)
+ Assert.assertEquals(menulinks.size(), 5);
+
+ Assert.assertTrue(menulinks
+ .contains("Test1|http://blah.blah/$SEQUENCE_ID$"));
+ Assert.assertTrue(menulinks
+ .contains("Test2|http://test2/$DB_ACCESSION$"));
+ Assert.assertTrue(menulinks
+ .contains("Test3|http://test3/$SEQUENCE_ID$"));
+ Assert.assertTrue(menulinks
+ .contains("UniProt Knowledgebase|http://identifiers.org/uniprot/$DB_ACCESSION$|uniprot"));
+ Assert.assertTrue(menulinks
+ .contains("InterPro|http://identifiers.org/interpro/$DB_ACCESSION$|interpro"));
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.urls.api.UrlProviderI;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Vector;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IdentifiersUrlProviderTest
+{
+ private static final String testIdOrgFile = "{\"Local\": [{\"id\":\"MIR:00000002\",\"name\":\"ChEBI\",\"pattern\":\"^CHEBI:\\d+$\","
+ + "\"definition\":\"Chemical Entities of Biological Interest (ChEBI)\",\"prefix\":\"chebi\","
+ + "\"url\":\"http://identifiers.org/chebi\"},{\"id\":\"MIR:00000005\",\"name\":\"UniProt Knowledgebase\","
+ + "\"pattern\":\"^([A-N,R-Z][0-9]([A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(\\.\\d+)?$\","
+ + "\"definition\":\"The UniProt Knowledgebase (UniProtKB)\",\"prefix\":\"uniprot\",\"url\":\"http://identifiers.org/uniprot\"},"
+ + "{\"id\":\"MIR:00000011\",\"name\":\"InterPro\",\"pattern\":\"^IPR\\d{6}$\",\"definition\":\"InterPro\",\"prefix\":\"interpro\","
+ + "\"url\":\"http://identifiers.org/interpro\"},"
+ + "{\"id\":\"MIR:00000372\",\"name\":\"ENA\",\"pattern\":\"^[A-Z]+[0-9]+(\\.\\d+)?$\",\"definition\":\"The European Nucleotide Archive (ENA),\""
+ + "\"prefix\":\"ena.embl\",\"url\":\"http://identifiers.org/ena.embl\"}]}";
+
+ private static final String[] dlinks = {
+ "UniProt Knowledgebase|http://identifiers.org/uniprot/$DB_ACCESSION$|uniprot",
+ "InterPro|http://identifiers.org/interpro/$DB_ACCESSION$|interpro",
+ "ENA|http://identifiers.org/ena.embl/$DB_ACCESSION$|ena.embl" };
+
+ private static final String[] dlinks1 = {
+ "MIR:00000011|http://identifiers.org/interpro/$DB_ACCESSION$",
+ "MIR:00000372|http://identifiers.org/ena.embl/$DB_ACCESSION$" };
+
+ private static final String[] dlinks2 = {
+ "MIR:00000005|http://identifiers.org/uniprot/$DB_ACCESSION$",
+ "MIR:00000011|http://identifiers.org/interpro/$DB_ACCESSION$" };
+
+ private static final String stringLinks = "MIR:00000005|http://identifiers.org/uniprot/$DB_ACCESSION$"
+ + "MIR:00000011|http://identifiers.org/interpro/$DB_ACCESSION$"
+ + "MIR:00000372|http://identifiers.org/ena.embl/$DB_ACCESSION$";
+
+ private static final String[] unselDlinks = { "ChEBI|http://identifiers.org/chebi/$DB_ACCESSION$" };
+
+ private static final Vector<String> displayLinks = new Vector<String>(
+ Arrays.asList(dlinks));
+
+ private static final Vector<String> unselDisplayLinks = new Vector<String>(
+ Arrays.asList(unselDlinks));
+
+ private static final Vector<String> displayLinks1 = new Vector<String>(
+ Arrays.asList(dlinks1));
+
+ private static final Vector<String> displayLinks2 = new Vector<String>(
+ Arrays.asList(dlinks2));
+
+ private static final HashMap<String, String> urlMap = new HashMap<String, String>()
+ {
+ {
+ put("MIR:00000005", "http://identifiers.org/uniprot/$DB_ACCESSION$");
+ put("MIR:00000011", "http://identifiers.org/interpro/$DB_ACCESSION$");
+ put("MIR:00000372", "http://identifiers.org/ena.embl/$DB_ACCESSION$");
+ }
+ };
+
+ private String testfile = "";
+
+
+ @BeforeClass(alwaysRun = true)
+ public void setup()
+ {
+ // setup test ids in a file
+ File outFile = null;
+ try
+ {
+ outFile = File.createTempFile("testidsfile", "txt");
+ outFile.deleteOnExit();
+
+ FileWriter fw = new FileWriter(outFile);
+ fw.write(testIdOrgFile);
+ fw.close();
+
+ testfile = outFile.getAbsolutePath();
+
+ } catch (Exception ex)
+ {
+ System.err.println(ex);
+ }
+
+ IdOrgSettings.setDownloadLocation(testfile);
+ }
+
+ /*
+ * Test urls are set and returned correctly
+ */
+ @Test(groups = { "Functional" })
+ public void testUrlLinks()
+ {
+ // creation from cached id list
+ String idList = "MIR:00000005|MIR:00000011|MIR:00000372";
+ UrlProviderI idProv = new IdentifiersUrlProvider(idList);
+
+ assertTrue(displayLinks.containsAll(idProv.getLinksForMenu()));
+
+ // because UrlProvider does not guarantee order of links, we can't just
+ // compare the output of writeUrlsAsString to a string, hence the hoops here
+ String result = idProv.writeUrlsAsString(true);
+ UrlProviderI up = new IdentifiersUrlProvider(result);
+ assertTrue(displayLinks.containsAll(up.getLinksForMenu()));
+
+ result = idProv.writeUrlsAsString(false);
+ up = new IdentifiersUrlProvider(result);
+ assertTrue(unselDisplayLinks.containsAll(up.getLinksForMenu()));
+
+ }
+
+ /*
+ * Test default is set and returned correctly
+ */
+ @Test(groups = { "Functional" })
+ public void testDefaultUrl()
+ {
+ // creation from cached id list
+ String idList = "MIR:00000005|MIR:00000011|MIR:00000372";
+ UrlProviderI idProv = new IdentifiersUrlProvider(idList);
+
+ // initially no default
+ assertEquals(null, idProv.getPrimaryUrl("seqid"));
+
+ // set and then retrieve default
+ assertTrue(idProv.setPrimaryUrl("MIR:00000005"));
+ assertEquals("http://identifiers.org/uniprot/seqid",
+ idProv.getPrimaryUrl("seqid"));
+
+ // ids less than length 4 return null
+ assertEquals(null,
+ idProv.getPrimaryUrl("123"));
+
+ // attempt to set bad default
+ assertFalse(idProv.setPrimaryUrl("MIR:00001234"));
+ // default set to null (as default should have been set elsewhere)
+ assertEquals(null, idProv.getPrimaryUrl("seqid"));
+
+ // chooseDefaultUrl not implemented for IdentifiersUrlProvider
+ assertEquals(null, idProv.choosePrimaryUrl());
+ }
+}
--- /dev/null
+package jalview.urls;
+
+import jalview.util.UrlLink;
+
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class UrlLinkDisplayTest {
+
+ @Test(groups = { "Functional" })
+ public void testDisplayColumnNames()
+ {
+ // 5 column names returned although 6 names internal to UrlLinkDisplay
+ List<String> names = UrlLinkDisplay.getDisplayColumnNames();
+ Assert.assertEquals(names.size(), 5);
+ }
+
+ @Test(groups = { "Functional" })
+ public void getValue()
+ {
+ UrlLink link = new UrlLink("Test Name",
+ "http://identifiers.org/$DB_ACCESSION$", "TestDB");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ Assert.assertFalse((boolean) u.getValue(UrlLinkDisplay.PRIMARY));
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.ID), "Test");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.DATABASE), "TestDB");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.NAME), "Test Name");
+ Assert.assertFalse((boolean) u.getValue(UrlLinkDisplay.SELECTED));
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.URL),
+ "http://identifiers.org/$DB_ACCESSION$");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testIsEditable()
+ {
+ // only default and selected columns are editable ever
+ // default only editable if link contains $SEQUENCE_ID$
+
+ UrlLink link = new UrlLink("Test Url",
+ "http://identifiers.org/$DB_ACCESSION$",
+ "TestName");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ Assert.assertFalse(u.isEditable(UrlLinkDisplay.PRIMARY));
+ Assert.assertTrue(u.isEditable(UrlLinkDisplay.SELECTED));
+ Assert.assertFalse(u.isEditable(UrlLinkDisplay.ID));
+ Assert.assertFalse(u.isEditable(UrlLinkDisplay.URL));
+ Assert.assertFalse(u.isEditable(UrlLinkDisplay.NAME));
+ Assert.assertFalse(u.isEditable(UrlLinkDisplay.DATABASE));
+
+ UrlLink vlink = new UrlLink("Test Sequence ID Url",
+ "http://myurl/$SEQUENCE_ID$", "TestName");
+ UrlLinkDisplay v = new UrlLinkDisplay("Test", vlink, false, false);
+
+ Assert.assertTrue(v.isEditable(UrlLinkDisplay.PRIMARY));
+ Assert.assertTrue(v.isEditable(UrlLinkDisplay.SELECTED));
+ Assert.assertFalse(v.isEditable(UrlLinkDisplay.ID));
+ Assert.assertFalse(v.isEditable(UrlLinkDisplay.URL));
+ Assert.assertFalse(v.isEditable(UrlLinkDisplay.NAME));
+ Assert.assertFalse(v.isEditable(UrlLinkDisplay.DATABASE));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testName()
+ {
+ UrlLink link = new UrlLink("Test Url",
+ "http://identifiers.org/$DB_ACCESSION$", "TestName");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ // Name initially as input in link
+ Assert.assertEquals(u.getDBName(), "TestName");
+
+ // Setting updates name
+ u.setDBName("NewName");
+ Assert.assertEquals(u.getDBName(), "NewName");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testDescription()
+ {
+ UrlLink link = new UrlLink("Test Name",
+ "http://identifiers.org/$DB_ACCESSION$", "TestDB");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ // Desc initially as input in link
+ Assert.assertEquals(u.getDescription(), "Test Name");
+
+ // Setting updates name
+ u.setDescription("New Desc");
+ Assert.assertEquals(u.getDescription(), "New Desc");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testUrl()
+ {
+ UrlLink link = new UrlLink("Test Name",
+ "http://identifiers.org/$DB_ACCESSION$", "TestDB");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ // Url initially as input in link
+ Assert.assertEquals(u.getUrl(), "http://identifiers.org/$DB_ACCESSION$");
+
+ // Setting updates url
+ u.setUrl("http://something.new/$SEQUENCE_ID$");
+ Assert.assertEquals(u.getUrl(), "http://something.new/$SEQUENCE_ID$");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetSetValue()
+ {
+ UrlLink link = new UrlLink("Test Name",
+ "http://identifiers.org/$DB_ACCESSION$", "TestDB");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ Assert.assertFalse((boolean) u.getValue(UrlLinkDisplay.PRIMARY));
+ Assert.assertFalse((boolean) u.getValue(UrlLinkDisplay.SELECTED));
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.DATABASE), "TestDB");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.NAME), "Test Name");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.ID), "Test");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.URL),
+ "http://identifiers.org/$DB_ACCESSION$");
+
+ u.setValue(UrlLinkDisplay.PRIMARY, true);
+ Assert.assertTrue((boolean) u.getValue(UrlLinkDisplay.PRIMARY));
+
+ u.setValue(UrlLinkDisplay.SELECTED, true);
+ Assert.assertTrue((boolean) u.getValue(UrlLinkDisplay.SELECTED));
+
+ u.setValue(UrlLinkDisplay.NAME, "New Desc");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.NAME), "New Desc");
+
+ u.setValue(UrlLinkDisplay.DATABASE, "NewName");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.DATABASE), "NewName");
+
+ u.setValue(UrlLinkDisplay.ID, "New ID");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.ID), "New ID");
+
+ u.setValue(UrlLinkDisplay.URL, "http://something.new/$SEQUENCE_ID$");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.URL),
+ "http://something.new/$SEQUENCE_ID$");
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import static jalview.util.UrlConstants.DELIM;
+import static jalview.util.UrlConstants.SEP;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.util.MessageManager;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.event.TableModelListener;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class UrlLinkTableModelTest {
+
+ private static final String inmenu = "TEST|http://someurl.blah/$DB_ACCESSION$|"
+ + "ANOTHER|http://test/t$SEQUENCE_ID$|"
+ + "TEST2|http://address/$SEQUENCE_ID$|SRS|"
+ + "http://theSRSlink/$SEQUENCE_ID$|"
+ + "MIR:00000005|MIR:00000011|MIR:00000372";
+
+ private static final String notinmenu = "Not1|http://not.in.menu/$DB_ACCESSION$|"
+ + "Not2|http://not.in.menu.either/$DB_ACCESSION$";
+
+ private static final String testIdOrgString = "{\"Local\": [{\"id\":\"MIR:00000002\",\"name\":\"ChEBI\",\"pattern\":\"^CHEBI:\\d+$\","
+ + "\"definition\":\"Chemical Entities of Biological Interest (ChEBI)\",\"prefix\":\"chebi\","
+ + "\"url\":\"http://identifiers.org/chebi\"},{\"id\":\"MIR:00000005\",\"name\":\"UniProt Knowledgebase\","
+ + "\"pattern\":\"^([A-N,R-Z][0-9]([A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(\\.\\d+)?$\","
+ + "\"definition\":\"The UniProt Knowledgebase (UniProtKB)\",\"prefix\":\"uniprot\",\"url\":\"http://identifiers.org/uniprot\"},"
+ + "{\"id\":\"MIR:00000011\",\"name\":\"InterPro\",\"pattern\":\"^IPR\\d{6}$\",\"definition\":\"InterPro\",\"prefix\":\"interpro\","
+ + "\"url\":\"http://identifiers.org/interpro\"},"
+ + "{\"id\":\"MIR:00000372\",\"name\":\"ENA\",\"pattern\":\"^[A-Z]+[0-9]+(\\.\\d+)?$\",\"definition\":\"The European Nucleotide Archive (ENA),\""
+ + "\"prefix\":\"ena.embl\",\"url\":\"http://identifiers.org/ena.embl\"}]}";
+
+ private UrlProviderI prov;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setup()
+ {
+ // set up UrlProvider data as the source for the TableModel
+ // the data gets updated by the TableModel, so needs to be reinitialised for
+ // each test
+
+ // make a dummy identifiers.org download file
+ File temp = null;
+ try
+ {
+ temp = File.createTempFile("tempfile", ".tmp");
+ temp.deleteOnExit();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
+ bw.write(testIdOrgString);
+ bw.close();
+ } catch (IOException e)
+ {
+ System.out.println("Error initialising UrlLinkTableModel test: "
+ + e.getMessage());
+ }
+
+ // set up custom and identifiers.org url providers
+ IdOrgSettings.setDownloadLocation(temp.getPath());
+ IdentifiersUrlProvider idprov = new IdentifiersUrlProvider(inmenu);
+ CustomUrlProvider cprov = new CustomUrlProvider(inmenu, notinmenu);
+ List<UrlProviderI> provlist = new ArrayList<UrlProviderI>();
+ provlist.add(idprov);
+ provlist.add(cprov);
+
+ prov = new UrlProvider("TEST2", provlist);
+ }
+
+ /*
+ * Test that the table model is correctly initialised
+ * Display columns and default row are set; data provider listening event set up
+ */
+ @Test(groups = { "Functional" })
+ public void testInitialisation()
+ {
+ int defaultCol = 4;
+ int dbCol = 0;
+ int descCol = 1;
+
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // exactly one table model listener
+ TableModelListener[] listeners = m
+ .getListeners(TableModelListener.class);
+ Assert.assertEquals(listeners.length, 1);
+
+ // default row exists, there is exactly 1, and it matches the supplied
+ // default
+ int count = 0;
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ boolean isDefault = (boolean) m.getValueAt(row, defaultCol);
+ if (isDefault)
+ {
+ count++;
+ String defaultDBName = (String) m.getValueAt(row, dbCol);
+ Assert.assertEquals(defaultDBName, "TEST2");
+
+ String defaultDesc = (String) m.getValueAt(row, descCol);
+ Assert.assertEquals(defaultDesc, "TEST2");
+ }
+ }
+ Assert.assertEquals(count, 1);
+ }
+
+ /*
+ * Test row and column counts
+ */
+ @Test(groups = { "Functional" })
+ public void testCounts()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // correct numbers of column and rows
+ Assert.assertEquals(m.getColumnCount(), 5);
+ Assert.assertEquals(m.getRowCount(), 10);
+ }
+
+ /*
+ * Test column access
+ */
+ @Test(groups = { "Functional" })
+ public void testColumns()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // check column names
+ Assert.assertEquals(m.getColumnName(0),
+ MessageManager.formatMessage("label.database"));
+ Assert.assertEquals(m.getColumnName(1),
+ MessageManager.formatMessage("label.name"));
+ Assert.assertEquals(m.getColumnName(2),
+ MessageManager.formatMessage("label.url"));
+ Assert.assertEquals(m.getColumnName(3),
+ MessageManager.formatMessage("label.inmenu"));
+ Assert.assertEquals(m.getColumnName(4),
+ MessageManager.formatMessage("label.primary"));
+
+ // check column classes
+ Assert.assertEquals(m.getColumnClass(0), String.class);
+ Assert.assertEquals(m.getColumnClass(1), String.class);
+ Assert.assertEquals(m.getColumnClass(2), String.class);
+ Assert.assertEquals(m.getColumnClass(3), Boolean.class);
+ Assert.assertEquals(m.getColumnClass(4), Boolean.class);
+ }
+
+ /*
+ * Test row insertion
+ */
+ @Test(groups = { "Functional" })
+ public void testRowInsert()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ m.insertRow("newname", "newurl");
+
+ // check table has new row inserted
+ Assert.assertEquals(m.getValueAt(10, 0), "newname");
+ Assert.assertEquals(m.getValueAt(10, 1), "newname");
+ Assert.assertEquals(m.getValueAt(10, 2), "newurl");
+ Assert.assertEquals(m.getValueAt(10, 3), true);
+ Assert.assertEquals(m.getValueAt(10, 4), false);
+
+ // check data source has new row insrte
+ Assert.assertTrue(prov.getLinksForMenu().contains(
+ "newname" + SEP + "newurl"));
+ }
+
+ /*
+ * Test row deletion
+ */
+ @Test(groups = { "Functional" })
+ public void testRowDelete()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // get name and url at row 0
+ String name = (String) m.getValueAt(0, 0);
+ String url = (String) m.getValueAt(0, 1);
+
+ m.removeRow(0);
+
+ // check table no longer has row 0 elements in it
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ Assert.assertNotEquals(m.getValueAt(row, 0), name);
+ }
+
+ // check data source likewise
+ Assert.assertFalse(prov.getLinksForMenu().contains(name + SEP + url));
+ }
+
+ /*
+ * Test value setting and getting
+ */
+ @Test(groups = { "Functional" })
+ public void testValues()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // get original default
+ int olddefault;
+ boolean isDefault = false;
+ for (olddefault = 0; olddefault < m.getRowCount() && !isDefault; olddefault++)
+ {
+ isDefault = (boolean) m.getValueAt(olddefault, 3);
+ }
+
+ // set new values, one in each row
+ m.setValueAt("dbnamechanged", 6, 0);
+ m.setValueAt("descchanged", 6, 1);
+ m.setValueAt("urlchanged", 7, 2);
+ m.setValueAt(false, 8, 3);
+ m.setValueAt(true, 6, 4);
+
+ m.setValueAt("dbnamechanged", 5, 0);
+
+ // check values updated in table
+ Assert.assertEquals(m.getValueAt(6, 0), "descchanged"); // custom url can't
+ // change db name
+ Assert.assertEquals(m.getValueAt(6, 1), "descchanged");
+ Assert.assertEquals(m.getValueAt(7, 2), "urlchanged");
+ Assert.assertFalse((boolean) m.getValueAt(8, 3));
+ Assert.assertTrue((boolean) m.getValueAt(6, 4));
+ Assert.assertFalse((boolean) m.getValueAt(olddefault, 4));
+
+ Assert.assertEquals(m.getValueAt(5, 0), "dbnamechanged");
+
+ // check default row is exactly one row still
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ isDefault = (boolean) m.getValueAt(row, 4);
+
+ // if isDefault is true, row is 9
+ // if isDefault is false, row is not 9
+ Assert.assertFalse(isDefault && !(row == 6));
+ }
+
+ // check table updated
+ Assert.assertTrue(prov.writeUrlsAsString(true).contains(
+ "descchanged" + SEP + m.getValueAt(6, 2)));
+ Assert.assertTrue(prov.writeUrlsAsString(true).contains(
+ m.getValueAt(7, 1) + SEP + "urlchanged"));
+ Assert.assertTrue(prov.writeUrlsAsString(false).contains(
+ (String) m.getValueAt(8, 1)));
+ Assert.assertEquals(prov.getPrimaryUrl("seqid"), m.getValueAt(6, 2)
+ .toString().replace(DELIM + SEQUENCE_ID + DELIM, "seqid"));
+ }
+
+ /*
+ * Test cell editability
+ */
+ @Test(groups = { "Functional" })
+ public void testEditable()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ Assert.assertFalse(m.isCellEditable(row, 0));
+ Assert.assertFalse(m.isCellEditable(row, 1));
+ Assert.assertFalse(m.isCellEditable(row, 2));
+ Assert.assertTrue(m.isCellEditable(row, 3));
+
+ if ((row == 4) || (row == 6) || (row == 7))
+ {
+ Assert.assertTrue(m.isCellEditable(row, 4));
+ }
+ else
+ {
+ Assert.assertFalse(m.isCellEditable(row, 4));
+ }
+ }
+ }
+
+ /*
+ * Test row 'deletability'
+ */
+ @Test(groups = { "Functional" })
+ public void testDeletable()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ if (row > 4)
+ {
+ Assert.assertTrue(m.isRowDeletable(row));
+ }
+ else
+ {
+ Assert.assertFalse(m.isRowDeletable(row));
+ }
+ }
+ }
+
+ /*
+ * Test indirect row editability
+ */
+ @Test(groups = { "Functional" })
+ public void testRowEditable()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ if (row > 3)
+ {
+ Assert.assertTrue(m.isRowEditable(row));
+ }
+ else
+ {
+ Assert.assertFalse(m.isRowEditable(row));
+ }
+ }
+ }
+}
--- /dev/null
+package jalview.urls;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.desktop.DesktopUrlProviderFactory;
+import jalview.util.UrlConstants;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+
+public class UrlProviderTest {
+
+ // Test identifiers.org download file
+ private static final String testIdOrgString = "{\"Local\": [{\"id\":\"MIR:00000002\",\"name\":\"ChEBI\",\"pattern\":\"^CHEBI:\\d+$\","
+ + "\"definition\":\"Chemical Entities of Biological Interest (ChEBI)\",\"prefix\":\"chebi\","
+ + "\"url\":\"http://identifiers.org/chebi\"},{\"id\":\"MIR:00000005\",\"name\":\"UniProt Knowledgebase\","
+ + "\"pattern\":\"^([A-N,R-Z][0-9]([A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(\\.\\d+)?$\","
+ + "\"definition\":\"The UniProt Knowledgebase (UniProtKB)\",\"prefix\":\"uniprot\",\"url\":\"http://identifiers.org/uniprot\"},"
+ + "{\"id\":\"MIR:00000011\",\"name\":\"InterPro\",\"pattern\":\"^IPR\\d{6}$\",\"definition\":\"InterPro\",\"prefix\":\"interpro\","
+ + "\"url\":\"http://identifiers.org/interpro\"},"
+ + "{\"id\":\"MIR:00000372\",\"name\":\"ENA\",\"pattern\":\"^[A-Z]+[0-9]+(\\.\\d+)?$\",\"definition\":\"The European Nucleotide Archive (ENA),\""
+ + "\"prefix\":\"ena.embl\",\"url\":\"http://identifiers.org/ena.embl\"}]}";
+
+ private UrlProviderI prov;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setup()
+ {
+ // make a dummy identifiers.org download file
+ File temp = null;
+
+ try
+ {
+ temp = File.createTempFile("tempfile", ".tmp");
+ temp.deleteOnExit();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
+ bw.write(testIdOrgString);
+ bw.close();
+ } catch (IOException e)
+ {
+ System.out.println("Error initialising UrlProviderTest test: "
+ + e.getMessage());
+ }
+
+ IdOrgSettings.setDownloadLocation(temp.getPath());
+
+ String defaultUrlString = "No default";
+ String cachedUrlList = "MIR:00000005|MIR:00000011|Test1|http://blah.blah/$SEQUENCE_ID$|"
+ + "Test2|http://test2/$DB_ACCESSION$|Test3|http://test3/$SEQUENCE_ID$";
+ String userUrlList = "MIR:00000372|Test4|httpL//another.url/$SEQUENCE_ID$";
+
+ DesktopUrlProviderFactory factory = new DesktopUrlProviderFactory(
+ defaultUrlString, cachedUrlList, userUrlList);
+ prov = factory.createUrlProvider();
+ }
+
+ @Test(groups = { "Functional" })
+ public void testInitUrlProvider()
+ {
+ String emblUrl = UrlConstants.DEFAULT_STRING.substring(
+ UrlConstants.DEFAULT_STRING.indexOf(UrlConstants.SEP) + 1,
+ UrlConstants.DEFAULT_STRING.length());
+
+ // chooses EMBL url when default Url id does not exist in provided url lists
+ Assert.assertEquals(prov.getPrimaryUrlId(), UrlConstants.DEFAULT_LABEL);
+ Assert.assertEquals(prov.getPrimaryUrl("FER_CAPAN"),
+ emblUrl.replace("$SEQUENCE_ID$", "FER_CAPAN"));
+
+ List<String> menulinks = prov.getLinksForMenu();
+ List<UrlLinkDisplay> allLinks = prov.getLinksForTable();
+
+ // 9 links in provider - 4 from id file, 4 custom links, 1 additional
+ // default
+ Assert.assertEquals(allLinks.size(), 9);
+
+ // 6 links in menu (cachedUrlList) + new default
+ Assert.assertEquals(menulinks.size(), 6);
+
+ Assert.assertTrue(menulinks
+ .contains("Test1|http://blah.blah/$SEQUENCE_ID$"));
+ Assert.assertTrue(menulinks
+ .contains("Test2|http://test2/$DB_ACCESSION$"));
+ Assert.assertTrue(menulinks
+ .contains("Test3|http://test3/$SEQUENCE_ID$"));
+ Assert.assertTrue(menulinks
+ .contains("UniProt Knowledgebase|http://identifiers.org/uniprot/$DB_ACCESSION$|uniprot"));
+ Assert.assertTrue(menulinks
+ .contains("InterPro|http://identifiers.org/interpro/$DB_ACCESSION$|interpro"));
+ Assert.assertTrue(menulinks.contains(UrlConstants.DEFAULT_LABEL
+ + UrlConstants.SEP + emblUrl));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetDefaultUrl()
+ {
+ // set custom url as default
+ Assert.assertTrue(prov.setPrimaryUrl("Test1"));
+ Assert.assertEquals(prov.getPrimaryUrlId(), "Test1");
+
+ // set identifiers url as default
+ Assert.assertTrue(prov.setPrimaryUrl("MIR:00000011"));
+ Assert.assertEquals(prov.getPrimaryUrlId(), "MIR:00000011");
+ }
+
+ @Test(
+ groups = { "Functional" },
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testSetDefaultUrlWrongly()
+ {
+ // don't allow default to be a non-key
+ prov.setPrimaryUrl("not-a-key");
+ }
+}
assertEquals(new Color(46, 31, 16), // with rounding down
ColorUtils.bleachColour(colour, -0.7f));
}
+
+ @Test(groups = "Functional")
+ public void testParseColourString()
+ {
+ /*
+ * by colour name - if known to AWT, and included in
+ *
+ * @see ColourSchemeProperty.getAWTColorFromName()
+ */
+ assertSame(Color.RED, ColorUtils.parseColourString("red"));
+ assertSame(Color.RED, ColorUtils.parseColourString("Red"));
+ assertSame(Color.RED, ColorUtils.parseColourString(" RED "));
+
+ /*
+ * by RGB hex code
+ */
+ String hexColour = Integer.toHexString(Color.RED.getRGB() & 0xffffff);
+ assertEquals("ff0000", hexColour);
+ assertEquals(Color.RED, ColorUtils.parseColourString(hexColour));
+ // 'hex' prefixes _not_ wanted here
+ assertNull(ColorUtils.parseColourString("0x" + hexColour));
+ assertNull(ColorUtils.parseColourString("#" + hexColour));
+ // out of range, but Color constructor just or's the rgb value with 0
+ assertEquals(Color.black, ColorUtils.parseColourString("1000000"));
+
+ /*
+ * by RGB triplet
+ */
+ Color c = Color.pink;
+ String rgb = String.format("%d,%d,%d", c.getRed(), c.getGreen(),
+ c.getBlue());
+ assertEquals("255,175,175", rgb);
+ assertEquals(c, ColorUtils.parseColourString(rgb));
+ assertEquals(c, ColorUtils.parseColourString("255, 175 , 175"));
+
+ /*
+ * odds and ends
+ */
+ assertNull(ColorUtils.parseColourString(null));
+ assertNull(ColorUtils.parseColourString("rubbish"));
+ assertEquals(Color.WHITE, ColorUtils.parseColourString("-1"));
+ assertNull(ColorUtils.parseColourString(String
+ .valueOf(Integer.MAX_VALUE)));
+ assertNull(ColorUtils.parseColourString("100,200,300")); // out of range
+ assertNull(ColorUtils.parseColourString("100,200")); // too few
+ assertNull(ColorUtils.parseColourString("100,200,100,200")); // too many
+ }
+
+ @Test(groups = "Functional")
+ public void testGetAWTColorFromName() {
+ assertEquals(Color.white, ColorUtils.getAWTColorFromName("white"));
+ assertEquals(Color.white, ColorUtils.getAWTColorFromName("White"));
+ assertEquals(Color.white, ColorUtils.getAWTColorFromName("WHITE"));
+ assertEquals(Color.pink, ColorUtils.getAWTColorFromName("pink"));
+ assertNull(ColorUtils.getAWTColorFromName("mauve")); // no such name
+ assertNull(ColorUtils.getAWTColorFromName(""));
+ assertNull(ColorUtils.getAWTColorFromName(null));
+ }
+
+ @Test(groups = "Functional")
+ public void testCreateColourFromName()
+ {
+ assertEquals(Color.white, ColorUtils.createColourFromName(null));
+ assertEquals(new Color(20, 20, 20), ColorUtils.createColourFromName(""));
+ assertEquals(new Color(98, 131, 171),
+ ColorUtils.createColourFromName("None")); // no special treatment!
+ assertEquals(new Color(123, 211, 122),
+ ColorUtils.createColourFromName("hello world"));
+ assertEquals(new Color(27, 147, 112),
+ ColorUtils.createColourFromName("HELLO WORLD"));
+ /*
+ * the algorithm makes the same values for r,g,b if
+ * the string consists of 3 repeating substrings
+ */
+ assertEquals(new Color(184, 184, 184),
+ ColorUtils.createColourFromName("HELLO HELLO HELLO "));
+ }
}
package jalview.util;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
import jalview.gui.JvOptionPane;
assertEquals(Format.repeat('b', 0), "");
assertEquals(Format.repeat('c', -1), "");
}
+
+ @Test(groups = "Functional")
+ public void testFormat_scientific()
+ {
+ Format f = new Format("%3.4e");
+ double d = 1d;
+ assertEquals(f.form(d), "1.0000e+000");
+ assertEquals(String.format("%3.4e", d), "1.0000e+00");
+
+ d = 12345678.12345678d;
+ assertEquals(f.form(d), "1.2346e+007");
+ assertEquals(String.format("%3.4e", d), "1.2346e+07");
+ }
+
+ /**
+ * Test that fails (in 2.10.1) with timeout as there is an infinite loop in
+ * Format.exp_format()
+ */
+ @Test(groups = "Functional", timeOut = 500)
+ public void testFormat_scientific_overflow()
+ {
+ Format f = new Format("%3.4e");
+ double d = 1.12E-310;
+ /*
+ * problem: exp_format() scales up 'd' to the range 1-10
+ * while computing a scaling factor, but this factor acquires
+ * the value Double.POSITIVE_INFINITY instead of 1.0E+309
+ * the value to be formatted is multipled by factor and becomes Infinity
+ * resulting in an infinite loop in the recursive call to exp_format()
+ */
+ assertEquals(f.form(d), "1.1200e-310");
+ }
+
+ /**
+ * This test shows that Format.form() is faster for this case than
+ * String.format()
+ */
+ @Test(groups = "Timing")
+ public void testFormat_scientificTiming()
+ {
+ Format f = new Format("%3.4e");
+ double d = 12345678.12345678d;
+
+ int iterations = 1000;
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < iterations; i++)
+ {
+ f.form(d);
+ }
+ long stop = System.currentTimeMillis();
+ long elapsed1 = stop - start;
+ System.out.println(iterations + " x Format.form took " + elapsed1
+ + "ms");
+
+ start = System.currentTimeMillis();
+ for (int i = 0; i < iterations; i++)
+ {
+ String.format("%3.4e", d);
+ }
+ stop = System.currentTimeMillis();
+ long elapsed2 = stop - start;
+ System.out.println(iterations + " x String.format took " + elapsed2
+ + "ms");
+ assertTrue(elapsed2 > elapsed1);
+ }
}
+ DELIM + URL_SUFFIX);
assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
- assertEquals(URL_PREFIX, ul.getUrl_prefix());
- assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertEquals(URL_PREFIX, ul.getUrlPrefix());
+ assertEquals(URL_SUFFIX, ul.getUrlSuffix());
assertTrue(ul.isDynamic());
assertFalse(ul.usesDBAccession());
assertNull(ul.getRegexReplace());
+ URL_SUFFIX);
assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
- assertEquals(URL_PREFIX, ul.getUrl_prefix());
- assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertEquals(URL_PREFIX, ul.getUrlPrefix());
+ assertEquals(URL_SUFFIX, ul.getUrlSuffix());
assertTrue(ul.isDynamic());
assertTrue(ul.usesDBAccession());
assertNull(ul.getRegexReplace());
ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX.substring(1));
assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
- assertEquals(URL_PREFIX + URL_SUFFIX.substring(1), ul.getUrl_prefix());
+ assertEquals(URL_PREFIX + URL_SUFFIX.substring(1), ul.getUrlPrefix());
assertFalse(ul.isDynamic());
assertFalse(ul.usesDBAccession());
assertNull(ul.getRegexReplace());
+ REGEX_NESTED + DELIM + URL_SUFFIX);
assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
- assertEquals(URL_PREFIX, ul.getUrl_prefix());
- assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertEquals(URL_PREFIX, ul.getUrlPrefix());
+ assertEquals(URL_SUFFIX, ul.getUrlSuffix());
assertTrue(ul.isDynamic());
assertFalse(ul.usesDBAccession());
assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
+ REGEX_NESTED + DELIM + URL_SUFFIX);
assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
- assertEquals(URL_PREFIX, ul.getUrl_prefix());
- assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertEquals(URL_PREFIX, ul.getUrlPrefix());
+ assertEquals(URL_SUFFIX, ul.getUrlSuffix());
assertTrue(ul.isDynamic());
assertTrue(ul.usesDBAccession());
assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
+ REGEX_RUBBISH + DELIM + URL_SUFFIX);
assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
- assertEquals(URL_PREFIX, ul.getUrl_prefix());
- assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertEquals(URL_PREFIX, ul.getUrlPrefix());
+ assertEquals(URL_SUFFIX, ul.getUrlSuffix());
assertTrue(ul.isDynamic());
assertTrue(ul.usesDBAccession());
assertEquals(REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2),
String key = DB + SEP + URL_PREFIX;
assertEquals(1, linkset.size());
assertTrue(linkset.containsKey(key));
- assertEquals(linkset.get(key).get(0), DB);
- assertEquals(linkset.get(key).get(1), DB);
- assertEquals(linkset.get(key).get(2), null);
- assertEquals(linkset.get(key).get(3), URL_PREFIX);
+ assertEquals(DB, linkset.get(key).get(0));
+ assertEquals(DB, linkset.get(key).get(1));
+ assertEquals(null, linkset.get(key).get(2));
+ assertEquals(URL_PREFIX, linkset.get(key).get(3));
}
/**
String key = DB + SEP + URL_PREFIX + URL_SUFFIX;
assertEquals(1, linkset.size());
assertTrue(linkset.containsKey(key));
- assertEquals(linkset.get(key).get(0), DB);
- assertEquals(linkset.get(key).get(1), DB);
- assertEquals(linkset.get(key).get(2), null);
- assertEquals(linkset.get(key).get(3), URL_PREFIX + URL_SUFFIX);
+ assertEquals(DB, linkset.get(key).get(0));
+ assertEquals(DB, linkset.get(key).get(1));
+ assertEquals(null, linkset.get(key).get(2));
+ assertEquals(URL_PREFIX + URL_SUFFIX, linkset.get(key).get(3));
}
/**
+ URL_SUFFIX;
assertEquals(1, linkset.size());
assertTrue(linkset.containsKey(key));
- assertEquals(linkset.get(key).get(0), DB);
- assertEquals(linkset.get(key).get(1), DB);
- assertEquals(linkset.get(key).get(2), seq0.getName());
- assertEquals(linkset.get(key).get(3), URL_PREFIX + seq0.getName()
- + URL_SUFFIX);
+ assertEquals(DB, linkset.get(key).get(0));
+ assertEquals(DB, linkset.get(key).get(1));
+ assertEquals(seq0.getName(), linkset.get(key).get(2));
+ assertEquals(URL_PREFIX + seq0.getName() + URL_SUFFIX, linkset.get(key)
+ .get(3));
// Test where link takes a db annotation id and only has one dbref
ul = new UrlLink(links.get(1));
ul.createLinksFromSeq(seq0, linkset);
key = "P83527|http://www.uniprot.org/uniprot/P83527";
- assertEquals(1, linkset.size());
+ assertEquals(linkset.size(), 1);
assertTrue(linkset.containsKey(key));
- assertEquals(linkset.get(key).get(0), DBRefSource.UNIPROT);
- assertEquals(linkset.get(key).get(1), DBRefSource.UNIPROT + SEP
- + "P83527");
- assertEquals(linkset.get(key).get(2), "P83527");
- assertEquals(linkset.get(key).get(3),
- "http://www.uniprot.org/uniprot/P83527");
+ assertEquals(DBRefSource.UNIPROT, linkset.get(key).get(0));
+ assertEquals(DBRefSource.UNIPROT + SEP + "P83527", linkset.get(key)
+ .get(1));
+ assertEquals("P83527", linkset.get(key).get(2));
+ assertEquals("http://www.uniprot.org/uniprot/P83527", linkset.get(key)
+ .get(3));
// Test where link takes a db annotation id and has multiple dbrefs
ul = new UrlLink(links.get(2));
// check each link made it in correctly
key = "IPR001041|http://www.ebi.ac.uk/interpro/entry/IPR001041";
assertTrue(linkset.containsKey(key));
- assertEquals(linkset.get(key).get(0), "INTERPRO");
- assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR001041");
- assertEquals(linkset.get(key).get(2), "IPR001041");
- assertEquals(linkset.get(key).get(3),
- "http://www.ebi.ac.uk/interpro/entry/IPR001041");
+ assertEquals("INTERPRO", linkset.get(key).get(0));
+ assertEquals("INTERPRO" + SEP + "IPR001041", linkset.get(key).get(1));
+ assertEquals("IPR001041", linkset.get(key).get(2));
+ assertEquals("http://www.ebi.ac.uk/interpro/entry/IPR001041", linkset
+ .get(key).get(3));
key = "IPR006058|http://www.ebi.ac.uk/interpro/entry/IPR006058";
assertTrue(linkset.containsKey(key));
- assertEquals(linkset.get(key).get(0), "INTERPRO");
- assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR006058");
- assertEquals(linkset.get(key).get(2), "IPR006058");
- assertEquals(linkset.get(key).get(3),
- "http://www.ebi.ac.uk/interpro/entry/IPR006058");
+ assertEquals("INTERPRO", linkset.get(key).get(0));
+ assertEquals("INTERPRO" + SEP + "IPR006058", linkset.get(key).get(1));
+ assertEquals("IPR006058", linkset.get(key).get(2));
+ assertEquals("http://www.ebi.ac.uk/interpro/entry/IPR006058", linkset
+ .get(key).get(3));
key = "IPR012675|http://www.ebi.ac.uk/interpro/entry/IPR012675";
assertTrue(linkset.containsKey(key));
- assertEquals(linkset.get(key).get(0), "INTERPRO");
- assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR012675");
- assertEquals(linkset.get(key).get(2), "IPR012675");
- assertEquals(linkset.get(key).get(3),
- "http://www.ebi.ac.uk/interpro/entry/IPR012675");
+ assertEquals("INTERPRO", linkset.get(key).get(0));
+ assertEquals("INTERPRO" + SEP + "IPR012675", linkset.get(key).get(1));
+ assertEquals("IPR012675", linkset.get(key).get(2));
+ assertEquals("http://www.ebi.ac.uk/interpro/entry/IPR012675", linkset
+ .get(key).get(3));
// Test where there are no matching dbrefs for the link
ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
assertTrue(linkset.isEmpty());
}
+ /**
+ * Test links where label and target are both included
+ */
+ @Test(groups = { "Functional" })
+ public void testLinksWithTargets()
+ {
+ UrlLink ul = new UrlLink(
+ "Protein Data Bank | http://www.identifiers.org/pdb/$"
+ + DB_ACCESSION + "$" + " | pdb");
+
+ assertEquals("Protein Data Bank", ul.getLabel());
+ assertEquals("pdb", ul.getTarget());
+ assertEquals("http://www.identifiers.org/pdb/$" + DB_ACCESSION + "$",
+ ul.getUrlWithToken());
+
+ assertEquals("Protein Data Bank|http://www.identifiers.org/pdb/$"
+ + DB_ACCESSION + "$" + "|pdb", ul.toStringWithTarget());
+
+ ul = new UrlLink("Protein Data Bank",
+ "http://www.identifiers.org/pdb/$" + DB_ACCESSION + "$", "pdb");
+
+ assertEquals("Protein Data Bank", ul.getLabel());
+ assertEquals("pdb", ul.getTarget());
+ assertEquals("http://www.identifiers.org/pdb/$" + DB_ACCESSION + "$",
+ ul.getUrlWithToken());
+
+ assertEquals("Protein Data Bank|http://www.identifiers.org/pdb/$"
+ + DB_ACCESSION + "$" + "|pdb", ul.toStringWithTarget());
+
+ }
+
}
{
try
{
- String aligfileout = FileFormat.Pfam.getAlignmentFile().print(
+ String aligfileout = FileFormat.Pfam.getWriter(al).print(
al.getSequencesArray(), true);
String anfileout = new AnnotationFile()
.printAnnotationsForAlignment(al);
try
{
// what format would be appropriate for RNAalifold annotations?
- String aligfileout = FileFormat.Pfam.getAlignmentFile().print(
+ String aligfileout = FileFormat.Pfam.getWriter(null).print(
al.getSequencesArray(), true);
String anfileout = new AnnotationFile()
try
{
// what format would be appropriate for RNAalifold annotations?
- String aligfileout = FileFormat.Pfam.getAlignmentFile().print(
+ String aligfileout = FileFormat.Pfam.getWriter(null).print(
al.getSequencesArray(), true);
String anfileout = new AnnotationFile()
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ws.utils;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class UrlDownloadClientTest {
+
+ /**
+ * Test that url is successfully loaded into download file
+ */
+ @Test(groups = { "Network" }, enabled = true)
+ public void UrlDownloadTest()
+ {
+ UrlDownloadClient client = new UrlDownloadClient();
+ String urlstring = "http://identifiers.org/rest/collections/";
+ String outfile = "testfile.tmp";
+
+ try
+ {
+ client.download(urlstring, outfile);
+ } catch (IOException e)
+ {
+ Assert.fail("Exception was thrown from UrlDownloadClient download: "
+ + e.getMessage());
+ File f = new File(outfile);
+ if (f.exists())
+ {
+ f.delete();
+ }
+ }
+
+ // download file exists
+ File f = new File(outfile);
+ Assert.assertTrue(f.exists());
+
+ // download file has a believable size
+ // identifiers.org file typically at least 250K
+ Assert.assertTrue(f.length() > 250000);
+
+ if (f.exists())
+ {
+ f.delete();
+ }
+
+ }
+
+ /**
+ * Test that garbage in results in IOException
+ */
+ @Test(
+ groups = { "Network" },
+ enabled = true,
+ expectedExceptions = { IOException.class })
+ public void DownloadGarbageUrlTest() throws IOException
+ {
+ UrlDownloadClient client = new UrlDownloadClient();
+ String urlstring = "identifiers.org/rest/collections/";
+ String outfile = "testfile.tmp";
+
+ client.download(urlstring, outfile);
+ }
+}