opentox-ruby 0.0.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,3 +39,48 @@
39
39
 
40
40
  # Uncomment for verbose logging
41
41
  # :logger: debug
42
+ # :backtrace: 1
43
+
44
+
45
+ # OpenSSO Authorization
46
+ # set ":server: " to disable A&A
47
+ :authorization:
48
+ :server: "https://opensso.in-silico.ch"
49
+ :free_request: #request-method not controlled by A&A
50
+ - "GET"
51
+ :authenticate_request: #only for authenticated user
52
+ - "POST"
53
+ :authorize_request: #only for authenticated and authorizeduser
54
+ - "DELETE"
55
+ - "PUT"
56
+ # Exceptions:
57
+ :free_uris: #request-method for uri not controlled by A&A
58
+ ? - :GET
59
+ : - !ruby/regexp /localhost\/algorithm/
60
+ - "http://localhost/dataset"
61
+ - "http://localhost/model"
62
+ - "http://localhost/validation"
63
+ - "http://localhost/validation/crossvalidation"
64
+ - "http://localhost/validation/reach_report"
65
+ - "http://localhost/validation/reach_report/crossvalidation"
66
+ - "http://localhost/validation/report"
67
+ - "http://localhost/validation/report/crossvalidation"
68
+ - "http://localhost/validation/reach_report/qmrf"
69
+ ? - :GET
70
+ - :POST
71
+ : - !ruby/regexp /localhost\/toxcreate/
72
+ - !ruby/regexp /localhost\/task/
73
+ - !ruby/regexp /localhost\/compound/
74
+ ? - :PUT
75
+ : - !ruby/regexp /localhost\/task/
76
+
77
+ :authorize_exceptions: #request-method for uri only authenticated, no authorization
78
+ ? - :POST
79
+ : - !ruby/regexp /localhost\/algorithm/
80
+ - "http://localhost/dataset"
81
+ - "http://localhost/model"
82
+ - "http://localhost/validation"
83
+ - !ruby/regexp /localhost\/validation\/[a-z,A-Z,\/,_\-]*$/
84
+
85
+
86
+
@@ -0,0 +1,53 @@
1
+ <!DOCTYPE Policies PUBLIC "-//Sun Java System Access Manager7.1 2006Q3
2
+ Admin CLI DTD//EN" "jar://com/sun/identity/policy/policyAdmin.dtd">
3
+
4
+ <Policies>
5
+ <Policy name="policy_user" referralPolicy="false" active="true">
6
+ <Rule name="rule_user">
7
+ <ServiceName name="iPlanetAMWebAgentService" />
8
+ <ResourceName name="uri"/>
9
+ <AttributeValuePair>
10
+ <Attribute name="GET" />
11
+ <Value>allow</Value>
12
+ </AttributeValuePair>
13
+ <AttributeValuePair>
14
+ <Attribute name="POST" />
15
+ <Value>allow</Value>
16
+ </AttributeValuePair>
17
+ <AttributeValuePair>
18
+ <Attribute name="PUT" />
19
+ <Value>allow</Value>
20
+ </AttributeValuePair>
21
+ <AttributeValuePair>
22
+ <Attribute name="DELETE" />
23
+ <Value>allow</Value>
24
+ </AttributeValuePair>
25
+ </Rule>
26
+ <Subjects name="subjects_user" description="">
27
+ <Subject name="subject_user" type="LDAPUsers" includeType="inclusive">
28
+ <AttributeValuePair>
29
+ <Attribute name="Values"/>
30
+ <Value>uid=guest,ou=people,dc=opentox,dc=org</Value>
31
+ </AttributeValuePair>
32
+ </Subject>
33
+ </Subjects>
34
+ </Policy>
35
+ <Policy name="policy_group" referralPolicy="false" active="true">
36
+ <Rule name="rule_group">
37
+ <ServiceName name="iPlanetAMWebAgentService" />
38
+ <ResourceName name="uri"/>
39
+ <AttributeValuePair>
40
+ <Attribute name="GET" />
41
+ <Value>allow</Value>
42
+ </AttributeValuePair>
43
+ </Rule>
44
+ <Subjects name="subjects_group" description="">
45
+ <Subject name="subject_group" type="LDAPGroups" includeType="inclusive">
46
+ <AttributeValuePair>
47
+ <Attribute name="Values"/>
48
+ <Value>cn=member,ou=groups,dc=opentox,dc=org</Value>
49
+ </AttributeValuePair>
50
+ </Subject>
51
+ </Subjects>
52
+ </Policy>
53
+ </Policies>
@@ -0,0 +1,53 @@
1
+ <!DOCTYPE Policies PUBLIC "-//Sun Java System Access Manager7.1 2006Q3
2
+ Admin CLI DTD//EN" "jar://com/sun/identity/policy/policyAdmin.dtd">
3
+
4
+ <Policies>
5
+ <Policy name="policy_user" referralPolicy="false" active="true">
6
+ <Rule name="rule_user">
7
+ <ServiceName name="iPlanetAMWebAgentService" />
8
+ <ResourceName name="uri"/>
9
+ <AttributeValuePair>
10
+ <Attribute name="GET" />
11
+ <Value>allow</Value>
12
+ </AttributeValuePair>
13
+ <AttributeValuePair>
14
+ <Attribute name="POST" />
15
+ <Value>allow</Value>
16
+ </AttributeValuePair>
17
+ <AttributeValuePair>
18
+ <Attribute name="PUT" />
19
+ <Value>allow</Value>
20
+ </AttributeValuePair>
21
+ <AttributeValuePair>
22
+ <Attribute name="DELETE" />
23
+ <Value>allow</Value>
24
+ </AttributeValuePair>
25
+ </Rule>
26
+ <Subjects name="subjects_user" description="">
27
+ <Subject name="subject_user" type="LDAPUsers" includeType="inclusive">
28
+ <AttributeValuePair>
29
+ <Attribute name="Values"/>
30
+ <Value>uid=guest,ou=people,dc=opentox,dc=org</Value>
31
+ </AttributeValuePair>
32
+ </Subject>
33
+ </Subjects>
34
+ </Policy>
35
+ <Policy name="policy_group" referralPolicy="false" active="true">
36
+ <Rule name="rule_group">
37
+ <ServiceName name="iPlanetAMWebAgentService" />
38
+ <ResourceName name="uri"/>
39
+ <AttributeValuePair>
40
+ <Attribute name="GET" />
41
+ <Value>allow</Value>
42
+ </AttributeValuePair>
43
+ </Rule>
44
+ <Subjects name="subjects_group" description="">
45
+ <Subject name="subject_group" type="LDAPGroups" includeType="inclusive">
46
+ <AttributeValuePair>
47
+ <Attribute name="Values"/>
48
+ <Value>cn=member,ou=groups,dc=opentox,dc=org</Value>
49
+ </AttributeValuePair>
50
+ </Subject>
51
+ </Subjects>
52
+ </Policy>
53
+ </Policies>
data/lib/to-html.rb ADDED
@@ -0,0 +1,112 @@
1
+
2
+ OT_LOGO = "http://opentox.informatik.uni-freiburg.de/ot-logo.png"
3
+
4
+ class String
5
+
6
+ # encloses URI in text with with link tag
7
+ # @return [String] new text with marked links
8
+ def link_urls
9
+ self.gsub(/(?i)http(s?):\/\/[^\r\n\s']*/, '<a href=\0>\0</a>')
10
+ end
11
+ end
12
+
13
+ module OpenTox
14
+
15
+ # produces a html page for making web services browser friendly
16
+ # format of text (=string params) is preserved (e.g. line breaks)
17
+ # urls are marked as links
18
+ # @example post params:
19
+ # [ [ [:mandatory_param_1], [:mandatory_param_2], [:optional_param,"default_value"] ],
20
+ # [ [:alteranative_mandatory_param_1], [:alteranative_mandatory_param_2] ]
21
+ # ]
22
+ # @param [String] text this is the actual content,
23
+ # @param [optional,String] related_links info on related resources
24
+ # @param [optional,String] description general info
25
+ # @param [optional,Array] post_params, array of arrays containing info on POST operation, see example
26
+ # @return [String] html page
27
+ def self.text_to_html( text, subjectid=nil, related_links=nil, description=nil, post_params=nil )
28
+
29
+ # TODO add title as parameter
30
+ title = nil #$sinatra.url_for($sinatra.request.env['PATH_INFO'], :full) if $sinatra
31
+ html = "<html>"
32
+ html += "<title>"+title+"</title>" if title
33
+ html += "<img src="+OT_LOGO+"><body>"
34
+
35
+ if AA_SERVER
36
+ user = OpenTox::Authorization.get_user(subjectid) if subjectid
37
+ html += "<pre><p align=\"right\">"
38
+ unless user
39
+ html += "You are currently not logged in to "+$url_provider.url_for("",:full)+
40
+ ", <a href="+$url_provider.url_for("/login",:full)+">login</a>"
41
+ else
42
+ html += "You are logged in as '#{user}' to "+$url_provider.url_for("",:full)+
43
+ ", <a href="+$url_provider.url_for("/logout",:full)+">logout</a>"
44
+ end
45
+ html += " </p></pre>"
46
+ end
47
+
48
+ html += "<h3>Description</h3><pre><p>"+description.link_urls+"</p></pre>" if description
49
+ html += "<h3>Related links</h3><pre><p>"+related_links.link_urls+"</p></pre>" if related_links
50
+ if post_params
51
+ html += "<h3>POST parameters</h3>"
52
+ count = 0
53
+ post_params.each do |p|
54
+ html += "<pre><p>alternatively:</p></pre>" if count > 0
55
+ html += "<pre><p><table><thead><tr><th>param</th><th>default_value</th></tr></thead>"
56
+ p.each do |k,v|
57
+ html += "<tr><th>"+k.to_s+"</th><th>"+(v!=nil ? v.to_s : "<i>mandatory</i>")+"</th></tr>"
58
+ end
59
+ html += "</table></p></pre>"
60
+ count += 1
61
+ end
62
+ end
63
+ html += "<h3>Content</h3>" if description || related_links
64
+ html += "<pre><p style=\"padding:15px; border:10px solid \#5D308A\">"
65
+ html += text.link_urls
66
+ html += "</p></pre></body><html>"
67
+ html
68
+ end
69
+
70
+ def self.login( msg=nil )
71
+ html = "<html><title>Login</title><img src="+OT_LOGO+"><body>"
72
+ html += "<form method='POST' action='"+$url_provider.url_for("/login",:full)+"'>"
73
+ html += "<pre><p style=\"padding:15px; border:10px solid \#5D308A\">"
74
+ html += msg+"\n\n" if msg
75
+ html += "Please login to "+$url_provider.url_for("",:full)+"\n\n"
76
+ html += "<table border=0>"
77
+ html += "<tr><td>user:</td><td><input type='text' name='user' size='15' /></td></tr>"+
78
+ "<tr><td>password:</td><td><input type='password' name='password' size='15' /></td></tr>"+
79
+ #"<input type=hidden name=back_to value="+back_to.to_s+">"+
80
+ "<tr><td><input type='submit' value='Login' /></td></tr>"
81
+ html += "</table></p></pre></form></body><html>"
82
+ html
83
+ end
84
+ end
85
+
86
+ =begin
87
+ get '/logout/?' do
88
+ response.set_cookie("subjectid",{:value=>nil})
89
+ content_type "text/html"
90
+ content = "Sucessfully logged out from "+$url_provider.url_for("",:full)
91
+ OpenTox.text_to_html(content)
92
+ end
93
+
94
+ get '/login/?' do
95
+ content_type "text/html"
96
+ OpenTox.login
97
+ end
98
+
99
+ post '/login/?' do
100
+ subjectid = OpenTox::Authorization.authenticate(params[:user], params[:password])
101
+ if (subjectid)
102
+ response.set_cookie("subjectid",{:value=>subjectid})
103
+ content_type "text/html"
104
+ content = "Sucessfully logged in as '"+params[:user]+"' to "+$url_provider.url_for("",:full)
105
+ OpenTox.text_to_html(content,subjectid)
106
+ else
107
+ content_type "text/html"
108
+ OpenTox.login("Login failed, please try again")
109
+ end
110
+ end
111
+ =end
112
+
data/lib/validation.rb CHANGED
@@ -1,70 +1,196 @@
1
1
  module OpenTox
2
- class Validation
2
+ class Validation
3
3
  include OpenTox
4
-
5
- attr_accessor :report_uri, :qmrf_report_uri
6
-
7
- def self.create_crossvalidation(params)
8
- params[:uri] = File.join(CONFIG[:services]['opentox-validation'], "crossvalidation")
9
- params[:num_folds] = 10 unless params[:num_folds]
10
- params[:random_seed] = 2 unless params[:random_seed]
11
- params[:stratified] = false unless params[:stratified]
12
- uri = OpenTox::RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/crossvalidation"),params,nil,false)
13
- OpenTox::Validation.new(uri)
14
- end
15
-
16
- def create_report
17
- @report_uri = RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/report/crossvalidation"), :validation_uris => @uri).to_s
18
- @report_uri
4
+
5
+ # find validation, raises error if not found
6
+ # @param [String] uri
7
+ # @param [String,optional] subjectid
8
+ # @return [OpenTox::Validation]
9
+ def self.find( uri, subjectid=nil )
10
+ val = Validation.new(uri)
11
+ val.load_metadata( subjectid )
12
+ val
19
13
  end
20
-
21
- def create_qmrf_report
22
- @qmrf_report_uri = RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/reach_report/qmrf"), :model_uri => @uri).to_s
23
- @qmrf_report_uri
14
+
15
+ # creates a validation object from crossvaldiation statistics, raise error if not found
16
+ # (as crossvaldiation statistics are returned as an average valdidation over all folds)
17
+ # @param [String] crossvalidation uri
18
+ # @param [String,optional] subjectid
19
+ # @return [OpenTox::Validation]
20
+ def self.from_cv_statistics( crossvalidation_uri, subjectid=nil )
21
+ find( File.join(crossvalidation_uri, 'statistics'),subjectid )
24
22
  end
25
-
26
- def summary(type)
27
- v = YAML.load RestClientWrappper.get(File.join(@uri, 'statistics'),:accept => "application/x-yaml").to_s
28
-
29
- case type
30
- when "classification"
31
- tp=0; tn=0; fp=0; fn=0; n=0
32
- v[:classification_statistics][:confusion_matrix][:confusion_matrix_cell].each do |cell|
33
- if cell[:confusion_matrix_predicted] == "true" and cell[:confusion_matrix_actual] == "true"
34
- tp = cell[:confusion_matrix_value]
35
- n += tp
36
- elsif cell[:confusion_matrix_predicted] == "false" and cell[:confusion_matrix_actual] == "false"
37
- tn = cell[:confusion_matrix_value]
38
- n += tn
39
- elsif cell[:confusion_matrix_predicted] == "false" and cell[:confusion_matrix_actual] == "true"
40
- fn = cell[:confusion_matrix_value]
41
- n += fn
42
- elsif cell[:confusion_matrix_predicted] == "true" and cell[:confusion_matrix_actual] == "false"
43
- fp = cell[:confusion_matrix_value]
44
- n += fp
23
+
24
+ # loads metadata via yaml from validation object
25
+ # fields (like for example the validated model) can be acces via validation.metadata[OT.model]
26
+ def load_metadata( subjectid=nil )
27
+ @metadata = YAML.load(OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid, :accept => "application/x-yaml"}))
28
+ end
29
+
30
+ # PENDING: creates summary as used for ToxCreate
31
+ def summary
32
+ if @metadata[OT.classificationStatistics]
33
+ res = {
34
+ :nr_predictions => @metadata[OT.numInstances] - @metadata[OT.numUnpredicted],
35
+ :correct_predictions => @metadata[OT.classificationStatistics][OT.percentCorrect],
36
+ :weighted_area_under_roc => @metadata[OT.classificationStatistics][OT.weightedAreaUnderRoc],
37
+ }
38
+ @metadata[OT.classificationStatistics][OT.classValueStatistics].each do |s|
39
+ if s[OT.classValue].to_s=="true"
40
+ res[:true_positives] = s[OT.numTruePositives]
41
+ res[:false_positives] = s[OT.numFalsePositives]
42
+ res[:true_negatives] = s[OT.numTrueNegatives]
43
+ res[:false_negatives] = s[OT.numFalseNegatives]
44
+ res[:sensitivity] = s[OT.truePositiveRate]
45
+ res[:specificity] = s[OT.falsePositiveRate]
46
+ break
45
47
  end
