summaryrefslogtreecommitdiff
path: root/lazar.rb
blob: 2b234953c39f1c90d65a87dfe7a9f7a65407a94d (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
124
125
126
127
128
129
130
131
132
133
134
require 'datamapper'

DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/db/#{ENV['RACK_ENV']}.db")

class LazarModel
	include DataMapper::Resource
	property :id, Serial
	property :activity_dataset_uri, String, :length => 256 # default is too short for URIs
	property :feature_dataset_uri, String, :length => 256 # default is too short for URIs
	property :created_at, DateTime

	def uri
		File.join(OpenTox::Model::LazarClassification.base_uri,"lazar_classification", self.id.to_s)
	end

	def predict(compound)

		training_activities = OpenTox::Dataset.find :uri => @activity_dataset_uri
		# TODO: find database activities
		# TODO: find prediction
		training_features = OpenTox::Dataset.find :uri => @feature_dataset_uri

		prediction_dataset = OpenTox::Dataset.find_or_create(:name => training_activities.name + '_predictions')
		prediction_neighbors = OpenTox::Dataset.find_or_create(:name => training_activities.name + '_neighbors')
		prediction_features = OpenTox::Dataset.find_or_create(:name => training_activities.name + '_prediction_features')

		feature_uris = compound.match(training_features)
		prediction_features.add({compound.uri => feature_uris}.to_yaml)

		conf = 0.0
		neighbors = []

		training_features.compounds.each do |neighbor|
			sim = OpenTox::Algorithm::Similarity.weighted_tanimoto(training_features,neighbor,prediction_features,compound).to_f
			if sim > 0.3
				neighbors << neighbor.uri
				training_activities.features(neighbor).each do |a|
					case OpenTox::Feature.new(:uri => a.uri).value('classification').to_s
					when 'true'
						conf += OpenTox::Utils.gauss(sim) 
					when 'false'
						conf -= OpenTox::Utils.gauss(sim)
					end
				end
			end
		end
		conf = conf/neighbors.size
		if conf > 0.0
			classification = true
		elsif conf < 0.0
			classification = false
		end

		prediction = OpenTox::Feature.new(:name => training_activities.name + " prediction", :classification => classification, :confidence => conf)
		prediction_neighbors.add({compound.uri => neighbors}.to_yaml)
		prediction_dataset.add({compound.uri => [prediction.uri]}.to_yaml)

		prediction.uri

	end
end

# automatically create the post table
LazarModel.auto_migrate! #unless LazarModel.table_exists?
LazarModel.auto_migrate! if ENV['RACK_ENV'] == 'test'

get '/lazar_classification/?' do # get index of models
	LazarModel.all.collect{|m| m.uri}.join("\n")
end

get '/lazar_classification/:id/?' do
	halt 404, "Model #{params[:id]} not found." unless @model = LazarModel.get(params[:id])
	@model.to_yaml
end

delete '/lazar_classification/:id/?' do
	halt 404, "Model #{params[:id]} not found." unless @model = LazarModel.get(params[:id])
	@model.destroy
	"Model #{params[:id]} succesfully deleted."
end

post '/lazar_classification/?' do # create model
	halt 404, "Dataset #{params[:activity_dataset_uri]} not found" unless  OpenTox::Dataset.find(:uri => params[:activity_dataset_uri])
	halt 404, "Dataset #{params[:feature_dataset_uri]} not found" unless OpenTox::Dataset.find(:uri => params[:feature_dataset_uri])
	model = LazarModel.new(params)
	model.save
	model.uri
end

# PREDICTIONS
post '/lazar_classification/:id/?' do # create prediction
	halt 404, "Model #{params[:id]} not found." unless @model = LazarModel.get(params[:id])
	compound = OpenTox::Compound.new :uri => params[:compound_uri]
	@model.predict(compound)
end

get '/lazar_classification/*/predictions?' do # get dataset URI
	name = params[:splat].first
	halt 404, "Model #{name} not found." unless @model = LazarModel.get(request.url)
	# Dataset.find
end

get '/lazar_classification/*/prediction/*' do	# display prediction for a compound
	name = params[:splat].first
	compound_uri = params[:splat][1]
	halt 404, "Model #{name} not found." unless @model = LazarModel.get(request.url)
	# prediction not found
	#prediction.to_yaml
	#xml prediction
end

get '/lazar_classification/*/prediction/*/neighbors' do	
	name = params[:splat].first
	compound_uri = params[:splat][1]
	halt 404, "Model #{name} not found." unless @model = LazarModel.get(request.url)
	# prediction not found
	# prediction.neighbors
end

get '/lazar_classification/*/prediction/*/features' do	
	name = params[:splat].first
	compound_uri = params[:splat][1]
	halt 404, "Model #{name} not found." unless @model = LazarModel.get(request.url)
	# prediction not found
	# prediction not found
	# prediction.features
end

delete '/lazar_classification/*/prediction/*' do	# display prediction for a compound
	name = params[:splat].first
	halt 404, "Model #{name} not found." unless @model = LazarModel.get(request.url)
	# Prediction.destroy
end