bio-publisci 0.0.3 → 0.0.4

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Rakefile +5 -5
  4. data/bin/bio-publisci +34 -11
  5. data/examples/bio-band_integration.rb +9 -0
  6. data/examples/no_magic.prov +40 -0
  7. data/examples/primer.prov +28 -0
  8. data/examples/prov_dsl.prov +51 -0
  9. data/features/create_generator.feature +5 -9
  10. data/features/integration_steps.rb +8 -8
  11. data/features/metadata.feature +15 -2
  12. data/features/metadata_steps.rb +21 -0
  13. data/features/orm_steps.rb +5 -5
  14. data/features/prov_dsl.feature +14 -0
  15. data/features/prov_dsl_steps.rb +11 -0
  16. data/lib/bio-publisci/dataset/ORM/data_cube_orm.rb +234 -236
  17. data/lib/bio-publisci/dataset/ORM/observation.rb +1 -3
  18. data/lib/bio-publisci/dataset/data_cube.rb +30 -26
  19. data/lib/bio-publisci/dataset/dataset_for.rb +14 -8
  20. data/lib/bio-publisci/metadata/metadata.rb +180 -42
  21. data/lib/bio-publisci/metadata/prov/activity.rb +106 -0
  22. data/lib/bio-publisci/metadata/prov/agent.rb +94 -0
  23. data/lib/bio-publisci/metadata/prov/association.rb +73 -0
  24. data/lib/bio-publisci/metadata/prov/derivation.rb +53 -0
  25. data/lib/bio-publisci/metadata/prov/dsl.rb +159 -0
  26. data/lib/bio-publisci/metadata/prov/element.rb +52 -0
  27. data/lib/bio-publisci/metadata/prov/entity.rb +101 -0
  28. data/lib/bio-publisci/metadata/prov/plan.rb +32 -0
  29. data/lib/bio-publisci/metadata/prov/prov.rb +76 -0
  30. data/lib/bio-publisci/mixins/custom_predicate.rb +26 -0
  31. data/lib/bio-publisci/mixins/vocabulary.rb +8 -0
  32. data/lib/bio-publisci/output.rb +27 -0
  33. data/lib/bio-publisci/parser.rb +17 -8
  34. data/lib/bio-publisci/readers/csv.rb +9 -7
  35. data/lib/bio-publisci/readers/dataframe.rb +9 -8
  36. data/lib/bio-publisci/readers/{big_cross.rb → r_cross.rb} +6 -10
  37. data/lib/bio-publisci/readers/r_matrix.rb +37 -13
  38. data/lib/bio-publisci/spira.rb +82 -0
  39. data/lib/bio-publisci/writers/dataframe.rb +65 -65
  40. data/lib/bio-publisci.rb +9 -4
  41. data/spec/ORM/data_cube_orm_spec.rb +3 -3
  42. data/spec/dataset_for_spec.rb +29 -0
  43. data/spec/generators/r_cross_spec.rb +51 -0
  44. data/spec/generators/r_matrix_spec.rb +14 -5
  45. metadata +42 -8
  46. data/lib/bio-publisci/readers/cross.rb +0 -72
@@ -3,6 +3,12 @@ module R2RDF
3
3
  extend R2RDF::Interactive
4
4
 
5
5
  def self.for(object, options={}, ask_on_ambiguous=true)
6
+
7
+ if options == false || options == true
8
+ ask_on_ambiguous = options
9
+ options = {}
10
+ end
11
+
6
12
  if object.is_a? String
7
13
  if File.exist? object
8
14
  if File.extname(object).size > 0
@@ -21,7 +27,7 @@ module R2RDF
21
27
  end
22
28
  else
23
29
  raise "Unable to find reader for File or String"
24
- end
30
+ end
25
31
  elsif object.is_a? Rserve::REXP
26
32
  r_object(object, options, ask_on_ambiguous)
27
33
  else
@@ -60,11 +66,11 @@ module R2RDF
60
66
  options[:measures] = selection.split(',').map(&:to_i).map{|i| meas[i]}
