bio-publisci 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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