1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
require "haml"
helpers do
def uri_available?(urlStr)
url = URI.parse(urlStr)
subjectid = params[:subjectid] if params[:subjectid]
subjectid = request.env['HTTP_SUBJECTID'] if !subjectid and request.env['HTTP_SUBJECTID']
unless subjectid
Net::HTTP.start(url.host, url.port) do |http|
return http.head(url.request_uri).code == "200"
end
else
Net::HTTP.start(url.host, url.port) do |http|
return http.post(url.request_uri, "subjectid=#{subjectid}").code == "202"
end
end
end
end
# Get model representation
# @return [application/rdf+xml,application/x-yaml] Model representation
get '/:id/?' do
accept = request.env['HTTP_ACCEPT']
accept = "application/rdf+xml" if accept == '*/*' or accept == '' or accept.nil?
# workaround for browser links
case params[:id]
when /.yaml$/
params[:id].sub!(/.yaml$/,'')
accept = 'application/x-yaml'
when /.rdf$/
params[:id].sub!(/.rdf$/,'')
accept = 'application/rdf+xml'
end
halt 404, "Model #{params[:id]} not found." unless model = ModelStore.get(params[:id])
lazar = YAML.load model.yaml
case accept
when /application\/rdf\+xml/
s = OpenTox::Serializer::Owl.new
s.add_model(url_for('/lazar',:full),lazar.metadata)
response['Content-Type'] = 'application/rdf+xml'
s.to_rdfxml
when /yaml/
response['Content-Type'] = 'application/x-yaml'
model.yaml
else
halt 400, "Unsupported MIME type '#{accept}'"
end
end
get '/:id/metadata.?:ext?' do
metadata = YAML.load(ModelStore.get(params[:id]).yaml).metadata
accept = request.env['HTTP_ACCEPT']
accept = "application/rdf+xml" if accept == '*/*' or accept == '' or accept.nil?
if params[:ext]
case params[:ext]
when "yaml"
accept = 'application/x-yaml'
when "rdf", "rdfxml"
accept = 'application/rdf+xml'
end
end
response['Content-Type'] = accept
case accept
when /yaml/
metadata.to_yaml
else #when /rdf/ and anything else
serializer = OpenTox::Serializer::Owl.new
serializer.add_metadata url_for("/#{params[:id]}",:full), metadata
serializer.to_rdfxml
end
end
# Store a lazar model. This method should not be called directly, use OpenTox::Algorithm::Lazr to create a lazar model
# @param [Body] lazar Model representation in YAML format
# @return [String] Model URI
post '/?' do # create model
halt 400, "MIME type \"#{request.content_type}\" not supported." unless request.content_type.match(/yaml/)
model = ModelStore.create
model.subjectid = params[:subjectid] if params[:subjectid]
model.subjectid = request.env["HTTP_SUBJECTID"] if !model.subjectid and request.env["HTTP_SUBJECTID"]
model.uri = url_for("/#{model.id}", :full)
lazar = YAML.load request.env["rack.input"].read
lazar.uri = model.uri
model.yaml = lazar.to_yaml
model.save
model.uri
end
# Make a lazar prediction. Predicts either a single compound or all compounds from a dataset
# @param [optional,String] dataset_uri URI of the dataset to be predicted
# @param [optional,String] compound_uri URI of the compound to be predicted
# @param [optional,Header] Accept Content-type of prediction, can be either `application/rdf+xml or application/x-yaml`
# @return [text/uri-list] URI of prediction task (dataset prediction) or prediction dataset (compound prediction)
post '/:id/?' do
subjectid = params[:subjectid] if params[:subjectid]
subjectid = request.env["HTTP_SUBJECTID"] if !subjectid and request.env["HTTP_SUBJECTID"]
@lazar = YAML.load ModelStore.get(params[:id]).yaml
halt 404, "Model #{params[:id]} does not exist." unless @lazar
halt 404, "No compound_uri or dataset_uri parameter." unless compound_uri = params[:compound_uri] or dataset_uri = params[:dataset_uri]
response['Content-Type'] = 'text/uri-list'
if compound_uri
cache = PredictionCache.first(:model_uri => @lazar.uri, :compound_uri => compound_uri)
return cache.dataset_uri if cache and uri_available?(cache.dataset_uri)
begin
prediction_uri = @lazar.predict(compound_uri,true,subjectid).uri
PredictionCache.create(:model_uri => @lazar.uri, :compound_uri => compound_uri, :dataset_uri => prediction_uri)
prediction_uri
rescue
LOGGER.error "Lazar prediction failed for #{compound_uri} with #{$!} "
halt 500, "Prediction of #{compound_uri} with #{@lazar.uri} failed."
end
elsif dataset_uri
task = OpenTox::Task.create("Predict dataset",url_for("/#{@lazar.id}", :full)) do
@lazar.predict_dataset(dataset_uri, subjectid).uri
end
halt 503,task.uri+"\n" if task.status == "Cancelled"
halt 202,task.uri
end
end
|