46
48
  end
49
+ res
50
+ elsif @metadata[OT.regressionStatistics]
47
51
  {
48
- :nr_predictions => n,
49
- :true_positives => tp,
50
- :false_positives => fp,
51
- :true_negatives => tn,
52
- :false_negatives => fn,
53
- :correct_predictions => 100*(tp+tn).to_f/n,
54
- :weighted_area_under_roc => v[:classification_statistics][:weighted_area_under_roc].to_f,
55
- :sensitivity => tp.to_f/(tp+fn),
56
- :specificity => tn.to_f/(tn+fp),
57
- }
58
- when "regression"
59
- {
60
- :nr_predictions => v[:num_instances] - v[:num_unpredicted],
61
- :r_square => v[:regression_statistics][:r_square],
62
- :root_mean_squared_error => v[:regression_statistics][:root_mean_squared_error],
63
- :mean_absolute_error => v[:regression_statistics][:mean_absolute_error],
52
+ :nr_predictions => @metadata[OT.numInstances] - @metadata[OT.numUnpredicted],
53
+ :r_square => @metadata[OT.regressionStatistics][OT.rSquare],
54
+ :root_mean_squared_error => @metadata[OT.regressionStatistics][OT.rootMeanSquaredError],
55
+ :mean_absolute_error => @metadata[OT.regressionStatistics][OT.meanAbsoluteError],
64
56
  }
