Skip to content

Commit 38f330d

Browse files
committed
Add /cesymm//multi route, try to recover from errors
1 parent 03dd2f2 commit 38f330d

File tree

7 files changed

+154
-42
lines changed

7 files changed

+154
-42
lines changed

src/main/java/org/biojava/http/BioJavaRoutes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class BioJavaRoutes {
2929
public static String MMCIF = "/mmcif/:id";
3030
public static String NGL = "/ngl/:id";
3131
public static String CESYMM = "/cesymm/:id";
32+
public static String CESYMM_MULTIPLE = "/cesymm/:id/multi";
3233
public static String CESYMM_JSON = "/cesymm/:id/json";
3334
public static String CESYMM_PDB = "/cesymm/:id/pdb";
3435
public static String CESYMM_AXES = "/cesymm/:id/axes";

src/main/java/org/biojava/http/ServerMain.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public static void main(String[] args) {
5858

5959
get(BioJavaRoutes.NGL, new NGLRoute(), new HandlebarsTemplateEngine());
6060

61-
get(BioJavaRoutes.CESYMM, new CeSymmRoute(), new HandlebarsTemplateEngine());
61+
get(BioJavaRoutes.CESYMM, new CeSymmRoute("cesymm.html.hbs"), new HandlebarsTemplateEngine());
62+
get(BioJavaRoutes.CESYMM_MULTIPLE, new CeSymmRoute("cesymm_multi.html.hbs"), new HandlebarsTemplateEngine());
6263
get(BioJavaRoutes.CESYMM_JSON, new CeSymmResultRoute(),new JsonTransformer());
6364
get(BioJavaRoutes.CESYMM_PDB, new CeSymmResultRoute() {
6465
@Override public CeSymmResult handle(Request request, Response response) {

src/main/java/org/biojava/http/compute/CeSymmResultCache.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.HashMap;
2929
import java.util.Map;
3030
import java.util.concurrent.Callable;
31+
import java.util.concurrent.ExecutionException;
3132
import java.util.concurrent.ExecutorService;
3233
import java.util.concurrent.Executors;
3334
import java.util.concurrent.Future;
@@ -58,16 +59,25 @@ private CeSymmResultCache() {
5859
public Future<CeSymmResult> analyze(String name) {
5960
Future<CeSymmResult> future;
6061
synchronized(cache) {
61-
if( !cache.containsKey(name)) {
62-
logger.info("Submitting ",name);
63-
CESymmParameters p = params.clone();
64-
Callable<CeSymmResult> worker = new CeSymmRunner(name, p, atomCache);
65-
future = executor.submit(worker);
66-
cache.put(name,future);
67-
} else {
68-
logger.info("Found previous calculation for {}",name);
62+
if( cache.containsKey(name)) {
6963
future = cache.get(name);
64+
boolean retry = false;
65+
try {
66+
retry = future.isDone() && future.get() == null;
67+
} catch (InterruptedException | ExecutionException e) {}
68+
if(retry) {
69+
logger.info("Retrying failed job: {}",name);
70+
} else {
71+
logger.info("Found previous calculation for {}",name);
72+
return future;
73+
}
74+
} else {
75+
logger.info("Submitting ",name);
7076
}
77+
CESymmParameters p = params.clone();
78+
Callable<CeSymmResult> worker = new CeSymmRunner(name, p, atomCache);
79+
future = executor.submit(worker);
80+
cache.put(name,future);
7181
}
7282

7383
return future;

src/main/java/org/biojava/http/routes/CeSymmRoute.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
public class CeSymmRoute implements TemplateViewRoute {
4343
public static Logger logger = LoggerFactory.getLogger(CeSymmRoute.class);
4444

45+
private final String template;
46+
public CeSymmRoute() {
47+
this("cesymm.html.hbs");
48+
}
49+
public CeSymmRoute(String template) {
50+
this.template = template;
51+
}
52+
4553
@Override
4654
public ModelAndView handle(Request request, Response response) throws Exception {
4755
String id = request.params(":id");
@@ -54,7 +62,7 @@ public ModelAndView handle(Request request, Response response) throws Exception
5462
String structUrl = BioJavaRoutes.CESYMM_PDB.replace(":id", id);
5563
String jsonUrl = BioJavaRoutes.CESYMM_TSV.replace(":id", id);
5664
CeSymmRouteParams params = new CeSymmRouteParams(id,structUrl,jsonUrl);
57-
return new ModelAndView(params, "cesymm.html.hbs");
65+
return new ModelAndView(params, template);
5866
} catch(Exception e) {
5967
logger.error("Error",e);
6068
response.status(404);

src/main/resources/static/index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,15 @@ <h3>CE-Symm</h3>
112112
Analyze the structure for internal symmetry using <a
113113
href="https://github.com/rcsb/symmetry">CE-Symm</a>.
114114
</p>
115+
<p>
116+
<table class="route">
117+
<tr>
118+
<td><pre>/cesymm/:id/multi</pre></td>
119+
<td>Example: <a href="/cesymm/1itb.A/multi">/cesymm/1itb.A</a></td>
120+
</tr>
121+
</table>
122+
View the CE-Symm alignment as a multiple structure superposition.
123+
</p>
115124
<p>Information about the alignment is available in several
116125
formats:
117126
<table class="route">
@@ -128,6 +137,13 @@ <h3>CE-Symm</h3>
128137
</tr>
129138
</table>
130139
JSON describing the alignment.
140+
<table class="route">
141+
<tr>
142+
<td><pre>/cesymm/:id/tsv</pre></td>
143+
<td>Example: <a href="/cesymm/1itb.A/tsv">/cesymm/1itb.A/tsv</a></td>
144+
</tr>
145+
</table>
146+
All aligned residues in the alignment, in tsv format.
131147
</p>
132148
</div>
133149
</body>

src/main/resources/templates/cesymm.html.hbs

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,42 @@ document.onkeypress = function(e) { default_keypress(stage,e); };
2222
2323
document.addEventListener( "DOMContentLoaded", function() {
2424
$.get("{{tsvUrl}}", function(tsv) {
25-
stage = new NGL.Stage( "viewport" );
26-
stage.setParameters({ backgroundColor:"white" } );
27-
2825
// Parse TSV file
2926
// Each line should contain ResNum/Chain/AminoAcid triplets
3027
// Lines end with tabs, so each line should have 3n+1 columns for n repeats.
3128
var lines = tsv.split("\n")
3229
.filter((x) => !x.startsWith("#") && x.length > 0)
3330
.map((x) => x.split("\t"));
3431
35-
// Get number of structures from first line
36-
var n_strucs = (lines[0].length - 1) / 3;
37-
38-
// Generate color palette
39-
var colors = palette('cb-Dark2', n_strucs);
40-
41-
// Create selection for each repeat
32+
// Check for significant alignment
4233
var colorSele = [];
43-
for (j = 0; j < n_strucs; j++) {
44-
var seleStr = [];
45-
for (i = 0; i < lines.length; i++) {
46-
if (lines[i][3*j] != "-") {
47-
seleStr.push("( " + lines[i][3*j] + " and :" + lines[i][3*j+1] + " )");
34+
35+
if( lines.length > 0) {
36+
// Get number of structures from first line
37+
var n_strucs = (lines[0].length - 1) / 3;
38+
39+
// Generate color palette
40+
var colors = palette('cb-Dark2', n_strucs);
41+
42+
// Create selection for each repeat
43+
for (j = 0; j < n_strucs; j++) {
44+
var seleStr = [];
45+
for (i = 0; i < lines.length; i++) {
46+
if (lines[i][3*j] != "-") {
47+
seleStr.push("( " + lines[i][3*j] + " and :" + lines[i][3*j+1] + " )");
48+
}
4849
}
50+
colorSele.push( ["#" + colors[j], seleStr.join(" or ")]);
4951
}
50-
colorSele.push( ["#" + colors[j], seleStr.join(" or ")]);
52+
} else {
53+
$('#messages').html("<p>No significant alignment found.</p>");
5154
}
5255
colorSele.push(["lightgrey","*"]);
53-
console.log(colorSele);
54-
56+
5557
var schemeId = NGL.ColorMakerRegistry.addSelectionScheme( colorSele, "CE-Symm {{structureId}}" );
5658
59+
stage = new NGL.Stage( "viewport" );
60+
stage.setParameters({ backgroundColor:"white" } );
5761
5862
stage.loadFile( "/pdb/{{structureId}}", { defaultRepresentation: false, ext:"pdb" } ).then( function( o ){
5963
o.addRepresentation( "cartoon", { color: schemeId } );
@@ -62,25 +66,15 @@ document.addEventListener( "DOMContentLoaded", function() {
6266
});
6367
o.centerView();
6468
} );
65-
66-
/* var schemeId = NGL.ColorMakerRegistry.addSelectionScheme( [
67-
[ "red", "64-74 or 134-154 or 222-254 or 310-310 or 322-326" ],
68-
[ "green", "311-322" ],
69-
[ "yellow", "40-63 or 75-95 or 112-133 or 155-173 or 202-221 or 255-277 or 289-309" ],
70-
[ "blue", "1-39 or 96-112 or 174-201 or 278-288" ],
71-
[ "white", "*" ]
72-
], "Transmembrane 3dqb" );
7369
74-
stage.loadFile( "rcsb://3dqb.pdb" ).then( function( o ){
75-
o.addRepresentation( "cartoon", { color: schemeId } ); // pass schemeId here
76-
o.centerView();
77-
} );
78-
*/ });
70+
});
7971
} );
8072
8173
</script>
8274

8375
<div id="viewport" style="width: 100vw; height: 100vh; display:block;"></div>
84-
76+
<div id="messages"></div>
77+
<p><a href="/cesymm/{{structureId}}/multi">Multiple Superposition</a>
78+
</p>
8579
</body>
8680
</html>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset='utf-8'>
5+
<title>{{structureId}} CE-Symm Analysis: Multiple Superposition</title>
6+
</head>
7+
<body>
8+
9+
<h1>CE-Symm Analysis of {{structureId}}: Multiple Superposition</h1>
10+
11+
<script src='//code.jquery.com/jquery-1.11.0.min.js'></script>
12+
13+
<script src="{{url}}"></script>
14+
15+
<script src="https://cdn.rawgit.com/google/palette.js/master/palette.js"></script>
16+
<!--script src="{{pallete_url}}"></script-->
17+
<script src="/js/ngl_ui.js"></script>
18+
<script>
19+
NGL.mainScriptFilePath = "{{url}}";
20+
var stage;
21+
document.onkeypress = function(e) { default_keypress(stage,e); };
22+
23+
document.addEventListener( "DOMContentLoaded", function() {
24+
$.get("{{tsvUrl}}", function(tsv) {
25+
// Parse TSV file
26+
// Each line should contain ResNum/Chain/AminoAcid triplets
27+
// Lines end with tabs, so each line should have 3n+1 columns for n repeats.
28+
var lines = tsv.split("\n")
29+
.filter((x) => !x.startsWith("#") && x.length > 0)
30+
.map((x) => x.split("\t"));
31+
32+
// Check for significant alignment
33+
var colorSele = [];
34+
35+
if( lines.length > 0) {
36+
// Get number of structures from first line
37+
var n_strucs = (lines[0].length - 1) / 3;
38+
39+
// Generate color palette
40+
var colors = palette('cb-Dark2', n_strucs);
41+
42+
// Create selection for each repeat
43+
var seleStr = [];
44+
for (j = 0; j < n_strucs; j++) {
45+
for (i = 0; i < lines.length; i++) {
46+
if (lines[i][3*j] != "-") {
47+
seleStr.push("( " + lines[i][3*j] + " and :" + lines[i][3*j+1] + " )");
48+
}
49+
}
50+
}
51+
for (j = 0; j < n_strucs; j++) {
52+
colorSele.push( ["#" + colors[j], "( "+seleStr.join(" or ")+" ) and /"+j ]);
53+
}
54+
} else {
55+
$('#messages').html("<p>No significant alignment found.</p>");
56+
}
57+
colorSele.push(["lightgrey","*"]);
58+
59+
var schemeId = NGL.ColorMakerRegistry.addSelectionScheme( colorSele, "CE-Symm {{structureId}}" );
60+
61+
stage = new NGL.Stage( "viewport" );
62+
stage.setParameters({ backgroundColor:"white" } );
63+
64+
stage.loadFile( "/cesymm/{{structureId}}/pdb", { defaultRepresentation: false, ext:"pdb" } ).then( function( o ){
65+
o.addRepresentation( "cartoon", { color: schemeId } );
66+
o.addRepresentation( "ball+stick", {
67+
sele: "hetero and not ( water )"
68+
});
69+
o.centerView();
70+
} );
71+
72+
});
73+
} );
74+
75+
</script>
76+
77+
<div id="viewport" style="width: 100vw; height: 100vh; display:block;"></div>
78+
<div id="messages"></div>
79+
<p><a href="/cesymm/{{structureId}}">CE-Symm Alignment</a>
80+
81+
</body>
82+
</html>

0 commit comments

Comments
 (0)