61
67
  end
62
68
  end
63
-
69
+
64
70
  df.generate_n3(con.eval(var),var,options)
65
-
71
+
66
72
  elsif r_classes.include? "cross"
67
- bc = R2RDF::Reader::BigCross.new
73
+ bc = R2RDF::Reader::RCross.new
68
74
 
69
75
  unless options[:measures] || !ask_on_ambiguous
70
76
  pheno_names = con.eval("names(#{var}$pheno)").to_ruby
@@ -87,7 +93,7 @@ module R2RDF
87
93
  elsif r_classes.include? "matrix"
88
94
  mat = R2RDF::Reader::RMatrix.new
89
95
 
90
- unless options[:measures] || !ask_on_ambiguous
96
+ unless options[:measures] || !ask_on_ambiguous
91
97
  puts "Row label"
92
98
  rows = gets.chomp
93
99
  rows = "row" unless rows.size > 0
@@ -102,7 +108,7 @@ module R2RDF
102
108
 
103
109
  options[:measures] = [cols,rows,vals]
104
110
  end
105
-
111
+
106
112
  base = var
107
113
  if ask_on_ambiguous
108
114
  puts "Output file base?"
@@ -117,7 +123,7 @@ module R2RDF
117
123
 
118
124
  elsif object.is_a? Rserve::REXP
119
125
  if object.attr.payload["class"].payload.first
120
-
126
+
121
127
  df = R2RDF::Reader::Dataframe.new
122
128
 
123
129
  var = nil
@@ -136,7 +142,7 @@ module R2RDF
136
142
  meas = object.payload.names
137
143
  options[:measures] = interact("Which measures?",meas,meas)
138
144
  end
139
-
145
+
140
146
  df.generate_n3(object,var,options)
141
147
  else
142
148
  raise "support for other Rserve objects coming shortly"
@@ -15,8 +15,8 @@ module R2RDF
15
15
  }
16
16
  end
17
17
 
18
- def basic(fields, options={} )
19
- #TODO don't assume base dataset is "ns:dataset-var",
18
+ def basic(fields)
19
+ #TODO don't assume base dataset is "ns:dataset-var",
20
20
  #make it just "var", and try to make that clear to calling classes
21
21
 
22
22
  fields[:var] = sanitize([fields[:var]]).first
@@ -31,8 +31,6 @@ module R2RDF
31
31
 
32
32
  fields[:date] = Time.now.strftime("%Y-%m-%d") unless fields[:date]
33
33
 
34
- options = defaults().merge(options)
35
-
36
34
  #TODO some of these should probably be resources, eg dct:creator, or put under DC namespace
37
35
  str = <<-EOF.unindent
38
36
  ns:dataset-#{fields[:var]} rdfs:label "#{fields[:title]}";
@@ -64,67 +62,207 @@ module R2RDF
64
62
  str + "\n" + end_str
65
63
  end
66
64
 
67
- def provenance(fields, options={})
65
+ def provenance(original, triplified, chain, options={})
68
66
  #TODO: should either add a prefixes method or replace some with full URIs
69
- var = sanitize([fields[:var]]).first
70
- creator = fields[:creator] if fields[:creator] #should be URI
71
- org = fields[:organization] if fields[:organization] #should be URI
72
- source_software = fields[:software] # software name, object type, optionally steps list for, eg, R
73
- str = "ns:dataset-#{var} a prov:Entity.\n\n"
74
- assoc_id = Time.now.nsec.to_s(32)
75
- endstr = <<-EOF.unindent
76
- </ns/R2RDF> a prov:Agent .
77
- ns:dataset-#{var} prov:wasGeneratredBy ns:activity-0 .
67
+ raise "MissingOriginal: must specify a provenance source" unless original && original[:resource]
78
68
 
79
- ns:activity-0 a prov:Activity ;
80
- prov:qualifiedAssociation ns:assoc-0_#{assoc_id};
81
- prov:generated ns:dataset-#{var} .
69
+ #TODO include file type etc, or create a separate method for it
82
70
 