65
57
  end
66
58
  end
59
+ end
60
+
61
+ class Crossvalidation
62
+ include OpenTox
63
+
64
+ attr_reader :report
65
+
66
+ # find crossvalidation, raises error if not found
67
+ # @param [String] uri
68
+ # @param [String,optional] subjectid
69
+ # @return [OpenTox::Crossvalidation]
70
+ def self.find( uri, subjectid=nil )
71
+ cv = Crossvalidation.new(uri)
72
+ cv.load_metadata( subjectid )
73
+ cv
74
+ end
75
+
76
+ # creates a crossvalidations, waits until it finishes, may take some time
77
+ # @param [Hash] params (required:algorithm_uri,dataset_uri,prediction_feature, optional:algorithm_params,num_folds(10),random_seed(1),stratified(false))
78
+ # @param [String,optional] subjectid
79
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
80
+ # @return [OpenTox::Crossvalidation]
81
+ def self.create( params, subjectid=nil, waiting_task=nil )
82
+ params[:subjectid] = subjectid if subjectid
83
+ uri = OpenTox::RestClientWrapper.post( File.join(CONFIG[:services]["opentox-validation"],"crossvalidation"),
84
+ params,{:content_type => "text/uri-list"},waiting_task )
85
+ Crossvalidation.new(uri)
86
+ end
67
87
 
