diff options
author | Christoph Helma <helma@in-silico.ch> | 2012-07-26 16:21:02 +0200 |
---|---|---|
committer | Christoph Helma <helma@in-silico.ch> | 2012-07-26 16:21:02 +0200 |
commit | 5be059caa873bd2697acc92c0651ca04aa2a5baa (patch) | |
tree | 9aee3c4997e0a40cdfd10eb86077a74a5b8a789e | |
parent | f85836b4eabe7efe1c29af6bf432cfc3b7b8dd26 (diff) |
initial model service
-rw-r--r-- | application.rb | 122 | ||||
-rw-r--r-- | config.ru | 12 | ||||
-rw-r--r-- | data/.gitignore | 3 | ||||
-rw-r--r-- | lazar.rb | 176 | ||||
-rw-r--r-- | public/robots.txt | 2 | ||||
-rw-r--r-- | views/model.builder | 8 |
6 files changed, 15 insertions, 308 deletions
diff --git a/application.rb b/application.rb index 8d79812..5f38ef8 100644 --- a/application.rb +++ b/application.rb @@ -1,116 +1,14 @@ -require 'rubygems' -gem "opentox-ruby", "~> 4" -require 'opentox-ruby' - -set :lock, true - -@@datadir = "data" - -class PredictionCache < Ohm::Model - attribute :compound_uri - attribute :model_uri - attribute :dataset_uri - - index :compound_uri - index :model_uri -end - -before do - @accept = request.env['HTTP_ACCEPT'] - @accept = 'application/rdf+xml' if @accept == '*/*' or @accept == '' or @accept.nil? - response['Content-Type'] = @accept - @id = request.path_info.match(/^\/\d+/) - unless @id.nil? - @id = @id.to_s.sub(/\//,'').to_i - - @uri = uri @id - @json_file = "#{@@datadir}/#{@id}.json" - raise OpenTox::NotFoundError.new "Model #{@id} not found." unless File.exists? @json_file - - extension = File.extname(request.path_info) - unless extension.empty? - case extension - when ".html" - @accept = 'text/html' - when ".yaml" - @accept = 'application/x-yaml' - when ".json" - @accept = 'application/json' - when ".rdfxml" - @accept = 'application/rdf+xml' - else - raise OpenTox::NotFoundError.new "File format #{extension} not supported." +module OpenTox + class Application < Service + post "/model/:id/?" do + [RDF::OT.featureCalculationAlgorithm, RDF::OT.predictionAlgorithm, RDF::OT.similarityAlgorithm, RDF::OT.trainingDataset , RDF::OT.dependentVariables , RDF::OT.featureDataset].each do |param| + query = "SELECT ?uri FROM <#{@uri}> WHERE {<#{@uri}> <#{param.to_s}> ?uri}" + param_uri = FourStore.query query, "text/uri-list" + param_name = param.to_s.split("#").last.underscore + params[param_name] = param_uri end + #puts params.inspect + RestClientWrapper.post File.join($algorithm[:uri],"lazar","predict"), params end end - - # make sure subjectid is not included in params, subjectid is set as member variable - params.delete(:subjectid) -end - -require 'lazar.rb' - -helpers do - - def next_id - id = Dir["./#{@@datadir}/*json"].collect{|f| File.basename(f.sub(/.json/,'')).to_i}.sort.last - id = 0 if id.nil? - id + 1 - end - - def uri(id) - url_for "/#{id}", :full - end - - def activity(a) - case a.to_s - when "true" - act = "active" - when "false" - act = "inactive" - else - act = "not available" - end - act - end -end - -get '/?' do # get index of models - uri_list = Dir["./#{@@datadir}/*json"].collect{|f| File.basename(f.sub(/.json/,'')).to_i}.sort.collect{|n| uri n}.join("\n") + "\n" - case @accept - when /html/ - response['Content-Type'] = 'text/html' - OpenTox.text_to_html uri_list - else - response['Content-Type'] = 'text/uri-list' - uri_list - end -end - -delete '/:id/?' do - LOGGER.debug "Deleting model with id "+@id.to_s - begin - FileUtils.rm @json_file - if @subjectid and !File.exists? @json_file and @uri - begin - res = OpenTox::Authorization.delete_policies_from_uri(@uri, @subjectid) - LOGGER.debug "Policy deleted for Model URI: #{@uri} with result: #{res}" - rescue - LOGGER.warn "Policy delete error for Model URI: #{@uri}" - end - end - response['Content-Type'] = 'text/plain' - "Model #{@id} deleted." - rescue - raise OpenTox::NotFoundError.new "Model #{@id} does not exist." - end -end - - -delete '/?' do - # TODO delete datasets - FileUtils.rm Dir["#{@@datadir}/*.json"] - PredictionCache.all.each {|cache| cache.delete } - response['Content-Type'] = 'text/plain' - "All models and cached predictions deleted." end @@ -1,7 +1,5 @@ -require 'rubygems' -require 'opentox-ruby' -require 'config/config_ru' -set :app_file, __FILE__ # to get the view path right -run Sinatra::Application -set :raise_errors, false -set :show_exceptions, false
\ No newline at end of file +SERVICE = "model" +require 'bundler' +Bundler.require +require './application.rb' +run OpenTox::Application diff --git a/data/.gitignore b/data/.gitignore deleted file mode 100644 index 59e3edd..0000000 --- a/data/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.rdfxml -*.xls -*.yaml diff --git a/lazar.rb b/lazar.rb deleted file mode 100644 index e4ae4c9..0000000 --- a/lazar.rb +++ /dev/null @@ -1,176 +0,0 @@ -require "haml" - -helpers do - - def yaml_file(id) - file = "#{@@datadir}/#{id}.yaml" - unless File.exists? file # lazy yaml generation - lazar = OpenTox::Model::Lazar.from_json(File.read(@json_file)) - File.open(file,"w+") { |f| f.puts lazar.to_yaml } - end - file - end - - def lazar - OpenTox::Model::Lazar.from_json(File.read(@json_file)) - end - - #def metadata - #lazar.metadata - #end - -end - -# Get model representation -# @return [application/rdf+xml,application/x-yaml,aapplication/json] Model representation -get '/:id/?' do - raise OpenTox::NotFoundError.new "Model #{params[:id]} not found." unless File.exists? @json_file - case @accept - when /application\/rdf\+xml/ - response['Content-Type'] = 'application/rdf+xml' - s = OpenTox::Serializer::Owl.new - s.add_model(@uri,lazar.metadata) - s.to_rdfxml - when /yaml/ - send_file yaml_file(params[:id]), :type => 'application/x-yaml' - when /json/ - send_file @json_file, :type => 'application/json' - when /html/ - response['Content-Type'] = 'text/html' - #OpenTox.text_to_html File.read(yaml_file(params[:id])) - OpenTox.text_to_html JSON.pretty_generate(JSON.parse(File.read(@json_file))) - else - raise OpenTox::BadRequestError.new "Unsupported MIME type '#{@accept}'" - end -end - -get '/:id/metadata.?:ext?' do - raise OpenTox::NotFoundError.new "Model #{params[:id]} not found." unless File.exists? @json_file - @accept = "application/x-yaml" if params[:ext] and params[:ext].match(/yaml/) - case @accept - when /yaml/ - lazar.metadata.to_yaml - else #when /rdf/ and anything else - serializer = OpenTox::Serializer::Owl.new - serializer.add_metadata @uri, lazar.metadata - serializer.to_rdfxml - end -end - -get '/:id/dependent.?:ext?' do - raise OpenTox::NotFoundError.new "Model #{params[:id]} not found." unless File.exists? @json_file - @accept = "application/x-yaml" if params[:ext] and params[:ext].match(/yaml/) - feature_uri = lazar.metadata[OT.dependentVariables] - case @accept - when /yaml/ - OpenTox::Feature.find(feature_uri, @subjectid).to_yaml - when "text/uri-list" - feature_uri - when /rdf/ - OpenTox::Feature.find(feature_uri, @subjectid).to_rdfxml - when /html/ - OpenTox.text_to_html OpenTox::Feature.find(feature_uri, @subjectid).to_yaml - else - raise OpenTox::BadRequestError.new "Unsupported MIME type '#{@accept}'" - end -end - -get '/:id/predicted/:prop' do - raise OpenTox::NotFoundError.new "Model #{params[:id]} not found." unless File.exists? @json_file - if params[:prop] == "value" or params[:prop] == "confidence" - #feature = eval "YAML.load_file(@json_file).prediction_#{params[:prop]}_feature" - feature = eval "lazar.prediction_#{params[:prop]}_feature" - case @accept - when /yaml/ - content_type "application/x-yaml" - feature.metadata.to_yaml - when /rdf/ - content_type "application/rdf+xml" - feature.to_rdfxml - when /html/ - content_type "text/html" - OpenTox.text_to_html feature.metadata.to_yaml - else - raise OpenTox::BadRequestError.new "Unsupported MIME type '#{@accept}'" - end - else - raise OpenTox::BadRequestError.new "Unknown URI #{@uri}" - end -end - -get '/:id/predicted.?:ext?' do - raise OpenTox::NotFoundError.new "Model #{params[:id]} not found." unless File.exists? @json_file - @accept = "application/x-yaml" if params[:ext] and params[:ext].match(/yaml/) - features = lazar.prediction_features - case @accept - when "text/uri-list" - "#{features.collect{|f| f.uri}.join("\n")}\n" - when /yaml/ - features.to_yaml - when /rdf/ - serializer = OpenTox::Serializer::Owl.new - features.each{|f| serializer.add_feature(f.uri,f.metadata)} - serializer.to_rdfxml - when /html/ - OpenTox.text_to_html features.to_yaml - else - raise OpenTox::BadRequestError.new "Unsupported MIME type '#{@accept}'" - end -end - -# Store a lazar model. This method should not be called directly, use OpenTox::Algorithm::Lazar to create a lazar model -# @param [Body] lazar Model representation in YAML format -# @return [String] Model URI -post '/?' do # create model - raise OpenTox::BadRequestError.new "MIME type \"#{request.content_type}\" not supported." unless request.content_type.match(/json/) - @id = next_id - @uri = uri @id - @json_file = "#{@@datadir}/#{@id}.json" - hash = Yajl::Parser.parse request.env["rack.input"].read - hash["uri"] = @uri - value_feature_uri = File.join( @uri, "predicted", "value") - confidence_feature_uri = File.join( @uri, "predicted", "confidence") - hash["metadata"][OT.predictedVariables] = [value_feature_uri, confidence_feature_uri] - File.open(@json_file,"w+"){|f| f.puts Yajl::Encoder.encode(hash)} - OpenTox::Authorization.check_policy(@uri, @subjectid) if File.exists? @json_file - response['Content-Type'] = 'text/uri-list' - @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 - - raise OpenTox::NotFoundError.new "Model #{params[:id]} does not exist." unless File.exists? @json_file - - raise OpenTox::NotFoundError.new "No compound_uri or dataset_uri parameter." unless compound_uri = params[:compound_uri] or dataset_uri = params[:dataset_uri] - #@lazar = YAML.load_file @json_file - - response['Content-Type'] = 'text/uri-list' - - if compound_uri - cache = PredictionCache.find(:model_uri => lazar.uri, :compound_uri => compound_uri).first - if cache and uri_available?(cache.dataset_uri) - return cache.dataset_uri - else - 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 #{$!} " - raise "Prediction of #{compound_uri} with #{lazar.uri} failed." - end - end - elsif dataset_uri - task = OpenTox::Task.create("Predict dataset",url_for("/#{lazar.id}", :full)) do |task| - lazar.predict_dataset(dataset_uri, @subjectid, task).uri - end - raise OpenTox::ServiceUnavailableError.newtask.uri+"\n" if task.status == "Cancelled" - halt 202,task.uri - end - -end diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index 1f53798..0000000 --- a/public/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: / diff --git a/views/model.builder b/views/model.builder deleted file mode 100644 index dbb1ca1..0000000 --- a/views/model.builder +++ /dev/null @@ -1,8 +0,0 @@ -xml.instruct! -xml.model do - xml.uri url_for("/", :full) + @model.id.to_s - xml.name @model.name - xml.training_dataset_uri @model.training_dataset_uri - xml.feature_dataset_uri @model.feature_dataset_uri - xml.finished @model.finished -end |