83
- ns:assoc-0_#{assoc_id} a prov:Assocation ;
84
- prov:entity </ns/R2RDF>;
85
- prov:hadPlan ns:plan-0.
71
+ str = <<-EOF.unindent
72
+ <#{original[:resource]}> a prov:Entity ;
73
+ prov:wasGeneratredBy ns:activity-1 .
86
74
 
87
- ns:plan-0 a prov:Plan ;
88
- rdfs:comment "generation of dataset-#{var} by R2RDF gem".
75
+ ns:activity-1 a prov:Activity ;
76
+ prov:generated <#{original[:resource]}> .
89
77
 
90
78
  EOF
91
79
 
92
- if creator
93
- str << "<#{creator}> a prov:Agent, prov:Person .\n"
94
- str << "</ns/R2RDF> prov:actedOnBehalfOf <#{creator}> .\n\n"
80
+ if original[:software]
81
+ original_assoc_id = Time.now.nsec.to_s(32)
82
+
83
+
84
+ str << <<-EOF.unindent
85
+ <#{original[:software]}> a prov:Entity.
86
+
87
+ ns:activity-1 prov:qualifiedAssociation ns:assoc-1_#{original_assoc_id} .
88
+
89
+ ns:assoc-1_#{original_assoc_id} a prov:Assocation ;
90
+ prov:entity <#{original[:software]}> .
91
+
92
+ EOF
93
+
94
+ if original[:process]
95
+ original[:process] = IO.read(original[:process]) if File.exist? original[:process]
96
+
97
+ steps = '"' + original[:process].split("\n").join('" "') + '"'
98
+ str << <<-EOF.unindent
99
+ ns:assoc-1_#{original_assoc_id} prov:hadPlan ns:plan-1.
100
+
101
+ ns:plan-1 a prov:Plan ;
102
+ rdfs:comment (#{steps});
103
+
104
+ EOF
105
+ end
106
+ end
107
+
108
+ if original[:author]
109
+ str << "<#{original[:author]}> a prov:Agent, prov:Person .\n"
110
+ str << "ns:activity-1 prov:wasAssociatedWith <#{original[:author]}> .\n"
95
111
 
96
- if org
97
- str << "<#{org}> a prov:Agent, prov:Organization .\n"
98
- str << "<#{creator}> prov:actedOnBehalfOf <#{org}> .\n"
112
+ str << "<#{original[:author]}> foaf:givenName \"#{original[:author_name]}\" .\n" if original[:author_name]
113
+
114
+ if original[:organization]
115
+ str << "<#{original[:author]}> prov:actedOnBehalfOf <#{original[:organization]}> .\n\n"
116
+ str << "<#{original[:organization]}> a prov:Agent, prov:Organization.\n"
117
+ if original[:organization_name]
118
+ str << "<#{original[:organization]}> foaf:name \"#{original[:organization_name]}\" .\n\n"
119
+ else
120
+ str << "\n"
121
+ end
122
+ else
123
+ str << "\n"
99
124
  end
100
125
  end
101
126
 
102
- if source_software
103
- source_software = [source_software] unless source_software.is_a? Array
104
- source_software.each_with_index.map{|soft,i|
105
- str << "</ns/prov/software/#{soft[:name]}> a prov:Agent .\n"
127
+ if triplified
128
+ triples_assoc_id = Time.now.nsec.to_s(32)
129
+
130
+ str << <<-EOF.unindent
131
+ <#{triplified[:resource]}> a prov:Entity;
132
+ prov:wasGeneratredBy ns:activity-0 .
133
+
134
+ </ns/R2RDF> a prov:Agent, prov:SoftwareAgent ;
135
+ rdfs:label "Semantic Publishing Toolkit" .
136
+
137
+ ns:activity-0 a prov:Activity ;
138
+ prov:qualifiedAssociation ns:assoc-0_#{triples_assoc_id};
139
+ prov:generated <#{triplified[:resource]}> ;
140
+ prov:used <#{original[:resource]}> .
141
+
142
+ ns:assoc-0_#{triples_assoc_id} a prov:Assocation ;
143
+ prov:entity </ns/R2RDF>;
144
+ prov:hadPlan ns:plan-0.
145
+
146
+ ns:plan-0 a prov:Plan ;
147
+ rdfs:comment "generation of <#{triplified[:resource]}> by R2RDF gem" .
148
+
149
+ EOF
150
+
151
+ if triplified[:author]
152
+ str << "<#{triplified[:author]}> a prov:Agent, prov:Person .\n"
106
153
 
107
- endstr << "ns:activity-0 prov:used </ns/dataset/#{var}#var> .\n"
108
- endstr << "ns:dataset-#{var} prov:wasDerivedFrom </ns/dataset/#{var}#var> .\n\n"
154
+ str << "<#{triplified[:author]}> foaf:givenName \"#{triplified[:author_name]}\" .\n" if triplified[:author_name]
109
155
 
110
- if soft[:process]
111
- if File.exist? soft[:process]
112
- soft[:process] = IO.read(soft[:process])
156
+ if triplified[:organization]
157
+ str << "<#{triplified[:author]}> prov:actedOnBehalfOf <#{triplified[:organization]}> .\n\n"
158
+ str << "<#{triplified[:organization]}> a prov:Agent, prov:Organization.\n"
159
+ if triplified[:organization_name]
160
+ str << "<#{triplified[:organization]}> foaf:name \"#{triplified[:organization_name]}\" .\n\n"
161
+ else
162
+ str << "\n"
113
163
  end
114
- endstr << "</ns/dataset/#{var}#var> prov:wasGeneratredBy ns:activity-#{i+1} .\n"
115
- endstr << process(i+1, soft[:process],"/ns/prov/software/#{soft[:name]}", var)
164
+ else
165
+ str << "\n"
166
+ end
167
+ end
168
+ end
169
+
170
+ if chain
171
+ str << "ns:activity-1 prov:used <#{chain.first[:resource]}> .\n"
172
+ str << "<#{original[:resource]}> prov:wasDerivedFrom <#{chain.first[:resource]}> .\n\n"
173
+ chain.each_with_index{ |src,i|
174
+ if i == chain.size-1
175
+ str << activity(src[:resource],nil,src)
176
+ else
177
+ str << activity(src[:resource],chain[i+1][:resource],src)
116
178
  end
117
179
  }
118
180
  end
119
- str + "\n" + endstr
181
+
182
+ str
120
183
  end
121
184
 
122
- def process(id, step_string, software_resource, software_var, options={})
185
+ def activity(entity, used, options={})
186
+ assoc_id = Time.now.nsec.to_s(32)
187
+ activity_id = Time.now.nsec.to_s(32)
188
+ plan_id = Time.now.nsec.to_s(32)
189
+
190
+ raise "NoEntityGiven: activity generation requires a subject entity" unless entity
191
+
192
+ entity_str = <<-EOF.unindent
193
+ <#{entity}> a prov:Entity ;
194
+ prov:wasGeneratredBy ns:activity-a_#{activity_id} ;
195
+ EOF
196
+
197
+ activity_str = <<-EOF.unindent
198
+ ns:activity-a_#{activity_id} a prov:Activity ;
199
+ prov:generated <#{entity}> ;
200
+ EOF
201
+
202
+ if used
203
+ entity_str << "\tprov:wasDerivedFrom <#{used}> . \n\n"
204
+ activity_str << "\tprov:used <#{used}> . \n\n"
205
+ else
206
+ entity_str[-2] = ".\n"
207
+ activity_str[-2] = ".\n"
208
+ end
209
+
210
+ activity_str << <<-EOF.unindent
211
+ ns:activity-a_#{activity_id} prov:qualifiedAssociation ns:assoc-s_#{assoc_id} .
212
+
213
+ ns:assoc-s_#{assoc_id} a prov:Assocation .
214
+
215
+ EOF
216
+
217
+ if options[:software]
218
+
219
+ activity_str << <<-EOF.unindent
220
+ <#{options[:software]}> a prov:Entity .
221
+
222
+ ns:assoc-s_#{assoc_id} prov:agent <#{options[:software]}> .
223
+ EOF
224
+
225
+ if options[:process]
226
+ options[:process] = IO.read(options[:process]) if File.exist? options[:process]
227
+
228
+ steps = '"' + options[:process].split("\n").join('" "') + '"'
229
+ activity_str << <<-EOF.unindent
230
+ ns:assoc-s_#{assoc_id} prov:hadPlan ns:plan-p_#{plan_id}.
231
+
232
+ ns:plan-p_#{plan_id} a prov:Plan ;
233
+ rdfs:comment (#{steps});
234
+ EOF
235
+ end
236
+ end
237
+
238
+ if options[:author]
239
+ entity_str << "<#{options[:author]}> a prov:Agent, prov:Person .\n"
240
+ entity_str << "<#{options[:author]}> foaf:givenName \"#{options[:author_name]}\" .\n" if options[:author_name]
241
+
242
+ activity_str << "ns:activity-a_#{activity_id} prov:wasAssociatedWith <#{options[:author]}> .\n"
243
+ activity_str << "ns:assoc-s_#{assoc_id} prov:agent <#{options[:author]}> .\n"
244
+
245
+ if options[:organization]
246
+ entity_str << "<#{options[:organization]}> a prov:Agent, prov:Organization .\n"
247
+ activity_str << "<#{options[:author]}> prov:actedOnBehalfOf <#{options[:organization]}> .\n\n"
248
+ if options[:organization_name]
249
+ entity_str << "<#{options[:organization]}> foaf:name \"#{options[:organization_name]}\" .\n\n"
250
+ end
251
+ else
252
+ activity_str << "\n"
253
+ # entity_str << "\n"
254
+ end
255
+ end
256
+
257
+ entity_str + "\n" + activity_str
258
+ end
259
+
260
+ def process(id, step_string, software_resource, software_var, options={})
123
261
  #TODO a better predicate for the steplist than rdfs:comment
124
262
  # and make sure it looks good.
125
263
  steps = '"' + step_string.split("\n").join('" "') + '"'
126
264
  assoc_id = Time.now.nsec.to_s(32)
127
- str = <<-EOF.unindent
265
+ str = <<-EOF.unindent
128
266
  ns:activity-#{id} a prov:Activity ;
129
267
  prov:qualifiedAssociation ns:assoc-#{assoc_id} ;
130
268
  prov:used </ns/dataset/#{software_var}#var>.
@@ -0,0 +1,106 @@
1
+ module PubliSci
2
+ module Prov
3
+ class Activity
4
+ include Prov::Element
5
+ class Associations < Array
6
+ def [](index)
7
+ if self.fetch(index).is_a? Symbol
8
+ Prov.agents[self.fetch(index)]
9
+ else
10
+ self.fetch(index)
11
+ end
12
+ end
13
+ end
14
+
15
+ def generated(entity=nil)
16
+ if entity
17
+ # if entity.is_a? Symbol
18
+ # entity = Prov.entities[entity.to_sym]
19
+ # end
20
+
21
+ if entity.is_a? Entity
22
+ entity.generated_by self
23
+ end
24
+
25
+ (@generated ||= []) << entity
26
+ elsif @generated.is_a? Symbol
27
+ @generated = Prov.entities[@generated]
28
+ else
29
+ @generated
30
+ end
31
+ end
32
+
33
+ def generated=(gen)
34
+ @generated = gen
35
+ end
36
+
37
+ def associated_with(agent=nil, &block)
38
+ if agent
39
+ (@associated ||= Associations.new) << agent
40
+ # Prov.register(nil,assoc)
41
+ elsif block_given?
42
+ assoc = Association.new
43
+ assoc.instance_eval(&block)
44
+ (@associated ||= Associations.new) << assoc
45
+ Prov.register(nil,assoc)
46
+ else
47
+ @associated
48
+ end
49
+ end
50
+
51
+ def used(entity=nil)
52
+ if entity
53
+ (@used ||= []) << entity
54
+ elsif @used
55
+ @used.map{|u| u.is_a?(Symbol) ? Prov.entities[u] : u}
56
+ else
57
+ @used
58
+ end
59
+ end
60
+
61
+ def to_n3
62
+ str = "<#{subject}> a prov:Activity ;\n"
63
+
64
+ if generated
65
+ str << "\tprov:generated "
66
+ generated.map{|src|
67
+ src = Prov.entities[src] if src.is_a?(Symbol) && Prov.entities[src]
68
+ str << "<#{src}>, "
69
+ }
70
+ str[-2]=" "
71
+ str[-1]=";\n"
72
+ end
73
+
74
+ if used
75
+ str << "\tprov:used "
76
+ used.map{|used|
77
+ str << "<#{used}>, "
78
+ }
79
+ str[-2]=";"
80
+ str[-1]="\n"
81
+ end
82
+
83
+ if associated_with
84
+ associated_with.map{|assoc|
85
+ assoc = Prov.agents[assoc] if assoc.is_a?(Symbol) && Prov.agents[assoc]
86
+
87
+ if assoc.is_a? Association
88
+ str << "\tprov:wasAssociatedWith <#{assoc.agent}> ;\n"
89
+ str << "\tprov:qualifiedAssociation <#{assoc}> ;\n"
90
+ else
91
+ str << "\tprov:wasAssociatedWith <#{assoc}> ;\n"
92
+ end
93
+ }
94
+ end
95
+
96
+ add_custom(str)
97
+
98
+ str << "\trdfs:label \"#{__label}\" .\n\n"
99
+ end
100
+
101
+ def to_s
102
+ subject
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,94 @@
1
+ module PubliSci
2
+ module Prov
3
+ class Agent
4
+ include Prov::Element
5
+
6
+ def type(t=nil)
7
+ if t
8
+ @type = t.to_sym
9
+ else
10
+ @type
11
+ end
12
+ end
13
+
14
+ def type=(t)
15
+ @type = t.to_sym
16
+ end
17
+
18
+ def name(name=nil)
19
+ if name
20
+ @name = name
21
+ else
22
+ @name
23
+ end
24
+ end
25
+
26
+ def name=(name)
27
+ @name = name
28
+ end
29
+
30
+ def organization(organization=nil)
31
+ if organization
32
+ @organization = organization
33
+ elsif @organization.is_a? Symbol
34
+ @organization = Prov.agents[@organization]
35
+ else
36
+ @organization
37
+ end
38
+ end
39
+
40
+ def organization=(organization)
41
+ @organization = organization
42
+ end
43
+
44
+ def on_behalf_of(agent=nil)
45
+ if agent
46
+ if agent.is_a? Symbol
47
+ raise "UnknownAgent: #{agent}" unless Prov.agents.has_key?(agent)
48
+ agent = Prov.agents[agent]
49
+ end
50
+ @on_behalf_of = agent
51
+ else
52
+ @on_behalf_of
53
+ end
54
+ end
55
+ alias_method :worked_for, :on_behalf_of
56
+
57
+ def to_n3
58
+ str = "<#{subject}> a prov:Agent"
59
+ if type
60
+ case type.to_sym
61
+ when :software
62
+ str << ", prov:SoftwareAgent ;\n"
63
+ when :person
64
+ str << ", prov:Person ;\n"
65
+ when :organization
66
+ str << ", prov:Organization ;\n"
67
+ end
68
+ else
69
+ str << " ;\n"
70
+ end
71
+
72
+ if name
73
+ if type && type.to_sym == :person
74
+ str << "\tfoaf:givenName \"#{name}\" ;\n"
75
+ else
76
+ str << "\tfoaf:name \"#{name}\" ;\n"
77
+ end
78
+ end
79
+
80
+ if on_behalf_of
81
+ str << "\tprov:actedOnBehalfOf <#{on_behalf_of}> ;\n"
82
+ end
83
+
84
+ add_custom(str)
85
+
86
+ str << "\trdfs:label \"#{__label}\" .\n\n"
87
+ end
88
+
89
+ def to_s
90
+ subject
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,73 @@
1
+ module PubliSci
2
+ module Prov
3
+ class Association
4
+ def subject(sub=nil)
5
+ if sub
6
+ @subject = sub
7
+ else
8
+ @subject ||= "#{Prov.base_url}/assoc/#{Time.now.nsec.to_s(32)}"
9
+ end
10
+ end
11
+
12
+ def agent(agent=nil)
13
+ if agent
14
+ # agent = Prov.agents[agent.to_sym] if agent.is_a?(String) || agent.is_a?(Symbol)
15
+ # raise "UnkownAgent #{ag}" unless agent
16
+ # puts "Warning: overwriting agent #{@agent.subject}" if @agent
17
+ @agent = agent
18
+ elsif @agent.is_a? Symbol
19
+ @agent = Prov.agents[@agent]
20
+ else
21
+ @agent
22
+ end
23
+ end
24
+
25
+ def had_plan(*args, &block)
26
+ if block_given?
27
+ p = Prov::Plan.new
28
+ p.instance_eval(&block)
29
+ p.__label=args[0]
30
+ @plan = p
31
+ Prov.register(args[0], p)
32
+ elsif args.size == 0
33
+ if @plan.is_a? Symbol
34
+ @plan = Prov.plans[@plan]
35
+ end
36
+ @plan
37
+ elsif args.size == 1
38
+ if args[0].is_a? Symbol
39
+ raise "UnknownPlan: #{args[0]}" unless Prov.plans[args[0]]
40
+ @plan = Prov.plans[args[0]]
41
+ else
42
+ @plan = args[0]
43
+ end
44
+ else
45
+ name = args.shift
46
+ args = Hash[*args]
47
+ p = Prov::Plan.new
48
+
49
+ p.__label=name
50
+ p.subject args[:subject]
51
+ (args.keys - [:subject]).map{|k|
52
+ raise "Unkown plan setting #{k}" unless try_auto_set(p,k,args[k])
53
+ }
54
+ @plan = p
55
+ Prov.register(name, p)
56
+ end
57
+ end
58
+ alias_method :plan, :had_plan
59
+
60
+ def to_n3
61
+ str = "<#{subject}> a prov:Association ;\n"
62
+ str << "\tprov:agent <#{agent}> ;\n"
63
+ str << "\tprov:hadPlan <#{plan}> ;\n" if plan
64
+ str[-2] = ".\n"
65
+ str
66
+ end
67
+
68
+ def to_s
69
+ subject
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,53 @@
1
+ module PubliSci
2
+ module Prov
3
+ class Derivation
4
+
5
+ include PubliSci::CustomPredicate
6
+
7
+ def subject(sub=nil)
8
+ if sub
9
+ @subject = sub
10
+ else
11
+ @subject ||= "#{Prov.base_url}/derivation/#{Time.now.nsec.to_s(32)}"
12
+ end
13
+ end
14
+
15
+ def had_activity(activity=nil)
16
+ if activity
17
+ @had_activity = activity
18
+ elsif @had_activity.is_a? Symbol
19
+ @had_activity = Prov.activities[@had_activity]
20
+ else
21
+ @had_activity
22
+ end
23
+ end
24
+ alias_method :activity, :had_activity
25
+
26
+ def entity(entity=nil)
27
+ if entity
28
+ @entity = entity
29
+ elsif @entity.is_a? Symbol
30
+ @entity = Prov.entities[@entity]
31
+ else
32
+ @entity
33
+ end
34
+ end
35
+ alias_method :data, :entity
36
+
37
+ def to_n3
38
+ str = "<#{subject}> a prov:Derivation ;\n"
39
+ str << "\tprov:entity <#{entity}> ;\n" if entity
40
+ str << "\tprov:hadActivity <#{had_activity}> ;\n" if had_activity
41
+
42
+ add_custom(str)
43
+
44
+ str[-2] = ".\n"
45
+ str
46
+ end
47
+
48
+ def to_s
49
+ subject
50
+ end
51
+ end
52
+ end
53
+ end