require 'rest_client'
require 'crack/xml'
module OpenTox
class OpenTox
attr_reader :uri
# Escape all nonword characters
def uri_escape(string)
URI.escape(string, /[^\w]/)
end
end
class Compound < OpenTox
# Initialize with :uri => uri, :smiles => smiles or :name => name (name can be also an InChI/InChiKey, CAS number, etc)
def initialize(params)
if params[:uri]
@uri = params[:uri].to_s
elsif params[:smiles]
@uri = RestClient.post ENV['OPENTOX_COMPOUNDS'] ,:smiles => uri_escape(params[:smiles])
elsif params[:name]
@uri = RestClient.post ENV['OPENTOX_COMPOUNDS'] ,:name => uri_escape(params[:name])
end
end
# Get the (canonical) smiles
def smiles
RestClient.get @uri
end
# Matchs a smarts string
def match?(smarts)
if RestClient.get(@uri + '/match/' + uri_escape(smarts)) == 'true'
true
else
false
end
end
# Match an array of smarts features, returns matching features
def match(smarts_features)
smarts_features.collect{ |smarts| smarts if self.match?(smarts.name) }.compact
end
end
class Feature < OpenTox
# Initialize with :uri => uri, or :name => name, :values => hash_of_property_names_and_values
def initialize(params)
if params[:uri]
@uri = params[:uri].to_s
else
@uri = ENV['OPENTOX_FEATURES'] + uri_escape(params[:name])
params[:values].each do |k,v|
@uri += '/' + k.to_s + '/' + v.to_s
end
end
end
# Get the value of a property
def value(property)
RestClient.get @uri + '/' + property
end
# Get the name of the feature
def name
RestClient.get @uri + '/name'
end
end
class Dataset < OpenTox
# Initialize with :uri => uri or :name => name (creates a new dataset)
def initialize(params)
if params[:uri]
@uri = params[:uri].to_s
elsif params[:name]
@uri = RestClient.post ENV['OPENTOX_DATASETS'], :name => params[:name]
RestClient.delete @uri + '/associations'
end
end
# Get the dataset name
def name
RestClient.get @uri + '/name'
end
# Get all compounds from a dataset
def compounds
RestClient.get(@uri + '/compounds').split("\n").collect{ |c| Compound.new(:uri => c) }
end
# Get all compounds and features from a dataset, returns a hash with compound_uris as keys and arrays of features as values
def all_compounds_and_features
compounds = {}
Crack::XML.parse(RestClient.get @uri + '/compounds/features')['dataset']['compound'].each do |c|
features = c['feature_uri'].collect{ |f| Feature.new :uri => f }
compounds[c['uri']] = features
end
compounds
end
# Get all features from a dataset
def all_features
RestClient.get(@uri + '/features').split("\n").collect{|f| Feature.new(:uri => f)}
end
# Get all features for a compound
def features(compound)
RestClient.get(@uri + '/compound/' + uri_escape(compound.uri) + '/features').split("\n").collect{|f| Feature.new(:uri => f) }
end
# Add a compound and a feature to a dataset
def add(compound,feature)
RestClient.put @uri, :compound_uri => compound.uri, :feature_uri => feature.uri
end
end
class Fminer < OpenTox
# Create a new dataset with BBRC features
def initialize(training_dataset)
@dataset_uri = RestClient.post ENV['OPENTOX_FMINER'], :dataset_uri => training_dataset.uri
end
def dataset
Dataset.new(:uri => @dataset_uri)
end
end
end