--- /dev/null
+ATOM 7013 N ALA A 650 -32.039 -14.559 -3.977 1.00 97.16 N
+ATOM 7014 CA ALA A 650 -33.253 -15.372 -3.971 1.00101.29 C
+ATOM 7015 C ALA A 650 -32.928 -16.865 -4.014 1.00102.48 C
+ATOM 7016 O ALA A 650 -33.833 -17.704 -4.075 1.00102.31 O
+ATOM 7017 CB ALA A 650 -34.168 -14.987 -5.138 1.00 94.98 C
+ATOM 7018 N MET A 651 -31.636 -17.186 -3.978 1.00 98.86 N
+ATOM 7019 CA MET A 651 -31.164 -18.568 -4.040 1.00 95.81 C
+ATOM 7020 C MET A 651 -29.680 -18.618 -3.678 1.00 95.69 C
+ATOM 7021 O MET A 651 -28.847 -18.030 -4.367 1.00 93.27 O
+ATOM 7022 CB MET A 651 -31.414 -19.157 -5.435 1.00 94.70 C
+ATOM 7023 CG MET A 651 -31.097 -18.189 -6.581 1.00 93.74 C
+ATOM 7024 SD MET A 651 -31.780 -18.651 -8.198 1.00 87.88 S
+ATOM 7025 CE MET A 651 -30.854 -20.142 -8.594 1.00 81.80 C
+ATOM 7026 N LYS A 652 -29.355 -19.313 -2.589 1.00 95.36 N
+ATOM 7027 CA LYS A 652 -27.982 -19.355 -2.075 1.00 88.97 C
+ATOM 7028 C LYS A 652 -27.021 -20.133 -2.984 1.00 89.03 C
+ATOM 7029 O LYS A 652 -27.393 -21.143 -3.592 1.00 90.36 O
+ATOM 7030 CB LYS A 652 -27.953 -19.930 -0.656 1.00 85.99 C
+ATOM 7031 N ARG A 653 -25.784 -19.655 -3.070 1.00 83.57 N
+ATOM 7032 CA ARG A 653 -24.765 -20.305 -3.888 1.00 82.09 C
+ATOM 7033 C ARG A 653 -23.704 -20.963 -3.017 1.00 79.82 C
+ATOM 7034 O ARG A 653 -23.327 -20.431 -1.977 1.00 79.58 O
+ATOM 7035 CB ARG A 653 -24.115 -19.291 -4.831 1.00 84.10 C
+ATOM 7036 CG ARG A 653 -23.554 -18.068 -4.129 1.00 82.91 C
+ATOM 7037 CD ARG A 653 -23.098 -17.010 -5.124 1.00 84.28 C
+ATOM 7038 NE ARG A 653 -23.064 -15.675 -4.527 1.00 83.48 N
+ATOM 7039 CZ ARG A 653 -21.959 -15.047 -4.134 1.00 82.34 C
+ATOM 7040 NH1 ARG A 653 -20.770 -15.621 -4.277 1.00 80.52 N
+ATOM 7041 NH2 ARG A 653 -22.045 -13.836 -3.602 1.00 84.76 N
+ATOM 7042 N ARG A 654 -23.219 -22.122 -3.446 1.00 83.16 N
+ATOM 7043 CA ARG A 654 -22.263 -22.882 -2.647 1.00 84.47 C
+ATOM 7044 C ARG A 654 -20.845 -22.831 -3.207 1.00 82.72 C
+ATOM 7045 O ARG A 654 -20.611 -22.306 -4.294 1.00 84.47 O
+ATOM 7046 CB ARG A 654 -22.720 -24.337 -2.500 1.00 86.90 C
+ATOM 7047 CG ARG A 654 -22.700 -25.156 -3.785 1.00 90.62 C
+ATOM 7048 CD ARG A 654 -21.792 -26.372 -3.625 1.00 94.56 C
+ATOM 7049 NE ARG A 654 -22.296 -27.559 -4.313 1.00100.64 N
+ATOM 7050 CZ ARG A 654 -21.755 -28.770 -4.203 1.00101.77 C
+ATOM 7051 NH1 ARG A 654 -20.690 -28.949 -3.433 1.00 99.43 N
+ATOM 7052 NH2 ARG A 654 -22.277 -29.803 -4.858 1.00103.21 N
+ATOM 7053 N ARG A 655 -19.901 -23.377 -2.452 1.00 80.06 N
+ATOM 7054 CA ARG A 655 -18.522 -23.461 -2.899 1.00 81.57 C
+ATOM 7055 C ARG A 655 -18.393 -24.576 -3.925 1.00 85.28 C
+ATOM 7056 O ARG A 655 -19.120 -25.567 -3.865 1.00 87.19 O
+ATOM 7057 CB ARG A 655 -17.617 -23.772 -1.718 1.00 83.19 C
+ATOM 7058 CG ARG A 655 -17.720 -25.217 -1.265 1.00 86.49 C
+ATOM 7059 CD ARG A 655 -17.099 -25.402 0.093 1.00 85.01 C
+ATOM 7060 NE ARG A 655 -15.880 -24.617 0.223 1.00 85.24 N
+ATOM 7061 CZ ARG A 655 -15.123 -24.608 1.310 1.00 87.53 C
+ATOM 7062 NH1 ARG A 655 -15.465 -25.351 2.354 1.00 87.44 N
+ATOM 7063 NH2 ARG A 655 -14.028 -23.864 1.350 1.00 89.64 N
<p>
The Structure Chooser interface allows you to interactively select
which PDB structures to view for the currently selected set of
- sequences. It's opened by selecting the <strong>"3D
+ sequences. It is opened by selecting the <strong>"3D
Structure Data.."</strong> option from the Sequence ID panel's <a
href="../menus/popupMenu.html">pop-up menu</a>. The dialog
provides:
<li>Association of structure data from a local file (in mmCIF
or PDB format)</li>
</ul>
-
+ <p>
+ <strong>Selecting and Viewing Structures</strong>
+ </p>
+ <p>
+ Once one or more structures have been selected, pressing the <strong>View</strong>
+ button will import them into <a
+ href="viewingpdbs.html#afterviewbutton">a new or existing
+ structure view</a>.
+ </p>
<p>
<strong>Automated discovery of structure data</strong>
</p>
- <p>After selecting "3D Structure Data ..", Jalview queries the PDB
- via the PDBe SOLR Rest API provided by EMBL-EBI to discover PDB ids
+ <p>
+ After selecting "3D Structure Data ..", Jalview queries the PDB via
+ the PDBe SOLR Rest API provided by EMBL-EBI to discover PDB IDs
associated with the sequence. It does this based on the sequence's
- ID string, and any other associated database IDs.</p>
+ ID string, and any other associated database IDs. <br />
+ <br />
<p>
- <strong>Exploration of meta-data for available structures</strong>
+ <strong><a name="cachedstructview">Viewing existing
+ structures for your sequences</a></strong>
+ </p>
+ <p>
+ If you have already loaded 3D structure data for the selected
+ sequences, the structure chooser will first open with the <strong>Cached
+ Structures View</strong>. This view shows associations between each
+ sequence, and chains for 3D structure files already in memory. If
+ you want to download additional structures, select one of the other
+ options from the drop down menu.
</p>
- <p>Information on each structure available is displayed in columns
- in the dialog box. By default, only the title, resolution and PDB
- identifier are shown, but many more are provided by the PDBe. To
- configure which ones are displayed, select the 'Configure Displayed
- Columns' tab and tick the columns which you want to see.</p>
<p>
<strong>Selection of the best structure for each sequence</strong>
</p>
<p>Jalview can automatically select the best structures according
- to meta-data provided by the PDB. By default, the 'Best Quality'
- structure for each sequence will be selected, but clicking on the
- drop down menu allows other criteria to be chosen, including
- Resolution (only defined for X-Ray structures), Highest Protein
- Chain etc. When 'Invert' is selected, structures are selected in
- reverse order for the current criteria (e.g. worst quality rather
- than best).</p>
+ to meta-data provided by the PDB. For alignments with no existing
+ structure data, the 'Best Quality' structure for each sequence will
+ by default be selected, but clicking on the drop down menu allows
+ other criteria to be chosen, including Resolution (only defined for
+ X-Ray structures), Highest Protein Chain etc. When 'Invert' is
+ selected, structures are selected in reverse order for the current
+ criteria (e.g. worst quality rather than best).</p>
<p>
<img src="schooser_main.png" style="width: 464px; height: 369px;">
<p><img src="schooser_cached.png"> -->
<br>The screenshot above shows the Structure Chooser interface
along with the meta-data of auto-discovered structures for the
- sample alignment. Note however that if no structures were
- auto-discovered, a different interface for manual association will
- be invoked as seen in the screenshot below.
+ sample alignment. If no structures were
+ auto-discovered, options for manually associating PDB records will be shown (see below).
+ <p>
+ <strong>Exploration of meta-data for available structures</strong>
+ </p>
+ <p>Information on each structure available is displayed in columns
+ in the dialog box. By default, only the title, resolution and PDB
+ identifier are shown, but many more are provided by the PDBe. To
+ configure which ones are displayed, select the 'Configure Displayed
+ Columns' tab and tick the columns which you want to see.</p>
<p>
<img src="schooser_enter-id.png"
style="width: 464px; height: 369px;">
- <p>
+ <br/>
<strong>Manual selection/association of PDB files with
Sequences</strong>
</p>
for your sequence. The PDB Rest API, provided by EMBL-EBI, is used
to validate and fetch structure data.<br></li>
</ul>
- <p>
- <strong>Viewing existing structures for your sequences</strong>
- </p>
- <p>
- If you have previously associated structure data on the alignment,
- selecting <strong>Cached PDB Entries</strong> from the drop down
- menu allows you to select these structures for display.
- </p>
<p>
<em>The Structure Chooser interface was introduced in Jalview
'highest resolution', simply choose another to pick structures in
a different way.<br />
<ul>
- <li><strong>Viewing Cached Structures</strong><br />If you
- have previously downloaded structures for your sequences, they
- can be viewed by selecting the <strong>Cached PDB
- Entries</strong> option from the drop down menu at the top of the
- dialog box.</li>
+ <li><strong>Viewing Cached Structures</strong><br />If
+ previously downloaded structures are available for your
+ sequences, the structure chooser will automatically offer them
+ via the <strong>Cached PDB Entries</strong> view. If you wish
+ to download new structures, select one of the PDBe selection
+ criteria from the drop-down menu.</li>
</ul></li>
<li><strong>To view selected structures, click the <strong>"View"</strong>
button.
<li><a href="siftsmapping.html">SIFTS</a> records will also
be downloaded for mapping UniProt protein sequence data to PDB
coordinates.</li>
+ <li>A new structure viewer will open, or you will be
+ prompted to add structures to existing viewers (see <a
+ href="#afterviewbutton">below</a> for details).
+ </li>
</ul></li>
</ol>
-
+ <p>
+ <strong>Structure Viewers in the Jalview Desktop</strong><br/>
The
<a href="jmol.html">Jmol viewer</a> has been included since Jalview
2.3. Jalview 2.8.2 included support for
the <a href="xsspannotation.html">Annotation from Structure</a> page
for more information.
</p>
-
<p>
- If a <strong>single</strong> PDB structure is selected, one of the
- following will happen:
+ <strong><a name="afterviewbutton">After pressing the
+ 'View' button in the Structure Chooser</a></strong><br /> The behaviour of
+ the 'View' button depends on the number of structures selected, and
+ whether structure views already exist for the selected structures or
+ aligned sequences.
+ </p>
+ <p>
+ If multiple structures are selected, then Jalview will always create
+ a new structure view. The selected structures will be imported into
+ this view, and superposed with the matched positions from the
+ aligned sequences.<br /> If a <strong>single</strong> PDB structure
+ is selected, one of the following will happen:
</p>
<ul>
<li>If another structure is already shown for the current
alignment, then you will be asked if you want to add and <a
- href="jmol.html#align">align this structure</a> to the structure
- in the existing view. (<em>new feature in Jalview 2.6</em>).
- </li>
+ href="jmol.html#align"></a> to
+ the structure in the existing view. (<em>new feature in Jalview
+ 2.6</em>).
+ </li>
<li>If the structure is already shown, then you will be
prompted to associate the sequence with an existing view of the
<tr>
<td width="60" nowrap>
<div align="center">
+ <strong><a name="Jalview.2.10.0b1">2.10.0b1</a><br />
+ <em>25/10/2016</em></strong>
+ </div>
+ </td>
+ <td><em>Application</em>
+ <ul>
+ <li>3D Structure chooser opens with 'Cached structures' view if structures already loaded</li>
+ </ul></td>
+ <td>
+ <div align="left">
+ <em>Application</em>
+ <ul>
+ <li>Cannot import or associated local PDB files without a PDB ID HEADER line</li>
+ <li>RMSD is not output in Jmol console when superposition is performed</li>
+ <li>Drag and drop of URL from Browser fails for Linux and OSX versions earlier than El Capitan</li>
+ <li>ENA client ignores invalid content from ENA server</li>
+ <li>Exceptions are not raised when ENA client attempts to fetch non-existent IDs via Fetch DB Refs UI option</li>
+ <li>Exceptions are not raised when a new view is created on the alignment</li>
+ </ul>
+ <em>New Known Issues</em>
+ <ul><li>Drag and drop from URL links in browsers do not work on Windows</li></ul>
+ <em>Build and deployment</em>
+ <ul><li>URL link checker now copes with multi-line anchor tags</li></ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td width="60" nowrap>
+ <div align="center">
<strong><a name="Jalview.2.10.0">2.10.0</a><br /> <em>06/10/2016</em></strong>
</div>
</td>
-->
<class name="jalview.datamodel.xdb.embl.EmblFile">
<map-to xml="ROOT"/>
+ <field name="text" type="string">
+ <bind-xml node="text"/>
+ </field>
<field name="entries" type="jalview.datamodel.xdb.embl.EmblEntry" collection="vector">
<bind-xml name="entry"/>
</field>
status.fetching_db_refs = Fetching db refs
status.loading_cached_pdb_entries = Loading Cached PDB Entries
status.searching_for_pdb_structures = Searching for PDB Structures
-status.opening_file = opening file
+status.opening_file_for = opening file for
status.colouring_chimera = Colouring Chimera
label.font_doesnt_have_letters_defined = Font doesn't have letters defined\nso cannot be used\nwith alignment data
label.font_too_small = Font size is too small
label.export_settings=Exportar Ajustes
label.linked_view_title=Vista vinculada de cDNA y proteÃna
label.couldnt_read_data=No se pudo leer los datos
-status.opening_file=abriendo fichero
+status.opening_file_for=abriendo fichero para
label.except_selected_sequences=Todo excepto secuencias seleccionadas
label.structure_chooser_no_of_structures=Selector de Estructuras - {0} Encontró ({1})
label.search_filter=filtro de búsqueda
<class name="jalview.datamodel.PDBEntry">
<field name="type"><bind-xml node="attribute"/></field>
<field name="id"><bind-xml node="attribute"/></field>
- <field name="property" collection="hashtable">
+ <field name="props" collection="hashtable">
<bind-xml name="property">
<class name="org.exolab.castor.mapping.MapItem">
<field name="key">
}
for (int i = 0; i < features.length; i++)
{
- if (features[i].getFeatureGroup().equals(pdbid))
+ if (features[i].getFeatureGroup() != null
+ && features[i].getFeatureGroup().equals(pdbid))
{
SequenceFeature tx = new SequenceFeature(features[i]);
tx.setBegin(1 + residues.elementAt(tx.getBegin() - offset).atoms
worker.start();
}
- if (pdbentry.getProperty() != null)
+ String method = (String) pdbentry.getProperty("method");
+ if (method != null)
{
- if (pdbentry.getProperty().get("method") != null)
- {
- title.append(" Method: ");
- title.append(pdbentry.getProperty().get("method"));
- }
- if (pdbentry.getProperty().get("chains") != null)
- {
- title.append(" Chain:");
- title.append(pdbentry.getProperty().get("chains"));
- }
+ 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);
}
import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
-import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
}
if (needtoadd)
{
- // make a note of the access mode and add
- if (pdbentry.getProperty() == null)
- {
- pdbentry.setProperty(new Hashtable());
- }
- pdbentry.getProperty().put("protocol", protocol);
+ pdbentry.setProperty("protocol", protocol);
toaddpdb.addPDBId(pdbentry);
alignPanel.getStructureSelectionManager()
.registerPDBEntry(pdbentry);
if (protocol == null || protocol.trim().length() == 0
|| protocol.equals("null"))
{
- protocol = (String) pdb.getProperty().get("protocol");
+ protocol = (String) pdb.getProperty("protocol");
if (protocol == null)
{
System.err.println("Couldn't work out protocol to open structure: "
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
-import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
-import org.jmol.util.Logger;
-
public class AppletJmol extends EmbmenuFrame implements
// StructureListener,
KeyListener, ActionListener, ItemListener
jmb.allocateViewer(renderPanel, true, ap.av.applet.getName()
+ "_jmol_", ap.av.applet.getDocumentBase(),
ap.av.applet.getCodeBase(), "-applet", scriptWindow, null);
- Logger.setLogLevel(Logger.LEVEL_WARN);
} catch (Exception e)
{
System.err
closeViewer();
}
});
- if (pdbentry.getProperty() == null)
- {
- pdbentry.setProperty(new Hashtable());
- pdbentry.getProperty().put("protocol", protocol);
- }
+ pdbentry.setProperty("protocol", protocol);
+
if (pdbentry.getFile() != null)
{
// import structure data from pdbentry.getFile based on given protocol
import jalview.util.CaseInsensitiveString;
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.Hashtable;
public class PDBEntry
{
+
+ /**
+ * constant for storing chain code in properties table
+ */
+ private static final String CHAIN_ID = "chain_code";
+
+ private Hashtable<String, Object> properties;
+
private static final int PDB_ID_LENGTH = 4;
private String file;
}
}
- /**
- * constant for storing chain code in properties table
- */
- private static final String CHAIN_ID = "chain_code";
-
- Hashtable properties;
/**
* Answers true if obj is a PDBEntry with the same id and chain code (both
/**
* @param pdbId
* @param chain
- * @param type
+ * @param entryType
* @param filePath
*/
- void init(String pdbId, String chain, PDBEntry.Type type, String filePath)
+ void init(String pdbId, String chain, PDBEntry.Type entryType, String filePath)
{
this.id = pdbId;
- this.type = type == null ? null : type.toString();
+ this.type = entryType == null ? null : entryType.toString();
this.file = filePath;
setChainCode(chain);
}
id = entry.id;
if (entry.properties != null)
{
- properties = (Hashtable) entry.properties.clone();
+ properties = (Hashtable<String, Object>) entry.properties.clone();
}
}
init(pdbId, chainCode, null, null);
}
- public void setFile(String file)
+ public void setFile(String f)
{
- this.file = file;
+ this.file = f;
}
public String getFile()
return id;
}
- public void setProperty(Hashtable property)
+ public void setProperty(String key, Object value)
{
- this.properties = property;
+ if (this.properties == null)
+ {
+ this.properties = new Hashtable<String, Object>();
+ }
+ properties.put(key, value);
}
- public Hashtable getProperty()
+ public Object getProperty(String key)
{
- return properties;
+ return properties == null ? null : properties.get(key);
+ }
+
+ /**
+ * Returns an enumeration of the keys of this object's properties (or an empty
+ * enumeration if it has no properties)
+ *
+ * @return
+ */
+ public Enumeration<String> getProperties()
+ {
+ if (properties == null)
+ {
+ return Collections.emptyEnumeration();
+ }
+ return properties.keys();
}
/**
: properties.get(CHAIN_ID).toString();
}
+ /**
+ * Sets a non-case-sensitive property for the given chain code. Two PDBEntry
+ * objects which differ only in the case of their chain code are considered
+ * equal. This avoids duplication of objects in lists of PDB ids.
+ *
+ * @param chainCode
+ */
public void setChainCode(String chainCode)
{
- if (properties == null)
+ if (chainCode == null)
{
- if (chainCode == null)
- {
- // nothing to do.
- return;
- }
- properties = new Hashtable();
+ deleteProperty(CHAIN_ID);
}
- if (chainCode == null)
+ else
+ {
+ setProperty(CHAIN_ID, new CaseInsensitiveString(chainCode));
+ }
+ }
+
+ /**
+ * Deletes the property with the given key, and returns the deleted value (or
+ * null)
+ */
+ Object deleteProperty(String key)
+ {
+ Object result = null;
+ if (properties != null)
{
- properties.remove(CHAIN_ID);
- return;
+ result = properties.remove(key);
}
- // update property for non-null chainCode
- properties.put(CHAIN_ID, new CaseInsensitiveString(chainCode));
+ return result;
}
@Override
}
/**
+ * Getter provided for Castor binding only. Application code should call
+ * getProperty() or getProperties() instead.
+ *
+ * @deprecated
+ * @see #getProperty(String)
+ * @see #getProperties()
+ * @see jalview.ws.dbsources.Uniprot#getUniprotEntries
+ * @return
+ */
+ @Deprecated
+ public Hashtable<String, Object> getProps()
+ {
+ return properties;
+ }
+
+ /**
+ * Setter provided for Castor binding only. Application code should call
+ * setProperty() instead.
+ *
+ * @deprecated
+ * @return
+ */
+ @Deprecated
+ public void setProps(Hashtable<String, Object> props)
+ {
+ properties = props;
+ }
+
+ /**
* Answers true if this object is either equivalent to, or can be 'improved'
* by, the given entry.
* <p>
* @param newEntry
* @return true if modifications were made
*/
- protected boolean updateFrom(PDBEntry newEntry)
+ public boolean updateFrom(PDBEntry newEntry)
{
if (this.equals(newEntry))
{
}
/*
- * id (less any chain code) has to match (ignoring case)
+ * id has to match (ignoring case)
*/
if (!getId().equalsIgnoreCase(newId))
{
}
/*
- * copy any new properties; notice this may include chain_code,
- * but we excluded differing chain codes earlier
+ * copy any new or modified properties
*/
- if (newEntry.getProperty() != null)
+ Enumeration<String> newProps = newEntry.getProperties();
+ while (newProps.hasMoreElements())
{
- if (properties == null)
+ /*
+ * copy properties unless value matches; this defends against changing
+ * the case of chain_code which is wrapped in a CaseInsensitiveString
+ */
+ String key = newProps.nextElement();
+ Object value = newEntry.getProperty(key);
+ if (!value.equals(getProperty(key)))
{
- properties = new Hashtable();
- }
- for (Object p : newEntry.getProperty().keySet())
- {
- /*
- * copy properties unless value matches; this defends against changing
- * the case of chain_code which is wrapped in a CaseInsensitiveString
- */
- Object value = newEntry.getProperty().get(p);
- if (!value.equals(properties.get(p)))
- {
- properties.put(p, newEntry.getProperty().get(p));
- }
+ setProperty(key, value);
}
}
return true;
Vector<EmblError> errors;
+ String text;
+
/**
* @return the entries
*/
*/
static void canonicaliseDbRefs(EmblFile record)
{
+ if (record.getEntries() == null)
+ {
+ return;
+ }
for (EmblEntry entry : record.getEntries())
{
if (entry.getDbRefs() != null)
}
}
}
+
+ public String getText()
+ {
+ return text;
+ }
+
+ public void setText(String text)
+ {
+ this.text = text;
+ }
}
*/
abstract class EnsemblRestClient extends EnsemblSequenceFetcher
{
+ private static final int DEFAULT_READ_TIMEOUT = 5 * 60 * 1000; // 5 minutes
+
+ private static final int CONNECT_TIMEOUT_MS = 10 * 1000; // 10 seconds
+
/*
* update these constants when Jalview has been checked / updated for
* changes to Ensembl REST API
*/
private boolean checkEnsembl()
{
- HttpURLConnection conn = null;
+ BufferedReader br = null;
try
{
// note this format works for both ensembl and ensemblgenomes
/*
* expect {"ping":1} if ok
+ * if ping takes more than 2 seconds to respond, treat as if unavailable
*/
- BufferedReader br = getHttpResponse(ping, null);
+ br = getHttpResponse(ping, null, 2 * 1000);
JSONParser jp = new JSONParser();
JSONObject val = (JSONObject) jp.parse(br);
String pingString = val.get("ping").toString();
+ t.getMessage());
} finally
{
- if (conn != null)
+ if (br != null)
{
- conn.disconnect();
+ try
+ {
+ br.close();
+ } catch (IOException e)
+ {
+ // ignore
+ }
}
}
return false;
}
/**
+ * Gets a reader to the HTTP response, using the default read timeout of 5
+ * minutes
+ *
+ * @param url
+ * @param ids
+ * @return
+ * @throws IOException
+ */
+ protected BufferedReader getHttpResponse(URL url, List<String> ids)
+ throws IOException
+ {
+ return getHttpResponse(url, ids, DEFAULT_READ_TIMEOUT);
+ }
+
+ /**
* Writes the HTTP request and gets the response as a reader.
*
* @param url
* @param ids
* written as Json POST body if more than one
+ * @param readTimeout
+ * in milliseconds
* @return
* @throws IOException
* if response code was not 200, or other I/O error
*/
- protected BufferedReader getHttpResponse(URL url, List<String> ids)
- throws IOException
+ protected BufferedReader getHttpResponse(URL url, List<String> ids,
+ int readTimeout) throws IOException
{
// long now = System.currentTimeMillis();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(multipleIds);
+ connection.setConnectTimeout(CONNECT_TIMEOUT_MS);
+ connection.setReadTimeout(readTimeout);
+
if (multipleIds)
{
writePostBody(connection, ids);
import java.io.File;
import java.net.URL;
import java.security.AccessControlException;
+import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
boolean loadedInline;
- /**
- * current set of model filenames loaded in the Jmol instance
- */
- String[] modelFileNames = null;
-
StringBuffer resetLastRes = new StringBuffer();
public Viewer viewer;
} catch (InterruptedException i)
{
}
- ;
}
+
+ /*
+ * get the distinct structure files modelled
+ * (a file with multiple chains may map to multiple sequences)
+ */
String[] files = getPdbFile();
if (!waitForFileLoad(files))
{
* 'matched' array will hold 'true' for visible alignment columns 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++)
{
* generate select statements to select regions to superimpose structures
*/
{
+ // TODO extract method to construct selection statements
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
String chainCd = ":" + structures[pdbfnum].chain;
}
}
StringBuilder command = new StringBuilder(256);
+ // command.append("set spinFps 10;\n");
+
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
if (pdbfnum == refStructure || selcom[pdbfnum] == null
}
if (selectioncom.length() > 0)
{
+ // TODO is performing selectioncom redundant here? is done later on
// System.out.println("Select regions:\n" + selectioncom.toString());
evalStateCommand("select *; cartoons off; backbone; select ("
+ selectioncom.toString() + "); cartoons; ");
}
if (modelFileNames == null)
{
- String mset[] = new String[viewer.ms.mc];
- _modelFileNameMap = new int[mset.length];
+ List<String> mset = new ArrayList<String>();
+ _modelFileNameMap = new int[viewer.ms.mc];
String m = viewer.ms.getModelFileName(0);
if (m != null)
{
- mset[0] = m;
+ String filePath = m;
try
{
- mset[0] = new File(m).getAbsolutePath();
+ filePath = new File(m).getAbsolutePath();
} catch (AccessControlException x)
{
// usually not allowed to do this in applet
.println("jmolBinding: Using local file string from Jmol: "
+ m);
}
- if (mset[0].indexOf("/file:") != -1)
+ if (filePath.indexOf("/file:") != -1)
{
// applet path with docroot - discard as format won't match pdbfile
- mset[0] = m;
+ filePath = m;
}
+ mset.add(filePath);
_modelFileNameMap[0] = 0; // filename index for first model is always 0.
}
int j = 1;
- for (int i = 1; i < mset.length; i++)
+ for (int i = 1; i < viewer.ms.mc; i++)
{
m = viewer.ms.getModelFileName(i);
- mset[j] = m;
+ String filePath = m;
if (m != null)
{
try
{
- mset[j] = new File(m).getAbsolutePath();
+ filePath = new File(m).getAbsolutePath();
} catch (AccessControlException x)
{
// usually not allowed to do this in applet, so keep raw handle
// System.err.println("jmolBinding: Using local file string from Jmol: "+m);
}
}
- _modelFileNameMap[j] = i; // record the model index for the filename
- // skip any additional models in the same file (NMR structures)
- if ((mset[j] == null ? mset[j] != mset[j - 1]
- : (mset[j - 1] == null || !mset[j].equals(mset[j - 1]))))
+
+ /*
+ * add this model unless it is read from a structure file we have
+ * already seen (example: 2MJW is an NMR structure with 10 models)
+ */
+ if (!mset.contains(filePath))
{
+ mset.add(filePath);
+ _modelFileNameMap[j] = i; // record the model index for the filename
j++;
}
}
- modelFileNames = new String[j];
- System.arraycopy(mset, 0, modelFileNames, 0, j);
+ modelFileNames = mset.toArray(new String[mset.size()]);
}
return modelFileNames;
}
try
{
/*
- * params -o (output to sysout) -i (no info logging, less verbose)
- * -n (nodisplay) -x (exit when finished)
+ * params -o (output to sysout) -n (nodisplay) -x (exit when finished)
* see http://wiki.jmol.org/index.php/Jmol_Application
*/
viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
- null, "-x -o -n -i", this);
+ null, "-x -o -n", this);
// ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
viewer.setBooleanProperty("defaultStructureDSSP", true);
} catch (ClassCastException x)
List<SequenceI> prot = new ArrayList<SequenceI>();
PDBChain tmpchain;
String pdbId = (String) ms.getInfo(0, "title");
- setId(pdbId);
+
+ if (pdbId == null)
+ {
+ setId(safeName(getDataName()));
+ setPDBIdAvailable(false);
+ }
+ else
+ {
+ setId(pdbId);
+ setPDBIdAvailable(true);
+ }
List<Atom> significantAtoms = convertSignificantAtoms(ms);
for (Atom tmpatom : significantAtoms)
{
tmpchain.atoms.addElement(tmpatom);
} catch (Exception e)
{
- tmpchain = new PDBChain(pdbId, tmpatom.chain);
+ tmpchain = new PDBChain(getId(), tmpatom.chain);
getChains().add(tmpchain);
tmpchain.atoms.addElement(tmpatom);
}
makeResidueList();
makeCaBondList();
- if (getId() == null)
- {
- setId(safeName(getDataName()));
- }
for (PDBChain chain : getChains())
{
SequenceI chainseq = postProcessChain(chain);
private String lastCommand;
- /*
- * current set of model filenames loaded
- */
- String[] modelFileNames = null;
-
String lastHighlightCommand;
/*
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
@Override
public void drop(DropTargetDropEvent evt)
{
+ // JAL-1552 - acceptDrop required before getTransferable call for
+ // Java's Transferable for native dnd
+ evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = evt.getTransferable();
java.util.List<String> files = new ArrayList<String>(), protocols = new ArrayList<String>();
public class AppJmol extends StructureViewerBase
{
+ // ms to wait for Jmol to load files
+ private static final int JMOL_LOAD_TIMEOUT = 20000;
+
private static final String SPACE = " ";
private static final String BACKSLASH = "\"";
jmb.setColourBySequence(true);
setSize(400, 400); // probably should be a configurable/dynamic default here
initMenus();
- worker = null;
- {
- addingStructures = false;
- worker = new Thread(this);
- worker.start();
- }
+ addingStructures = false;
+ worker = new Thread(this);
+ worker.start();
+
this.addInternalFrameListener(new InternalFrameAdapter()
{
@Override
scriptWindow.setVisible(false);
}
- /*
- * -i for no info logging (less verbose)
- */
- jmb.allocateViewer(renderPanel, true, "", null, null, "-i",
+ jmb.allocateViewer(renderPanel, true, "", null, null, "",
scriptWindow, null);
// jmb.newJmolPopup("Jmol");
if (command == null)
}
// need to wait around until script has finished
- int waitMax = 5000; // give up after 5 seconds
+ int waitMax = JMOL_LOAD_TIMEOUT;
int waitFor = 35;
int waitTotal = 0;
while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled()
}
if (waitTotal > waitMax)
{
- System.err.println("Timed out waiting for Jmol to load files");
+ System.err
+ .println("Timed out waiting for Jmol to load files after "
+ + waitTotal + "ms");
+// System.err.println("finished: " + jmb.isFinishedInit()
+// + "; loaded: " + Arrays.toString(jmb.getPdbFile())
+// + "; files: " + files.toString());
+ jmb.getPdbFile();
break;
}
}
{
int pos = filePDBpos.get(num).intValue();
long startTime = startProgressBar("Chimera "
- + MessageManager.getString("status.opening_file"));
+ + MessageManager.getString("status.opening_file_for")
+ + " " + pe.getId());
jmb.openFile(pe);
jmb.addSequence(pos, jmb.getSequence()[pos]);
File fl = new File(pe.getFile());
public void drop(DropTargetDropEvent evt)
{
boolean success = true;
+ // JAL-1552 - acceptDrop required before getTransferable call for
+ // Java's Transferable for native dnd
+ evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = evt.getTransferable();
java.util.List<String> files = new ArrayList<String>();
java.util.List<String> protocols = new ArrayList<String>();
{
// Works on Windows and MacOSX
Cache.log.debug("Drop handled as javaFileListFlavor");
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
for (Object file : (List) t
.getTransferData(DataFlavor.javaFileListFlavor))
{
{
Cache.log.debug("Drop handled as uriListFlavor");
// This is used by Unix drag system
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
data = (String) t.getTransferData(uriListFlavor);
}
if (data == null)
{
Cache.log.debug("Supported transfer dataflavor: "
+ fl.toString());
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Object df = t.getTransferData(fl);
if (df != null)
{
}
}
- if (entry.getProperty() != null && !entry.getProperty().isEmpty())
+ Enumeration<String> props = entry.getProperties();
+ if (props.hasMoreElements())
{
PdbentryItem item = new PdbentryItem();
- Hashtable properties = entry.getProperty();
- Enumeration en2 = properties.keys();
- while (en2.hasMoreElements())
+ while (props.hasMoreElements())
{
Property prop = new Property();
- String key = en2.nextElement().toString();
+ String key = props.nextElement();
prop.setName(key);
- prop.setValue(properties.get(key).toString());
+ prop.setValue(entry.getProperty(key).toString());
item.addProperty(prop);
}
pdb.addPdbentryItem(item);
entry.setType(PDBEntry.Type.FILE);
}
}
- if (ids[p].getFile() != null)
+ // jprovider is null when executing 'New View'
+ if (ids[p].getFile() != null && jprovider != null)
{
if (!pdbloaded.containsKey(ids[p].getFile()))
{
}
if (ids[p].getPdbentryItem() != null)
{
- entry.setProperty(new Hashtable());
for (PdbentryItem item : ids[p].getPdbentryItem())
{
for (Property pr : item.getProperty())
{
- entry.getProperty().put(pr.getName(), pr.getValue());
+ entry.setProperty(pr.getName(), pr.getValue());
}
}
}
private boolean isValidPBDEntry;
+ private boolean cachedPDBExists;
+
public StructureChooser(SequenceI[] selectedSeqs, SequenceI selectedSeq,
AlignmentPanel ap)
{
}
// ensure a filter option is in force for search
- populateFilterComboBox(true);
+ populateFilterComboBox(true, cachedPDBExists);
Thread discoverPDBStructuresThread = new Thread(new Runnable()
{
@Override
startTime);
fetchStructuresMetaData();
// revise filter options if no results were found
- populateFilterComboBox(isStructuresDiscovered());
+ populateFilterComboBox(isStructuresDiscovered(), cachedPDBExists);
updateProgressIndicator(null, startTime);
mainFrame.setVisible(true);
updateCurrentView();
}
}
}
-
+ cachedPDBExists = !entries.isEmpty();
PDBEntryTableModel tableModelx = new PDBEntryTableModel(entries);
tbl_local_pdb.setModel(tableModelx);
}
* Populates the filter combo-box options dynamically depending on discovered
* structures
*/
- protected void populateFilterComboBox(boolean haveData)
+ protected void populateFilterComboBox(boolean haveData,
+ boolean cachedPDBExists)
{
/*
* temporarily suspend the change listener behaviour
VIEWS_ENTER_ID));
cmb_filterOption.addItem(new FilterOption("From File", "-",
VIEWS_FROM_FILE));
- cmb_filterOption.addItem(new FilterOption("Cached PDB Entries", "-",
- VIEWS_LOCAL_PDB));
+ FilterOption cachedOption = new FilterOption("Cached PDB Entries", "-",
+ VIEWS_LOCAL_PDB);
+ cmb_filterOption.addItem(cachedOption);
+
+ if (/*!haveData &&*/cachedPDBExists)
+ {
+ cmb_filterOption.setSelectedItem(cachedOption);
+ }
cmb_filterOption.addItemListener(this);
}
protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
PDBEntry[] pdbs, SequenceI[][] seqsForPdbs, AlignmentPanel ap)
{
+ PDBEntry[] pdbsForFile = getUniquePdbFiles(pdbs);
JalviewStructureDisplayI sview = null;
if (viewerType.equals(ViewerType.JMOL))
{
- sview = new AppJmol(ap, pdbs, ap.av.collateForPDB(pdbs));
+ sview = new AppJmol(ap, pdbsForFile, ap.av.collateForPDB(pdbsForFile));
}
else if (viewerType.equals(ViewerType.CHIMERA))
{
- sview = new ChimeraViewFrame(pdbs, ap.av.collateForPDB(pdbs), ap);
+ sview = new ChimeraViewFrame(pdbsForFile,
+ ap.av.collateForPDB(pdbsForFile), ap);
}
else
{
return sview;
}
+ /**
+ * Convert the array of PDBEntry into an array with no filename repeated
+ *
+ * @param pdbs
+ * @return
+ */
+ static PDBEntry[] getUniquePdbFiles(PDBEntry[] pdbs)
+ {
+ if (pdbs == null)
+ {
+ return null;
+ }
+ List<PDBEntry> uniques = new ArrayList<PDBEntry>();
+ List<String> filesSeen = new ArrayList<String>();
+ for (PDBEntry entry : pdbs)
+ {
+ String file = entry.getFile();
+ if (file == null)
+ {
+ uniques.add(entry);
+ }
+ else if (!filesSeen.contains(file))
+ {
+ uniques.add(entry);
+ filesSeen.add(file);
+ }
+ }
+ return uniques.toArray(new PDBEntry[uniques.size()]);
+ }
+
protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
PDBEntry pdb, SequenceI[] seqsForPdb, AlignmentPanel ap)
{
import java.awt.Color;
import java.io.IOException;
import java.lang.reflect.Constructor;
-import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
private Vector<PDBChain> chains;
+ private boolean pdbIdAvailable;
+
public StructureFile(String inFile, String type) throws IOException
{
super(inFile, type);
{
}
- @SuppressWarnings("rawtypes")
protected SequenceI postProcessChain(PDBChain chain)
{
SequenceI pdbSequence = chain.sequence;
PDBEntry entry = new PDBEntry();
entry.setId(getId());
entry.setType(getStructureFileType());
- entry.setProperty(new Hashtable());
if (chain.id != null)
{
- entry.setChainCode(String.valueOf(chain.id));
+ entry.setChainCode(chain.id);
}
if (inFile != null)
{
{
return new PDBFeatureSettings();
}
+
+ /**
+ * Answers true if the structure file has a PDBId
+ *
+ * @return
+ */
+ public boolean isPPDBIdAvailable()
+ {
+ return pdbIdAvailable;
+ }
+
+ public void setPDBIdAvailable(boolean pdbIdAvailable)
+ {
+ this.pdbIdAvailable = pdbIdAvailable;
+ }
}
{
registerPDBFile(pdb.getId().trim(), pdbFile);
}
+ // if PDBId is unavailable then skip SIFTS mapping execution path
+ isMapUsingSIFTs = pdb.isPPDBIdAvailable();
+
} catch (Exception ex)
{
ex.printStackTrace();
private StructureSelectionManager ssm;
+ /*
+ * distinct PDB entries (pdb files) associated
+ * with sequences
+ */
private PDBEntry[] pdbEntry;
/*
private boolean finishedInit = false;
/**
+ * current set of model filenames loaded in the Jmol instance
+ */
+ protected String[] modelFileNames = null;
+
+ /**
* Data bean class to simplify parameterisation in superposeStructures
*/
protected class SuperposeData
// TODO: give a more informative title when multiple structures are
// displayed.
StringBuilder title = new StringBuilder(64);
- final PDBEntry pdbEntry = getPdbEntry(0);
+ final PDBEntry pdbe = getPdbEntry(0);
title.append(viewerName + " view for " + getSequence()[0][0].getName()
- + ":" + pdbEntry.getId());
+ + ":" + pdbe.getId());
if (verbose)
{
- if (pdbEntry.getProperty() != null)
+ String method = (String) pdbe.getProperty("method");
+ if (method != null)
{
- if (pdbEntry.getProperty().get("method") != null)
- {
- title.append(" Method: ");
- title.append(pdbEntry.getProperty().get("method"));
- }
- if (pdbEntry.getProperty().get("chains") != null)
- {
- title.append(" Chain:");
- title.append(pdbEntry.getProperty().get("chains"));
- }
+ title.append(" Method: ").append(method);
+ }
+ String chain = (String) pdbe.getProperty("chains");
+ if (chain != null)
+ {
+ title.append(" Chain:").append(chain);
}
}
return title.toString();
{
int refStructure = -1;
String[] files = getPdbFile();
+ if (files == null)
+ {
+ return -1;
+ }
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
StructureMapping[] mappings = getSsm().getMapping(files[pdbfnum]);
}
structures[pdbfnum].pdbId = mapping.getPdbId();
structures[pdbfnum].isRna = theSequence.getRNA() != null;
- // move on to next pdb file
+
+ /*
+ * move on to next pdb file (ignore sequences for other chains
+ * for the same structure)
+ */
s = seqCountForPdbFile;
break;
}
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
PDBEntry pdbr = new PDBEntry();
pdbr.setId(pdbid);
pdbr.setType(PDBEntry.Type.PDB);
- pdbr.setProperty(new Hashtable());
pdbr.setChainCode(chaincode);
- // pdbr.getProperty().put("CHAIN", chaincode);
seq.addPDBId(pdbr);
}
else
}
}
+ /*
+ * invalid accession gets a reply with no <entry> elements, text content of
+ * EmbFile reads something like (e.g.) this ungrammatical phrase
+ * Entry: <acc> display type is either not supported or entry is not found.
+ */
List<SequenceI> peptides = new ArrayList<SequenceI>();
- if (efile != null)
+ if (efile != null && efile.getEntries() != null)
{
for (EmblEntry entry : efile.getEntries())
{
if ("EMBL".equals(pdb.getType()))
{
// look for a CDS reference and add it, too.
- String cdsId = (String) pdb.getProperty()
- .get("protein sequence ID");
+ String cdsId = (String) pdb.getProperty("protein sequence ID");
if (cdsId != null && cdsId.trim().length() > 0)
{
// remove version
* <property type="gene ID" value="ENSG00000158828"/>
* </dbReference>
*/
- String cdsId = (String) pdb.getProperty()
- .get("protein sequence ID");
+ String cdsId = (String) pdb.getProperty("protein sequence ID");
if (cdsId != null && cdsId.trim().length() > 0)
{
dbr = new DBRefEntry(DBRefSource.ENSEMBL, DBRefSource.UNIPROT
String pdbFile, String chain) throws SiftsException
{
structId = (chain == null) ? pdbId : pdbId + "|" + chain;
- System.out.println("Getting mapping for: " + pdbId + "|" + chain
- + " : seq- " + seq.getName());
+ System.out.println("Getting SIFTS mapping for " + structId + ": seq "
+ + seq.getName());
final StringBuilder mappingDetails = new StringBuilder(128);
PrintStream ps = new PrintStream(System.out)
int pdbStart = UNASSIGNED;
int pdbEnd = UNASSIGNED;
- Integer[] keys = mapping.keySet().toArray(new Integer[0]);
- Arrays.sort(keys);
- if (keys.length < 1)
+ if (mapping.isEmpty())
{
- throw new SiftsException(">>> Empty SIFTS mapping generated!!");
+ throw new SiftsException("SIFTS mapping failed");
}
+
+ Integer[] keys = mapping.keySet().toArray(new Integer[0]);
+ Arrays.sort(keys);
seqStart = keys[0];
seqEnd = keys[keys.length - 1];
import jalview.datamodel.PDBEntry.Type;
-import java.util.Hashtable;
-
//import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
assertNotEquals(case9, case10);
// add properties
- case7.getProperty().put("hello", "world");
+ case7.setProperty("hello", "world");
assertNotEquals(case7, case9);
- case9.getProperty().put("hello", "world");
+ case9.setProperty("hello", "world");
assertEquals(case7, case9);
- case9.getProperty().put("hello", "WORLD");
+ case9.setProperty("hello", "WORLD");
assertNotEquals(case7, case9);
/*
* change string wrapper property to string...
*/
- case1.getProperty().put("chain_code", "a");
+ case1.setProperty("chain_code", "a");
assertFalse(pdbEntry.equals(case1));
assertFalse(case1.equals(pdbEntry));
}
*/
pdb1 = new PDBEntry("3A6S", null, null, null);
pdb2 = new PDBEntry("3A6S", null, null, null);
- // ughh properties not null if chain code has been set...
- // JAL-2196 addresses this
- pdb1.properties = new Hashtable();
- pdb2.properties = new Hashtable();
- pdb1.properties.put("destination", "mars");
- pdb1.properties.put("hello", "world");
- pdb2.properties.put("hello", "moon");
- pdb2.properties.put("goodbye", "world");
+ pdb1.setProperty("destination", "mars");
+ pdb1.setProperty("hello", "world");
+ pdb2.setProperty("hello", "moon");
+ pdb2.setProperty("goodbye", "world");
assertTrue(pdb1.updateFrom(pdb2));
- assertEquals(pdb1.properties.get("destination"), "mars");
- assertEquals(pdb1.properties.get("hello"), "moon");
- assertEquals(pdb1.properties.get("goodbye"), "world");
+ assertEquals(pdb1.getProperty("destination"), "mars");
+ assertEquals(pdb1.getProperty("hello"), "moon");
+ assertEquals(pdb1.getProperty("goodbye"), "world");
/*
* add properties only
*/
pdb1 = new PDBEntry("3A6S", null, null, null);
pdb2 = new PDBEntry("3A6S", null, null, null);
- pdb2.properties = new Hashtable();
- pdb2.properties.put("hello", "moon");
+ pdb2.setProperty("hello", "moon");
assertTrue(pdb1.updateFrom(pdb2));
- assertEquals(pdb1.properties.get("hello"), "moon");
+ assertEquals(pdb1.getProperty("hello"), "moon");
}
@Test(groups = { "Functional" })
package jalview.ext.jmol;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import jalview.bin.Cache;
assertEquals('H', structCode[4]);
assertEquals('E', structCode[5]);
}
+
+ @Test(groups = "Functional")
+ public void testLocalPDBId() throws Exception
+ {
+ JmolParser structureData;
+ /*
+ * reads a local structure
+ */
+ structureData = new JmolParser("examples/testdata/localstruct.pdb",
+ AppletFormatAdapter.FILE);
+ assertNotNull(structureData);
+ /*
+ * local structure files should yield a false ID based on the filename
+ */
+ assertNotNull(structureData.getId());
+ assertEquals(structureData.getId(), "localstruct.pdb");
+ assertNotNull(structureData.getSeqs());
+ /*
+ * the ID is also the group for features derived from structure data
+ */
+ assertNotNull(structureData.getSeqs().get(0).getSequenceFeatures()[0].featureGroup);
+ assertEquals(
+ structureData.getSeqs().get(0).getSequenceFeatures()[0].featureGroup,
+ "localstruct.pdb");
+
+ }
}
import jalview.datamodel.PDBEntry;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import jalview.jbgui.GStructureChooser.FilterOption;
import java.util.Vector;
{
SequenceI[] selectedSeqs = new SequenceI[] { seq };
StructureChooser sc = new StructureChooser(selectedSeqs, seq, null);
- sc.populateFilterComboBox(false);
+ sc.populateFilterComboBox(false, false);
int optionsSize = sc.getCmbFilterOption().getItemCount();
assertEquals(3, optionsSize); // if structures are not discovered then don't
// populate filter options
- sc.populateFilterComboBox(true);
+ sc.populateFilterComboBox(true, false);
optionsSize = sc.getCmbFilterOption().getItemCount();
assertTrue(optionsSize > 3); // if structures are found, filter options
// should be populated
+
+ sc.populateFilterComboBox(true, true);
+ assertTrue(sc.getCmbFilterOption().getSelectedItem() != null);
+ FilterOption filterOpt = (FilterOption) sc.getCmbFilterOption()
+ .getSelectedItem();
+ assertEquals("Cached PDB Entries", filterOpt.getName());
}
@Test(groups = { "Functional" })
--- /dev/null
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
+
+import org.testng.annotations.Test;
+
+public class StructureViewerTest
+{
+ @Test(groups = "Functional")
+ public void testGetUniquePdbFiles()
+ {
+ assertNull(StructureViewer.getUniquePdbFiles(null));
+
+ PDBEntry pdbe1 = new PDBEntry("1A70", "A", Type.PDB, "path1");
+ PDBEntry pdbe2 = new PDBEntry("3A6S", "A", Type.PDB, "path2");
+ PDBEntry pdbe3 = new PDBEntry("1A70", "B", Type.PDB, "path1");
+ PDBEntry pdbe4 = new PDBEntry("1GAQ", "A", Type.PDB, null);
+ PDBEntry pdbe5 = new PDBEntry("3A6S", "B", Type.PDB, "path2");
+ PDBEntry pdbe6 = new PDBEntry("1GAQ", "B", Type.PDB, null);
+
+ /*
+ * pdbe2 and pdbe5 get removed as having a duplicate file path
+ */
+ PDBEntry[] uniques = StructureViewer.getUniquePdbFiles(new PDBEntry[] {
+ pdbe1, pdbe2, pdbe3, pdbe4, pdbe5, pdbe6 });
+ assertEquals(uniques,
+ new PDBEntry[] { pdbe1, pdbe2, pdbe4, pdbe6 });
+ }
+}
*/
public class AAStructureBindingModelTest
{
+ /*
+ * Scenario: Jalview has 4 sequences, corresponding to 1YCS (chains A and B), 3A6S|B, 1OOT|A
+ */
private static final String PDB_1 = "HEADER COMPLEX (ANTI-ONCOGENE/ANKYRIN REPEATS) 30-SEP-96 1YCS \n"
+ "ATOM 2 CA VAL A 97 24.134 4.926 45.821 1.00 47.43 C \n"
+ "ATOM 9 CA PRO A 98 25.135 8.584 46.217 1.00 41.60 C \n"
+ "ATOM 16 CA SER A 99 28.243 9.596 44.271 1.00 39.63 C \n"
+ "ATOM 22 CA GLN A 100 31.488 10.133 46.156 1.00 35.60 C \n"
- + "ATOM 31 CA LYS A 101 33.323 11.587 43.115 1.00 41.69 C \n";
+ // artificial jump in residue numbering to prove it is correctly
+ // mapped:
+ + "ATOM 31 CA LYS A 102 33.323 11.587 43.115 1.00 41.69 C \n"
+ + "ATOM 1857 CA GLU B 374 9.193 -16.005 95.870 1.00 54.22 C \n"
+ + "ATOM 1866 CA ILE B 375 7.101 -14.921 92.847 1.00 46.82 C \n"
+ + "ATOM 1874 CA VAL B 376 10.251 -13.625 91.155 1.00 47.80 C \n"
+ + "ATOM 1881 CA LYS B 377 11.767 -17.068 91.763 1.00 50.21 C \n"
+ + "ATOM 1890 CA PHE B 378 8.665 -18.948 90.632 1.00 44.85 C \n";
private static final String PDB_2 = "HEADER HYDROLASE 09-SEP-09 3A6S \n"
- + "ATOM 2 CA MET A 1 15.366 -11.648 24.854 1.00 32.05 C \n"
- + "ATOM 10 CA LYS A 2 16.846 -9.215 22.340 1.00 25.68 C \n"
- + "ATOM 19 CA LYS A 3 15.412 -6.335 20.343 1.00 19.42 C \n"
- + "ATOM 28 CA LEU A 4 15.629 -5.719 16.616 1.00 15.49 C \n"
- + "ATOM 36 CA GLN A 5 14.412 -2.295 15.567 1.00 12.19 C \n";
+ + "ATOM 2 CA MET B 1 15.366 -11.648 24.854 1.00 32.05 C \n"
+ + "ATOM 10 CA LYS B 2 16.846 -9.215 22.340 1.00 25.68 C \n"
+ + "ATOM 19 CA LYS B 3 15.412 -6.335 20.343 1.00 19.42 C \n"
+ + "ATOM 28 CA LEU B 4 15.629 -5.719 16.616 1.00 15.49 C \n"
+ + "ATOM 36 CA GLN B 5 14.412 -2.295 15.567 1.00 12.19 C \n";
private static final String PDB_3 = "HEADER STRUCTURAL GENOMICS 04-MAR-03 1OOT \n"
- + "ATOM 2 CA SER A 1 29.427 3.330 -6.578 1.00 32.50 C \n"
- + "ATOM 8 CA PRO A 2 29.975 3.340 -2.797 1.00 17.62 C \n"
- + "ATOM 16 CA ALYS A 3 26.958 3.024 -0.410 0.50 8.78 C \n"
- + "ATOM 33 CA ALA A 4 26.790 4.320 3.172 1.00 11.98 C \n"
- + "ATOM 39 CA AVAL A 5 24.424 3.853 6.106 0.50 13.83 C \n";
+ + "ATOM 2 CA SER A 7 29.427 3.330 -6.578 1.00 32.50 C \n"
+ + "ATOM 8 CA PRO A 8 29.975 3.340 -2.797 1.00 17.62 C \n"
+ + "ATOM 16 CA ALYS A 9 26.958 3.024 -0.410 0.50 8.78 C \n"
+ + "ATOM 33 CA ALA A 10 26.790 4.320 3.172 1.00 11.98 C \n"
+ + "ATOM 39 CA AVAL A 12 24.424 3.853 6.106 0.50 13.83 C \n";
AAStructureBindingModel testee;
@BeforeMethod(alwaysRun = true)
public void setUp()
{
- SequenceI seq1 = new Sequence("1YCS", "-VPSQK");
+ SequenceI seq1a = new Sequence("1YCS|A", "-VPSQK");
+ SequenceI seq1b = new Sequence("1YCS|B", "EIVKF-");
SequenceI seq2 = new Sequence("3A6S", "MK-KLQ");
SequenceI seq3 = new Sequence("1OOT", "SPK-AV");
- al = new Alignment(new SequenceI[] { seq1, seq2, seq3 });
+ al = new Alignment(new SequenceI[] { seq1a, seq1b, seq2, seq3 });
al.setDataset(null);
+ /*
+ * give pdb files the name generated by Jalview for PASTE source
+ */
PDBEntry[] pdbFiles = new PDBEntry[3];
- pdbFiles[0] = new PDBEntry("1YCS", "A", Type.PDB, "1YCS.pdb");
- pdbFiles[1] = new PDBEntry("3A6S", "B", Type.PDB, "3A6S.pdb");
- pdbFiles[2] = new PDBEntry("1OOT", "A", Type.PDB, "1OOT.pdb");
+ pdbFiles[0] = new PDBEntry("1YCS", "A", Type.PDB, "INLINE1YCS");
+ pdbFiles[1] = new PDBEntry("3A6S", "B", Type.PDB, "INLINE3A6S");
+ pdbFiles[2] = new PDBEntry("1OOT", "A", Type.PDB, "INLINE1OOT");
String[][] chains = new String[3][];
SequenceI[][] seqs = new SequenceI[3][];
- seqs[0] = new SequenceI[] { seq1 };
+ seqs[0] = new SequenceI[] { seq1a, seq1b };
seqs[1] = new SequenceI[] { seq2 };
seqs[2] = new SequenceI[] { seq3 };
StructureSelectionManager ssm = new StructureSelectionManager();
- ssm.setMapping(new SequenceI[] { seq1 }, null, PDB_1,
+ ssm.setMapping(new SequenceI[] { seq1a, seq1b }, null, PDB_1,
AppletFormatAdapter.PASTE);
ssm.setMapping(new SequenceI[] { seq2 }, null, PDB_2,
AppletFormatAdapter.PASTE);
@Override
public String[] getPdbFile()
{
- /*
- * fudge 'filenames' to match those generated when PDBFile parses PASTE
- * data
- */
return new String[] { "INLINE1YCS", "INLINE3A6S", "INLINE1OOT" };
}
@Test(groups = { "Functional" })
public void testFindSuperposableResidues()
{
- SuperposeData[] structs = new SuperposeData[al.getHeight()];
+ /*
+ * create a data bean to hold data per structure file
+ */
+ SuperposeData[] structs = new SuperposeData[testee.getPdbFile().length];
for (int i = 0; i < structs.length; i++)
{
structs[i] = testee.new SuperposeData(al.getWidth());
*/
assertFalse(matched[0]); // gap in first sequence
assertTrue(matched[1]);
- assertFalse(matched[2]); // gap in second sequence
- assertFalse(matched[3]); // gap in third sequence
+ assertFalse(matched[2]); // gap in third sequence
+ assertFalse(matched[3]); // gap in fourth sequence
assertTrue(matched[4]);
- assertTrue(matched[5]);
+ assertTrue(matched[5]); // gap in second sequence
+
+ assertEquals("1YCS", structs[0].pdbId);
+ assertEquals("3A6S", structs[1].pdbId);
+ assertEquals("1OOT", structs[2].pdbId);
+ assertEquals("A", structs[0].chain); // ? struct has chains A _and_ B
+ assertEquals("B", structs[1].chain);
+ assertEquals("A", structs[2].chain);
+ // the 0's for unsuperposable positions propagate down the columns:
+ assertEquals("[0, 97, 98, 99, 100, 102]",
+ Arrays.toString(structs[0].pdbResNo));
+ assertEquals("[0, 2, 0, 3, 4, 5]", Arrays.toString(structs[1].pdbResNo));
+ assertEquals("[0, 8, 0, 0, 10, 12]",
+ Arrays.toString(structs[2].pdbResNo));
}
@Test(groups = { "Functional" })
package jalview.ws.dbsources;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertNull;
PDBEntry xref = xrefs.get(0);
assertEquals("2FSQ", xref.getId());
assertEquals("PDB", xref.getType());
- assertEquals(2, xref.getProperty().size());
- assertEquals("X-ray", xref.getProperty().get("method"));
- assertEquals("1.40", xref.getProperty().get("resolution"));
+ assertEquals("X-ray", xref.getProperty("method"));
+ assertEquals("1.40", xref.getProperty("resolution"));
xref = xrefs.get(1);
assertEquals("2FSR", xref.getId());
assertEquals("PDBsum", xref.getType());
- assertNull(xref.getProperty());
+ assertFalse(xref.getProperties().hasMoreElements());
xref = xrefs.get(2);
assertEquals("AE007869", xref.getId());
assertEquals("EMBL", xref.getType());
- assertNotNull(xref.getProperty());
assertEquals("AAK85932.1",
- (String) xref.getProperty().get("protein sequence ID"));
+ xref.getProperty("protein sequence ID"));
assertEquals("Genomic_DNA",
- (String) xref.getProperty().get("molecule type"));
- assertEquals(2, xref.getProperty().size());
-
+ xref.getProperty("molecule type"));
}
@Test(groups = { "Functional" })
--- /dev/null
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ * A file reader that concatenates lines
+ *
+ * @author gmcarstairs
+ *
+ */
+public class BufferedLineReader
+{
+ interface LineCleaner
+ {
+ String cleanLine(String l);
+ }
+
+ /*
+ * a reader for the file being read
+ */
+ private BufferedReader br;
+
+ /*
+ * optional handler to post-process each line as it is read
+ */
+ private LineCleaner cleaner;
+
+ /*
+ * current buffer of <bufferSize> post-processed input lines
+ */
+ private String[] buffer;
+
+ private boolean atEof;
+
+ /**
+ * Constructor
+ *
+ * @param reader
+ * @param bufferSize
+ * the number of lines to concatenate at a time while reading
+ * @param tidier
+ * an optional callback handler to post-process each line after
+ * reading
+ * @throws FileNotFoundException
+ */
+ public BufferedLineReader(BufferedReader reader, int bufferSize,
+ LineCleaner tidier)
+ throws IOException
+ {
+ br = reader;
+ buffer = new String[bufferSize];
+ cleaner = tidier;
+
+ /*
+ * load up the buffer with N-1 lines, ready for the first read
+ */
+ for (int i = 1; i < bufferSize; i++)
+ {
+ readLine();
+ }
+
+ }
+
+ /**
+ * Reads the next line from file, invokes the post-processor if one was
+ * provided, and returns the 'cleaned' line, or null at end of file.
+ *
+ * @return
+ */
+ private String readLine() // throws IOException
+ {
+ if (atEof)
+ {
+ return null;
+ }
+
+ String line = null;
+ try
+ {
+ line = br.readLine();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ if (line == null)
+ {
+ atEof = true;
+ return null;
+ }
+ if (cleaner != null)
+ {
+ line = cleaner.cleanLine(line);
+ }
+
+ /*
+ * shuffle down the lines buffer and add the new line
+ * in the last position
+ */
+ for (int i = 1; i < buffer.length; i++)
+ {
+ buffer[i - 1] = buffer[i];
+ }
+ buffer[buffer.length - 1] = line;
+ return line;
+ }
+
+ /**
+ * Returns a number of concatenated lines from the file, or null at end of
+ * file.
+ *
+ * @return
+ */
+ public String read()
+ {
+ if (readLine() == null)
+ {
+ return null;
+ }
+ StringBuilder result = new StringBuilder(100 * buffer.length);
+ for (String line : buffer)
+ {
+ if (line != null)
+ {
+ result.append(line);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * A main 'test' method!
+ *
+ * @throws IOException
+ */
+ public static void main(String[] args) throws IOException
+ {
+ String data = "Now is the winter\n" + "Of our discontent\n"
+ + "Made glorious summer\n" + "By this sun of York\n";
+ BufferedReader br = new BufferedReader(new StringReader(data));
+ BufferedLineReader reader = new BufferedLineReader(br, 3,
+ new LineCleaner()
+ {
+ @Override
+ public String cleanLine(String l)
+ {
+ return l.toUpperCase();
+ }
+ });
+ String line = reader.read();
+ String expect = "NOW IS THE WINTEROF OUR DISCONTENTMADE GLORIOUS SUMMER";
+ if (!line.equals(expect))
+ {
+ System.err.println("Fail: expected '" + expect + "', found '" + line
+ + ";");
+ }
+ else
+ {
+ System.out.println("Line one ok!");
+ }
+ line = reader.read();
+ expect = "OF OUR DISCONTENTMADE GLORIOUS SUMMERBY THIS SUN OF YORK";
+ if (!line.equals(expect))
+ {
+ System.err.println("Fail: expected '" + expect + "', found '" + line
+ + "'");
+ }
+ else
+ {
+ System.out.println("Line two ok!!");
+ }
+ line = reader.read();
+ if (line != null)
+ {
+ System.err.println("Fail: expected null at eof, got '" + line + "'");
+ }
+ else
+ {
+ System.out.println("EOF ok!!!");
+ }
+ }
+}
* @author gmcarstairs
*
*/
-public class HelpLinksChecker
+public class HelpLinksChecker implements BufferedLineReader.LineCleaner
{
private static final String HELP_HS = "help.hs";
try
{
BufferedReader br = new BufferedReader(new FileReader(hrefFile));
- String data = br.readLine();
+ BufferedLineReader blr = new BufferedLineReader(br, 3, this);
+ String data = blr.read();
while (data != null)
{
if (data.contains(nameAnchor) || data.contains(idAnchor))
found = true;
break;
}
- data = br.readLine();
+ data = blr.read();
}
br.close();
} catch (IOException e)
}
return value;
}
+
+ /**
+ * Trim whitespace from concatenated lines but preserve one space for valid
+ * parsing
+ */
+ @Override
+ public String cleanLine(String l)
+ {
+ return l.trim() + " ";
+ }
}
* @author gmcarstairs
*
*/
-public class MessageBundleChecker
+public class MessageBundleChecker implements BufferedLineReader.LineCleaner
{
/*
* regex ^"[^"]*"$
return;
}
- String[] lines = new String[bufferSize];
BufferedReader br = new BufferedReader(new FileReader(f));
- for (int i = 0; i < bufferSize; i++)
- {
- String readLine = br.readLine();
- lines[i] = stripCommentsAndTrim(readLine);
- }
+ BufferedLineReader blr = new BufferedLineReader(br, bufferSize, this);
int lineNo = 0;
-
- while (lines[bufferSize - 1] != null)
+ String line = blr.read();
+ while (line != null)
{
lineNo++;
- inspectSourceLines(path, lineNo, lines);
-
- for (int i = 0; i < bufferSize - 1; i++)
- {
- lines[i] = lines[i + 1];
- }
- lines[bufferSize - 1] = stripCommentsAndTrim(br.readLine());
+ inspectSourceLines(path, lineNo, line);
+ line = blr.read();
}
br.close();
}
- /*
- * removes anything after (and including) '//'
- */
- private String stripCommentsAndTrim(String line)
- {
- if (line != null)
- {
- int pos = line.indexOf("//");
- if (pos != -1)
- {
- line = line.substring(0, pos);
- }
- line = line.replace("\t", " ").trim();
- }
- return line;
- }
-
/**
* Look for calls to MessageManager methods, possibly split over two or more
- * lines
+ * lines that have been concatenated while parsing the file
*
* @param path
* @param lineNo
- * @param lines
+ * @param line
*/
- private void inspectSourceLines(String path, int lineNo, String[] lines)
+ private void inspectSourceLines(String path, int lineNo, String line)
{
- String lineNos = String.format("%d-%d", lineNo, lineNo + lines.length
+ String lineNos = String
+ .format("%d-%d", lineNo, lineNo + bufferSize
- 1);
- String combined = combineLines(lines);
for (String method : METHODS)
{
- int pos = combined.indexOf(method);
+ int pos = line.indexOf(method);
if (pos == -1)
{
continue;
/*
* extract what follows the opening bracket of the method call
*/
- String methodArgs = combined.substring(pos + method.length()).trim();
+ String methodArgs = line.substring(pos + method.length()).trim();
if ("".equals(methodArgs))
{
/*
if (METHOD3 == method)
{
System.out.println(String.format("Dynamic key at %s line %s %s",
- path.substring(sourcePath.length()), lineNos, combined));
+ path.substring(sourcePath.length()), lineNos, line));
continue;
}
if (messageKey == null)
{
System.out.println(String.format("Trouble parsing %s line %s %s",
- path.substring(sourcePath.length()), lineNos, combined));
+ path.substring(sourcePath.length()), lineNos, line));
continue;
}
if (!(STRING_PATTERN.matcher(messageKey).matches()))
{
System.out.println(String.format("Dynamic key at %s line %s %s",
- path.substring(sourcePath.length()), lineNos, combined));
+ path.substring(sourcePath.length()), lineNos, line));
continue;
}
return endPos == -1 ? null : key.substring(0, endPos);
}
- private String combineLines(String[] lines)
- {
- String combined = "";
- if (lines != null)
- {
- for (String line : lines)
- {
- if (line != null)
- {
- combined += line;
- }
- }
- }
- return combined;
- }
-
/**
* Loads properties from Message.properties
*
}
+ /**
+ * Remove any trailing comments, change tabs to space, and trim
+ */
+ @Override
+ public String cleanLine(String l)
+ {
+ if (l != null)
+ {
+ int pos = l.indexOf("//");
+ if (pos != -1)
+ {
+ l = l.substring(0, pos);
+ }
+ l = l.replace("\t", " ").trim();
+ }
+ return l;
+ }
+
}