summaryrefslogtreecommitdiff
path: root/webapp/dataset.rb
blob: 82aed3fc0467fc47b91ad711fa986239fb6b2df5 (plain)
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
# dataset.rb
# OpenTox dataset
# Author: Andreas Maunz

module OpenTox

  class Application < Service


    # Get a list of descriptor calculation 
    # @return [text/uri-list] URIs
    get '/dataset/*/pc' do
      dataset=params["captures"][0]
      algorithms = YAML::load_file File.join(ENV['HOME'], ".opentox", "config", "pc_descriptors.yaml")
      list = (algorithms.keys.sort << "AllDescriptors").collect { |name| url_for("/dataset/#{dataset}/pc/#{name}",:full) }.join("\n") + "\n"
      format_output(list)
    end
    
    # Get representation of descriptor calculation
    # @return [String] Representation
    get '/dataset/*/pc/*' do
      dataset = params[:captures][0]
      params[:descriptor] = params[:captures][1]
      descriptors = YAML::load_file File.join(ENV['HOME'], ".opentox", "config", "pc_descriptors.yaml")
      alg_params = [ 
        { DC.description => "Dataset URI", 
          OT.paramScope => "mandatory", 
          DC.title => "dataset_uri" } 
      ]
      if params[:descriptor] != "AllDescriptors"
        descriptors = descriptors[params[:descriptor]]
      else
        alg_params << { 
          DC.description => "Physico-chemical type, one or more of '#{descriptors.collect { |id, info| info[:pc_type] }.uniq.sort.join(",")}'", 
          OT.paramScope => "optional", DC.title => "pc_type" 
        }
        alg_params << { 
          DC.description => "Software Library, one or more of '#{descriptors.collect { |id, info| info[:lib] }.uniq.sort.join(",")}'", 
          OT.paramScope => "optional", DC.title => "lib" 
        }
        descriptors = {:id => "AllDescriptors", :name => "All PC descriptors" } # Comes from pc_descriptors.yaml for single descriptors
      end
    
      if descriptors 
        # Contents
        algorithm = OpenTox::Algorithm.new(url_for("/dataset/#{dataset}/pc/#{params[:descriptor]}",:full))
        mmdata = {
          DC.title => params[:descriptor],
          DC.creator => "andreas@maunz.de",
          DC.description => descriptors[:name],
          RDF.type => [OTA.DescriptorCalculation],
        }
        mmdata[DC.description] << (", pc_type: " + descriptors[:pc_type]) unless descriptors[:id] == "AllDescriptors"
        mmdata[DC.description] << (", lib: " + descriptors[:lib])         unless descriptors[:id] == "AllDescriptors"
        algorithm.metadata=mmdata
        algorithm.parameters = alg_params
        format_output(algorithm)
      else
        resource_not_found_error "Unknown descriptor #{params[:descriptor]}."
      end
    end


    # Calculate PC descriptors
    # Single descriptors or sets of descriptors can be selected
    # Sets are selected via lib and/or pc_type, and take precedence, when also a descriptor is submitted
    # If none of descriptor, lib, and pc_type is submitted, all descriptors are calculated
    # Set composition is induced by intersecting lib and pc_type sets, if appropriate
    # @param [optional, HEADER] accept Accept one of 'application/rdf+xml', 'text/csv', defaults to 'application/rdf+xml'
    # @param [optional, String] descriptor A single descriptor to calculate values for.
    # @param [optional, String] lib One or more descriptor libraries out of [cdk,joelib,openbabel], for whose descriptors to calculate values.
    # @param [optional, String] pc_type One or more descriptor types out of [constitutional,topological,geometrical,electronic,cpsa,hybrid], for whose descriptors to calculate values
    # @return [application/rdf+xml,text/csv] Compound descriptors and values
    post '/dataset/*/pc' do
      dataset=params["captures"][0]
      params.delete('splat')
      params.delete('captures')
      params_array = params.collect{ |k,v| [k.to_sym, v]}
      params = Hash[params_array]
      params[:dataset] = dataset
      descriptor = params[:descriptor].nil? ? "" : params[:descriptor]
      lib = params[:lib].nil? ? "" : params[:lib]
      pc_type = params[:pc_type].nil? ? "" : params[:pc_type]

      task = OpenTox::Task.create(
                                 $task[:uri],
                                 @subjectid,
                                 { RDF::DC.description => "Calculating PC descriptors",
                                   RDF::DC.creator => url_for("/dataset/#{dataset}/pc",:full)
                                 }
                                ) do |task|

       begin
         result_ds = OpenTox::Dataset.new(nil,@subjectid)
         ds=OpenTox::Dataset.find("#{$dataset[:uri]}/#{dataset}",@subjectid)
         $logger.debug "AM: #{ds.compounds.size} compounds"
         ds.compounds.each { |cmpd|
           ds_string = OpenTox::RestClientWrapper.post("#{$compound[:uri]}/#{cmpd.inchi}/pc", params, {:accept => "application/rdf+xml"})
           single_cmpd_ds = OpenTox::Dataset.new(nil,@subjectid)
           single_cmpd_ds.parse_rdfxml(ds_string)
           single_cmpd_ds.get(true)
           result_ds.features = single_cmpd_ds.features unless result_ds.features.size>0 # features assumed to be present already
           result_ds << [ cmpd ] + single_cmpd_ds.data_entries[0]
         }
         result_ds.put @subjectid
         $logger.debug result_ds.uri
         result_ds.uri

       rescue => e
         $logger.debug "#{e.class}: #{e.message}"
         $logger.debug "Backtrace:\n\t#{e.backtrace.join("\n\t")}"
       end

      end
      response['Content-Type'] = 'text/uri-list'
      service_unavailable_error "Service unavailable" if task.cancelled?
      halt 202,task.uri.to_s+"\n"
    end

  end

end