68
- end
88
+ # looks for report for this crossvalidation, creates a report if no report is found
89
+ # @param [String,optional] subjectid
90
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
91
+ # @return [String] report uri
92
+ def find_or_create_report( subjectid=nil, waiting_task=nil )
93
+ @report = CrossvalidationReport.find_for_crossvalidation(@uri, subjectid) unless @report
94
+ @report = CrossvalidationReport.create(@uri, subjectid, waiting_task) unless @report
95
+ @report.uri
96
+ end
97
+
98
+ # loads metadata via yaml from crossvalidation object
99
+ # fields (like for example the validations) can be acces via validation.metadata[OT.validation]
100
+ def load_metadata( subjectid=nil )
101
+ @metadata = YAML.load(OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid, :accept => "application/x-yaml"}))
102
+ end
103
+
104
+ # PENDING: creates summary as used for ToxCreate
105
+ def summary( subjectid=nil )
106
+ Validation.from_cv_statistics( @uri, subjectid ).summary
107
+ end
108
+ end
109
+
110
+ class ValidationReport
111
+ include OpenTox
112
+
113
+ # finds ValidationReport for a particular validation
114
+ # @param [String] crossvalidation uri
115
+ # @param [String,optional] subjectid
116
+ # @return [OpenTox::ValidationReport] nil if no report found
117
+ def self.find_for_validation( validation_uri, subjectid=nil )
118
+ uris = RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
119
+ "/report/validation?validation="+validation_uri), {:subjectid => subjectid}).chomp.split("\n")
120
+ uris.size==0 ? nil : ValidationReport.new(uris[-1])
121
+ end
122
+
123
+ end
124
+
125
+ class CrossvalidationReport
126
+ include OpenTox
127
+
128
+ # finds CrossvalidationReport via uri, raises error if not found
129
+ # @param [String] uri
130
+ # @param [String,optional] subjectid
131
+ # @return [OpenTox::CrossvalidationReport]
132
+ def self.find( uri, subjectid=nil )
133
+ # PENDING load report data?
134
+ OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid})
135
+ CrossvalidationReport.new(uri)
136
+ end
137
+
138
+ # finds CrossvalidationReport for a particular crossvalidation
139
+ # @param [String] crossvalidation uri
140
+ # @param [String,optional] subjectid
141
+ # @return [OpenTox::CrossvalidationReport] nil if no report found
142
+ def self.find_for_crossvalidation( crossvalidation_uri, subjectid=nil )
143
+ uris = RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
144
+ "/report/crossvalidation?crossvalidation="+crossvalidation_uri), {:subjectid => subjectid}).chomp.split("\n")
145
+ uris.size==0 ? nil : CrossvalidationReport.new(uris[-1])
146
+ end
147
+
148
+ # creates a crossvalidation report via crossvalidation
149
+ # @param [String] crossvalidation uri
150
+ # @param [String,optional] subjectid
151
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
152
+ # @return [OpenTox::CrossvalidationReport]
153
+ def self.create( crossvalidation_uri, subjectid=nil, waiting_task=nil )
154
+ uri = RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/report/crossvalidation"),
155
+ { :validation_uris => crossvalidation_uri, :subjectid => subjectid }, {}, waiting_task )
156
+ CrossvalidationReport.new(uri)
157
+ end
158
+ end
159
+
160
+ class QMRFReport
161
+ include OpenTox
162
+
163
+ # finds QMRFReport, raises Error if not found
164
+ # @param [String] uri
165
+ # @param [String,optional] subjectid
166
+ # @return [OpenTox::QMRFReport]
167
+ def self.find( uri, subjectid=nil )
168
+ # PENDING load crossvalidation data?
169
+ OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid})
170
+ QMRFReport.new(uri)
171
+ end
172
+
173
+ # finds QMRF report for a particular model
174
+ # @param [String] model_uri
175
+ # @param [String,optional] subjectid
176
+ # @return [OpenTox::QMRFReport] nil if no report found
177
+ def self.find_for_model( model_uri, subjectid=nil )
178
+ uris = RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
179
+ "/reach_report/qmrf?model="+model_uri), {:subjectid => subjectid}).chomp.split("\n")
180
+ uris.size==0 ? nil : QMRFReport.new(uris[-1])
181
+ end
182
+
183
+ # creates a qmrf report via model
184
+ # @param [String] model_uri
185
+ # @param [String,optional] subjectid
186
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
187
+ # @return [OpenTox::QMRFReport]
188
+ def self.create( model_uri, subjectid=nil, waiting_task=nil )
189
+ uri = RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/reach_report/qmrf"),
190
+ { :model_uri => model_uri, :subjectid => subjectid }, {}, waiting_task )
191
+ QMRFReport.new(uri)
192
+ end
193
+ end
194
+
69
195
  end
70
196