bio-publisci 0.0.5 → 0.0.6
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.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/examples/no_magic.rb +58 -0
- data/examples/orm.prov +48 -0
- data/examples/primer-full.prov +120 -0
- data/examples/prov_dsl.prov +4 -2
- data/features/prov_dsl.feature +1 -1
- data/lib/bio-publisci.rb +1 -0
- data/lib/bio-publisci/dataset/ORM/data_cube_orm.rb +1 -1
- data/lib/bio-publisci/metadata/prov/activity.rb +30 -51
- data/lib/bio-publisci/metadata/prov/agent.rb +76 -71
- data/lib/bio-publisci/metadata/prov/association.rb +54 -20
- data/lib/bio-publisci/metadata/prov/derivation.rb +2 -0
- data/lib/bio-publisci/metadata/prov/dsl.rb +36 -80
- data/lib/bio-publisci/metadata/prov/element.rb +69 -1
- data/lib/bio-publisci/metadata/prov/entity.rb +34 -50
- data/lib/bio-publisci/metadata/prov/model/prov_models.rb +79 -0
- data/lib/bio-publisci/metadata/prov/plan.rb +1 -1
- data/lib/bio-publisci/metadata/prov/prov.rb +1 -1
- data/lib/bio-publisci/metadata/prov/role.rb +40 -0
- data/lib/bio-publisci/metadata/prov/usage.rb +64 -0
- data/lib/bio-publisci/mixins/custom_predicate.rb +16 -4
- data/lib/bio-publisci/mixins/dereferencable.rb +34 -0
- data/lib/bio-publisci/parser.rb +4 -4
- data/spec/prov/activity_spec.rb +74 -0
- data/spec/prov/agent_spec.rb +55 -0
- data/spec/prov/association_spec.rb +56 -0
- data/spec/prov/entity_spec.rb +53 -0
- data/spec/prov/role_spec.rb +95 -0
- data/spec/prov/usage_spec.rb +99 -0
- metadata +15 -2
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'rdf/4store'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'spira'
|
5
|
+
|
6
|
+
module PubliSci
|
7
|
+
module Prov
|
8
|
+
module Model
|
9
|
+
PROV ||= RDF::Vocabulary.new(RDF::URI.new('http://www.w3.org/ns/prov#'))
|
10
|
+
|
11
|
+
class Entity < Spira::Base
|
12
|
+
type PROV.Entity
|
13
|
+
property :label, predicate: RDF::RDFS.label
|
14
|
+
property :wasGeneratedBy, predicate: PROV.wasGeneratedBy
|
15
|
+
has_many :wasAttributedTo, predicate: PROV.wasAttributedTo
|
16
|
+
has_many :wasDerivedFrom, predicate: PROV.wasDerivedFrom
|
17
|
+
has_many :qualifiedAssociation, predicate: PROV.qualifiedAssociation
|
18
|
+
|
19
|
+
def organization
|
20
|
+
wasAttributedTo.map{|src|
|
21
|
+
if Agent.for(src).actedOnBehalfOf
|
22
|
+
Agent.for(Agent.for(src).actedOnBehalfOf).label
|
23
|
+
end
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Agent < Spira::Base
|
29
|
+
type PROV.Agent
|
30
|
+
type PROV.Organization
|
31
|
+
type PROV.SoftwareAgent
|
32
|
+
type PROV.Person
|
33
|
+
property :label, predicate: RDF::RDFS.label
|
34
|
+
property :wasGeneratedBy, predicate: PROV.wasGeneratedBy
|
35
|
+
property :foaf_name, predicate: RDF::FOAF.name
|
36
|
+
property :foaf_given, predicate: RDF::FOAF.givenName
|
37
|
+
property :name, predicate: PROV.actedOnBehalfOf
|
38
|
+
property :actedOnBehalfOf, predicate: PROV.actedOnBehalfOf
|
39
|
+
|
40
|
+
def name
|
41
|
+
foaf_given || foaf_name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Activity < Spira::Base
|
46
|
+
type PROV.Activity
|
47
|
+
property :label, predicate: RDF::RDFS.label
|
48
|
+
has_many :generated, predicate: PROV.generated
|
49
|
+
has_many :used, predicate: PROV.used
|
50
|
+
has_many :wasAssociatedWith, predicate: PROV.wasAssociatedWith
|
51
|
+
has_many :qualifiedAssociation, predicate: PROV.qualifiedAssociation
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
class Association < Spira::Base
|
56
|
+
type PROV.Association
|
57
|
+
property :label, predicate: RDF::RDFS.label
|
58
|
+
property :agent, predicate: PROV.agent
|
59
|
+
property :hadPlan, predicate: PROV.plan
|
60
|
+
end
|
61
|
+
|
62
|
+
class Derivation < Spira::Base
|
63
|
+
type PROV.Derivation
|
64
|
+
property :label, predicate: RDF::RDFS.label
|
65
|
+
property :agent, predicate: PROV.agent
|
66
|
+
property :hadPlan, predicate: PROV.plan
|
67
|
+
end
|
68
|
+
|
69
|
+
class Plan < Spira::Base
|
70
|
+
type PROV.Plan
|
71
|
+
property :label, predicate: RDF::RDFS.label
|
72
|
+
property :comment, predicate: RDF::RDFS.comment
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
rescue LoadError
|
78
|
+
# puts "spira not installed, ORM unavailable"
|
79
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module PubliSci
|
2
|
+
module Prov
|
3
|
+
class Role
|
4
|
+
# attr_writer :comment
|
5
|
+
|
6
|
+
include Prov::Element
|
7
|
+
|
8
|
+
def comment(str=nil)
|
9
|
+
if str
|
10
|
+
@comment = str
|
11
|
+
else
|
12
|
+
@comment
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# def steps(steps=nil)
|
17
|
+
# if steps
|
18
|
+
# if File.exist? steps
|
19
|
+
# steps = Array[IO.read(steps).split("\n")]
|
20
|
+
# end
|
21
|
+
# @steps = Array[steps]
|
22
|
+
# else
|
23
|
+
# @steps
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
|
27
|
+
def to_n3
|
28
|
+
str = "<#{subject}> a prov:Role ;\n"
|
29
|
+
str << "\trdfs:comment \"#{comment}\" ;\n" if comment
|
30
|
+
add_custom(str)
|
31
|
+
|
32
|
+
str << "\trdfs:label \"#{__label}\" .\n\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
subject
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module PubliSci
|
2
|
+
module Prov
|
3
|
+
class Usage
|
4
|
+
include Prov::Element
|
5
|
+
|
6
|
+
def __label
|
7
|
+
@__label ||= Time.now.nsec.to_s(32)
|
8
|
+
end
|
9
|
+
|
10
|
+
def entity(entity=nil)
|
11
|
+
basic_keyword(:entity,:entities,entity)
|
12
|
+
end
|
13
|
+
|
14
|
+
def had_role(*args, &block)
|
15
|
+
if block_given?
|
16
|
+
p = Prov::Role.new
|
17
|
+
p.instance_eval(&block)
|
18
|
+
p.__label=args[0]
|
19
|
+
@role = p
|
20
|
+
# puts p.class
|
21
|
+
Prov.register(args[0], p)
|
22
|
+
elsif args.size == 0
|
23
|
+
if @role.is_a? Symbol
|
24
|
+
raise "UnknownRole: #{@role}" unless (Prov.registry[:role]||={})[@role]
|
25
|
+
@role = Prov.registry[:role][@role]
|
26
|
+
end
|
27
|
+
@role
|
28
|
+
elsif args.size == 1
|
29
|
+
unless (Prov.registry[:role]||={})[args[0]]
|
30
|
+
p = Prov::Role.new
|
31
|
+
p.__label=args[0]
|
32
|
+
@role = p
|
33
|
+
Prov.register(args[0], p)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
name = args.shift
|
37
|
+
args = Hash[*args]
|
38
|
+
p = Prov::Role.new
|
39
|
+
|
40
|
+
p.__label=name
|
41
|
+
p.subject args[:subject]
|
42
|
+
(args.keys - [:subject]).map{|k|
|
43
|
+
raise "Unkown Role setting #{k}" unless try_auto_set(p,k,args[k])
|
44
|
+
}
|
45
|
+
@role = p
|
46
|
+
Prov.register(name, p)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
alias_method :role, :had_role
|
50
|
+
|
51
|
+
def to_n3
|
52
|
+
str = "<#{subject}> a prov:Usage ;\n"
|
53
|
+
str << "\tprov:entity <#{entity}> ;\n"
|
54
|
+
str << "\tprov:hadRole <#{had_role}> ;\n" if had_role
|
55
|
+
str[-2] = ".\n"
|
56
|
+
str
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
subject
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module PubliSci
|
2
2
|
module CustomPredicate
|
3
3
|
def has(predicate, object)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
if object.is_a? Symbol
|
5
|
+
obj = object
|
6
|
+
else
|
7
|
+
predicate = RDF::Resource(predicate) if RDF::Resource(predicate).valid?
|
8
|
+
obj = RDF::Resource(object)
|
9
|
+
obj = RDF::Literal(object) unless obj.valid?
|
10
|
+
end
|
11
|
+
((@custom ||= {})[predicate] ||= []) << obj
|
8
12
|
end
|
9
13
|
alias_method :set, :has
|
10
14
|
|
@@ -17,6 +21,14 @@ module PubliSci
|
|
17
21
|
custom.map{|k,v|
|
18
22
|
pk = k.respond_to?(:to_base) ? k.to_base : k
|
19
23
|
v.map{|vv|
|
24
|
+
if vv.is_a? Symbol
|
25
|
+
|
26
|
+
deref = Prov.registry.values.map{|h|
|
27
|
+
h[vv] if vv
|
28
|
+
}.reject{|x| x==nil}
|
29
|
+
raise "Unknown Element #{vv}" unless deref.size > 0
|
30
|
+
vv = RDF::Resource(deref.first)
|
31
|
+
end
|
20
32
|
str << "\t#{pk} #{vv.to_base} ;\n"
|
21
33
|
}
|
22
34
|
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module PubliSci
|
2
|
+
module Prov
|
3
|
+
module Dereferencable
|
4
|
+
def dereference
|
5
|
+
self.map{|x|
|
6
|
+
if x.is_a? Symbol
|
7
|
+
raise "Unknown#{method.capitalize}: #{x}" unless Prov.registry[method.to_sym][x]
|
8
|
+
Prov.registry[method.to_sym][x]
|
9
|
+
else
|
10
|
+
x
|
11
|
+
end
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def method
|
16
|
+
raise "must be overridden"
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](index)
|
20
|
+
self.dereference.fetch(index)
|
21
|
+
# if self.fetch(index).is_a? Symbol
|
22
|
+
# raise "UnknownEntity: #{self.fetch(index)}" unless Prov.entities[self.fetch(index)]
|
23
|
+
# Prov.entities[self.fetch(index)]
|
24
|
+
# else
|
25
|
+
# self.fetch(index)
|
26
|
+
# end
|
27
|
+
end
|
28
|
+
|
29
|
+
def map_(&blk)
|
30
|
+
self.dereference.map(&blk)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/bio-publisci/parser.rb
CHANGED
@@ -38,13 +38,13 @@ module R2RDF
|
|
38
38
|
h
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
42
|
-
f = Tempfile.new('
|
41
|
+
def load_string(string,repo=RDF::Repository.new)
|
42
|
+
f = Tempfile.new('repo')
|
43
43
|
f.write(string)
|
44
44
|
f.close
|
45
|
-
|
45
|
+
repo.load(f.path, :format => :ttl)
|
46
46
|
f.unlink
|
47
|
-
|
47
|
+
repo
|
48
48
|
end
|
49
49
|
|
50
50
|
def get_ary(query_results,method='to_s')
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative '../../lib/bio-publisci.rb'
|
2
|
+
include PubliSci::Prov::DSL
|
3
|
+
include PubliSci::Prov
|
4
|
+
|
5
|
+
describe PubliSci::Prov::Activity do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@evaluator = PubliSci::Prov::DSL::Singleton.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "can generate activity fields from symbol" do
|
12
|
+
a = activity :name
|
13
|
+
a.is_a?(Activity).should be true
|
14
|
+
a.subject.should == "http://rqtl.org/ns/activity/name"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can specify fields manually" do
|
18
|
+
a = activity :name, subject: "http://example.org/name"
|
19
|
+
a.subject.should == "http://example.org/name"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can be created with a block" do
|
23
|
+
e = entity :data
|
24
|
+
a = activity :ag do
|
25
|
+
subject "http://things.com/stuff"
|
26
|
+
generated :data
|
27
|
+
end
|
28
|
+
a.is_a?(Activity).should be true
|
29
|
+
a.subject.should == "http://things.com/stuff"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "lazy loads other objects" do
|
33
|
+
a = activity :ag do
|
34
|
+
subject "http://things.com/stuff"
|
35
|
+
generated :data
|
36
|
+
end
|
37
|
+
e = entity :data
|
38
|
+
|
39
|
+
a.generated[0].should == e
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises an exception when used does not refer to an entity" do
|
43
|
+
a = activity :name, used: :some_data
|
44
|
+
expect {a.used[0]}.to raise_error
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises an exception when generated does not refer to an entity" do
|
48
|
+
a = activity :name, generated: :other_data
|
49
|
+
expect {a.generated[0]}.to raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
it "lazy loads generated relationships" do
|
53
|
+
a = activity :act, generated: :data
|
54
|
+
e = entity :data
|
55
|
+
|
56
|
+
a.generated[0].should == e
|
57
|
+
end
|
58
|
+
|
59
|
+
it "lazy loads used relationships" do
|
60
|
+
a = activity :act, generated: :data, used: :other_data
|
61
|
+
e = entity :data
|
62
|
+
f = entity :other_data
|
63
|
+
|
64
|
+
a.used[0].should == f
|
65
|
+
end
|
66
|
+
|
67
|
+
# it "lazy loads other objects, so declaration order doesn't usually matter" do
|
68
|
+
# a = activity :name, on_behalf_of: :other
|
69
|
+
# b = activity :other
|
70
|
+
|
71
|
+
# a.on_behalf_of.should == b
|
72
|
+
# end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative '../../lib/bio-publisci.rb'
|
2
|
+
include PubliSci::Prov::DSL
|
3
|
+
include PubliSci::Prov
|
4
|
+
|
5
|
+
describe PubliSci::Prov::Agent do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@evaluator = PubliSci::Prov::DSL::Singleton.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "can generate agent fields from symbol" do
|
12
|
+
a = agent :name
|
13
|
+
a.is_a?(Agent).should be true
|
14
|
+
a.subject.should == "http://rqtl.org/ns/agent/name"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can specify fields manually" do
|
18
|
+
a = agent :name, subject: "http://example.org/name"
|
19
|
+
a.subject.should == "http://example.org/name"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can be created with a block" do
|
23
|
+
a = agent :ag do
|
24
|
+
subject "http://things.com/stuff"
|
25
|
+
name "Mr Person"
|
26
|
+
end
|
27
|
+
a.is_a?(Agent).should be true
|
28
|
+
a.subject.should == "http://things.com/stuff"
|
29
|
+
a.name.should == "Mr Person"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can be given a type corresponding to a subclass of prov:Agent" do
|
33
|
+
a = agent :name, type: "software"
|
34
|
+
a.type.should == :software
|
35
|
+
a.to_n3["prov:SoftwareAgent"].should_not be nil
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can be created using the organization helper" do
|
39
|
+
a = organization :group
|
40
|
+
a.type.should == :organization
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises an exception when on_behalf_of does not refer to an agent" do
|
44
|
+
a = agent :name, on_behalf_of: :other
|
45
|
+
expect {a.on_behalf_of[0]}.to raise_error
|
46
|
+
end
|
47
|
+
|
48
|
+
it "lazy loads other objects, so declaration order doesn't usually matter" do
|
49
|
+
a = agent :name, on_behalf_of: :other
|
50
|
+
b = agent :other
|
51
|
+
|
52
|
+
a.on_behalf_of.should == b
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative '../../lib/bio-publisci.rb'
|
2
|
+
include PubliSci::Prov
|
3
|
+
include PubliSci::Prov::DSL
|
4
|
+
|
5
|
+
describe PubliSci::Prov::Association do
|
6
|
+
before(:each) do
|
7
|
+
@ev = PubliSci::Prov::DSL::Singleton.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "can create simple associations" do
|
11
|
+
e = @ev.entity :name
|
12
|
+
f = @ev.agent :other
|
13
|
+
g = @ev.activity :do_things, generated: :name, associated_with: :other
|
14
|
+
g.associated_with[0].should == f
|
15
|
+
@ev.generate_n3["prov:wasAssociatedWith"].size.should > 0
|
16
|
+
end
|
17
|
+
|
18
|
+
it "creates qualified associations when a block is passed" do
|
19
|
+
e = @ev.entity :name
|
20
|
+
f = @ev.agent :other
|
21
|
+
p = @ev.plan :the_plan
|
22
|
+
g = @ev.activity :do_things do
|
23
|
+
generated :name
|
24
|
+
associated_with do
|
25
|
+
agent :other
|
26
|
+
plan :the_plan
|
27
|
+
end
|
28
|
+
end
|
29
|
+
g.associated_with.first.agent.should == f
|
30
|
+
@ev.generate_n3["prov:wasAssociatedWith"].size.should > 0
|
31
|
+
@ev.generate_n3["prov:qualifiedAssociation"].size.should > 0
|
32
|
+
end
|
33
|
+
|
34
|
+
# it "raises an exception when derivation does not refer to an entity" do
|
35
|
+
# e = entity :name, derived_from: :dataset
|
36
|
+
# expect {e.derived_from[0]}.to raise_error
|
37
|
+
# end
|
38
|
+
|
39
|
+
# it "raises an exception when attribution does not refer to an agent" do
|
40
|
+
# e = entity :name, attributed_to: :person
|
41
|
+
# expect {e.attributed_to[0]}.to raise_error
|
42
|
+
# end
|
43
|
+
|
44
|
+
# it "raises an exception when generated_by does not refer to an activity" do
|
45
|
+
# e = entity :name, generated_by: :act
|
46
|
+
# expect {e.generated_by[0]}.to raise_error
|
47
|
+
# end
|
48
|
+
|
49
|
+
# it "lazy loads other objects, so declaration order doesn't usually matter" do
|
50
|
+
# e = entity :name, derived_from: :other
|
51
|
+
# f = entity :other
|
52
|
+
|
53
|
+
|
54
|
+
# e.derived_from[0].should == f
|
55
|
+
# end
|
56
|
+
end
|