yarrrml_template_builder 0.1.54

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1485 @@
1
+ require_relative 'version'
2
+ require 'tempfile'
3
+ require 'rest-client'
4
+ require 'yaml'
5
+ require 'digest'
6
+
7
+ class YARRRML_Template_Builder
8
+
9
+ attr_accessor :prefix_map
10
+ attr_accessor :baseURI
11
+ attr_accessor :sio_verbose
12
+ attr_accessor :source_tag
13
+ attr_accessor :sources_module
14
+ attr_accessor :mappings
15
+
16
+ SIO = {
17
+ "entity" => ["http://semanticscience.org/resource/SIO_000000", "http://semanticscience.org/resource/entity"],
18
+ "day" => ["http://semanticscience.org/resource/SIO_000430", "http://semanticscience.org/resource/day"],
19
+ "has-attribute" => ["http://semanticscience.org/resource/SIO_000008", "http://semanticscience.org/resource/has-attribute"],
20
+ "has-measurement-value" => ["http://semanticscience.org/resource/SIO_000216", "http://semanticscience.org/resource/has-measurement-value"],
21
+ "has-quality" => ["http://semanticscience.org/resource/SIO_000217", "http://semanticscience.org/resource/has-quality"],
22
+ "has-unit" => ["http://semanticscience.org/resource/SIO_000221", "http://semanticscience.org/resource/has-unit"],
23
+ "has-value" => ["http://semanticscience.org/resource/SIO_000300", "http://semanticscience.org/resource/has-value"],
24
+ "has-part" => ["http://semanticscience.org/resource/SIO_000028", "http://semanticscience.org/resource/has-part"],
25
+ "has-role" => ["http://semanticscience.org/resource/SIO_000228", "http://semanticscience.org/resource/has-role"],
26
+ "has-agent" => ["http://semanticscience.org/resource/SIO_000139", "http://semanticscience.org/resource/has-agent"],
27
+ "has-target" => ["http://semanticscience.org/resource/SIO_000291", "http://semanticscience.org/resource/has-target"],
28
+ "is-participant-in" => ["http://semanticscience.org/resource/SIO_000062", "http://semanticscience.org/resource/is-participant-in"],
29
+ "is-about" => ["http://semanticscience.org/resource/SIO_000332", "http://semanticscience.org/resource/is-about"],
30
+ "has-output" => ["http://semanticscience.org/resource/SIO_000229", "http://semanticscience.org/resource/has-output"],
31
+ "denotes" => ["http://semanticscience.org/resource/SIO_000020", "http://semanticscience.org/resource/denotes"],
32
+ "is-realized-in" => ["http://semanticscience.org/resource/SIO_000356", "http://semanticscience.org/resource/is-realized-in"],
33
+ "is-causally-related-to" => ["http://semanticscience.org/resource/SIO_000294", "http://semanticscience.org/resource/is-causally-related-to"],
34
+ "is-causally-related-from" => ["http://semanticscience.org/resource/SIO_000352", "http://semanticscience.org/resource/is-causally-related-from"],
35
+ "is-specified-by" => ["http://semanticscience.org/resource/SIO_000339", "http://semanticscience.org/resource/is-specified-by"],
36
+ "has-component-part" => ["http://semanticscience.org/resource/SIO_000369", "http://semanticscience.org/resource/has-component-part"],
37
+ # predicates
38
+ # for processs
39
+ "has-start-time" => ["http://semanticscience.org/resource/SIO_000680", "http://semanticscience.org/resource/has-start-time"],
40
+ "exists-at" => ["http://semanticscience.org/resource/SIO_000687", "http://semanticscience.org/resource/exists-at"],
41
+ "has-end-time" => ["http://semanticscience.org/resource/SIO_000681", "http://semanticscience.org/resource/has-end-time"],
42
+ "has-time-boundary" => ["http://semanticscience.org/resource/SIO_000679", "http://semanticscience.org/resource/has-time-boundary"],
43
+ # for information artifact
44
+ "measured-at" => ["http://semanticscience.org/resource/SIO_000793", "http://semanticscience.org/resource/measured-at"],
45
+ # objects
46
+ "start-time" => ["http://semanticscience.org/resource/SIO_000669", "http://semanticscience.org/resource/start-time"],
47
+ "end-time" => ["http://semanticscience.org/resource/SIO_000670", "http://semanticscience.org/resource/end-time"],
48
+ "start-date" => ["http://semanticscience.org/resource/SIO_000031", "http://semanticscience.org/resource/start-date"],
49
+ "end-date" => ["http://semanticscience.org/resource/SIO_000032", "http://semanticscience.org/resource/end-date"],
50
+ "time-instant" => ["http://semanticscience.org/resource/SIO_000418", "http://semanticscience.org/resource/time-instant"],
51
+ #
52
+
53
+
54
+
55
+ "is-component-part-of" => ["http://semanticscience.org/resource/SIO_000313", "http://semanticscience.org/resource/is-component-part-of"],
56
+ "drug" => ["http://semanticscience.org/resource/SIO_010038", "http://semanticscience.org/resource/drug"],
57
+ "specialized-object" => ["http://semanticscience.org/resource/SIO_001353", "http://semanticscience.org/resource/specialized-object"],
58
+ "object" => ["http://semanticscience.org/resource/SIO_000776", "http://semanticscience.org/resource/object"],
59
+ "is-base-for" => ["http://semanticscience.org/resource/SIO_000642", "http://semanticscience.org/resource/is-base-for"],
60
+ "has-concretization" => ["http://semanticscience.org/resource/SIO_000213", "http://semanticscience.org/resource/has-concretization"],
61
+ "realizable-entity" => ["http://semanticscience.org/resource/SIO_000340", "http://semanticscience.org/resource/realizable-entity"],
62
+ "information-content-entity" => ["http://semanticscience.org/resource/SIO_000015", "http://semanticscience.org/resource/information-content-entity"],
63
+ "measurement-value" => ["http://semanticscience.org/resource/SIO_000070", "http://semanticscience.org/resource/measurement-value"],
64
+ "refers-to" => ["http://semanticscience.org/resource/SIO_000628", "http://semanticscience.org/resource/refers-to"],
65
+ "has-input" => ["http://semanticscience.org/resource/SIO_000230", "http://semanticscience.org/resource/has-input"],
66
+ "person" => ["http://semanticscience.org/resource/SIO_000498", "http://semanticscience.org/resource/person"],
67
+ "identifier" => ["http://semanticscience.org/resource/SIO_000115", "http://semanticscience.org/resource/identifier"],
68
+ "role" => ["http://semanticscience.org/resource/SIO_000016", "http://semanticscience.org/resource/role"],
69
+ "process" => ["http://semanticscience.org/resource/SIO_000006", "http://semanticscience.org/resource/process"],
70
+ "attribute" => ["http://semanticscience.org/resource/SIO_000614", "http://semanticscience.org/resource/attribute"],
71
+ "conforms-to" => ["https://semanticscience.org/resource/CHEMINF_000047", "http://semanticscience.org/resource/conforms-to"],
72
+
73
+ }
74
+
75
+
76
+
77
+ # all params are passed as a hash, and retrieved by params.fetch(paramName)
78
+ #
79
+ # @param params [Hash] params a Hash of options
80
+ # @option params [String] :baseURI a URL that will become the base for "urls owned by the data provider" e.g. "https://my.dataset.org/thisdataset/records/"
81
+ # @option params [String] :source_name a "short name" (i.e. a single word, no spaces) for the kind of data being transformed. e.g. height_data
82
+ # @option params [Integer] :sio_verbose (0) "1" means to use http://semanticscience.org/resource/has-value instead of http://semanticscience.org/resource/SIO_000300 for all sio. Default is 0
83
+ #
84
+ # @return [YARRRML_Template_BuilderII]
85
+ def initialize(params = {}) # get a name from the "new" call, or set a default
86
+
87
+ @baseURI = params.fetch(:baseURI, "|||BASE|||")
88
+ @sio_verbose = params.fetch(:sio_verbose, 0)
89
+ abort "must have a baseURI parameter" unless self.baseURI
90
+ @mappings = []
91
+
92
+ @source_tag = params.fetch(:source_tag, nil)
93
+ abort "must have a source_name parameter" unless self.source_tag
94
+
95
+ @prefix_map = {
96
+ "rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
97
+ "rdfs" => "http://www.w3.org/2000/01/rdf-schema#",
98
+ "ex" => "https://ejp-rd.eu/ids/",
99
+ "obo" => "http://purl.obolibrary.org/obo/",
100
+ "sio" => "http://semanticscience.org/resource/",
101
+ "vocab" => "https://ejp-rd.eu/vocab/",
102
+ "pico" => "https://data.cochrane.org/ontologies/pico/",
103
+ "ndfrt" => "http://purl.bioontology.org/ontology/NDFRT/",
104
+ "edam" => "http://purl.bioontology.org/ontology/EDAM/",
105
+ "ordo" => "http://www.orpha.net/ORDO/",
106
+ }
107
+
108
+ self.add_prefixes(prefixesHash: {"this" => self.baseURI})
109
+ sources_module()
110
+
111
+ end
112
+
113
+
114
+
115
+
116
+ # adds new Prefixes to the prefix map
117
+ #
118
+ # Parameters passed as the value to the key :prefixesHash
119
+ #
120
+ # @param params [Hash]
121
+ # @option params [Hash] :prefixesHash ({}) hash of shortname to URL prefix mappings
122
+ #
123
+ # a hash of prefix [String] => URL prefix
124
+ #
125
+ # e.g. {"mydata" => "https://my.dataset.org/thisdataset/records/"}
126
+ #
127
+ # you can send it an empty hash to simply return the existing hash
128
+ #
129
+ # @return [Hash] the current hash of prefixes
130
+ #
131
+ def add_prefixes(params = {})
132
+
133
+ prefixesHash = params.fetch(:prefixesHash, {})
134
+ $stderr.puts prefixesHash
135
+ @prefix_map.merge!(prefixesHash)
136
+ return self.prefix_map
137
+
138
+ end
139
+
140
+
141
+ # Generate the YARRRML Template
142
+ #
143
+ # No input parameters
144
+ #
145
+ # @return [YAML] represents the YARRRML template
146
+ #
147
+ def generate
148
+ output = Hash.new
149
+ output["prefixes"] = @prefix_map
150
+ output["sources"] = @sources_module
151
+
152
+ clauses = Hash.new
153
+
154
+ self.mappings.each {|m| clauses.merge!(m)}#; $stderr.puts m; $stderr.puts "CLAUSES: #{clauses}\n\n"}
155
+ output["mappings"] = clauses
156
+
157
+ #$stderr.puts output.inspect
158
+ return YAML::dump(output)
159
+
160
+ end
161
+
162
+
163
+
164
+
165
+ def sources_module
166
+
167
+ @sources_module = {
168
+ "#{self.source_tag}-source" =>
169
+ {
170
+ "access" => "|||DATA|||",
171
+ "referenceFormulation" => "|||FORMULATION|||",
172
+ "iterator" => "$"
173
+ }
174
+ }
175
+
176
+ end
177
+
178
+
179
+
180
+
181
+
182
+ # creates a single clause of the YARRRML (one subject, [p, o; p,o;....] mapping)
183
+ #
184
+ # DO NOT use this externally! I will eventually make it private...
185
+ #
186
+ # @param name [String] a unique name for that YARRRRML component (e.g. thisRole_realized_in_SomeProcess)
187
+ # @param source [String] the YARRRML source identifier
188
+ # @param s [String] URI of the subject
189
+ # @param pots [Array] An array of arrays of [Predicate-object-datatype] (datatype is "iri" if it is a Node, rather than a literal)
190
+ #
191
+ # @return [String] the mapping_clause in YAML format
192
+ #
193
+ def mapping_clause(name, source, s, pots)
194
+ pos = []
195
+ pots.each do |pot|
196
+ #$stderr.puts pot.class
197
+ (pred, obj, type) = pot
198
+ #$stderr.puts "#{pred} #{obj} #{type}"
199
+ typetag = "type"
200
+ typetag = "datatype" unless type == 'iri'
201
+ type = "xsd:string" unless type
202
+ pos << {
203
+ "predicates" => pred,
204
+ "objects" => {
205
+ "value" => obj,
206
+ typetag => type}
207
+ }
208
+ end
209
+
210
+ mappingclause = {
211
+ name => {
212
+ "sources" => source,
213
+ "s" => s,
214
+ "po" => pos
215
+ }
216
+ }
217
+
218
+ return mappingclause
219
+ end
220
+
221
+
222
+ def get_root_url(uniq)
223
+ if uniq
224
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})_process"
225
+ else
226
+ "this:individual_$(#{@personid_column})_process"
227
+ end
228
+ end
229
+
230
+ # creates an entity/identifier/role set of clauses
231
+ #
232
+ # Parameters passed as a hash
233
+ #
234
+ # @param params [Hash] a hash of options
235
+ # @option params :entityid_column [String] (required) the column header that contains the identifier of the entity
236
+ # @option params :uniqueid_column [String] (required) the column header that contains unique ID for that row (over ALL datasets! e.g. a hash of a timestamp); defaults to "uniqid"
237
+ # @option params :identifier_type [String] the URL of the ontological type of that identifier; defaults to 'sio:identifier'
238
+ # @option params :identifier_type_column [String] the column header for the ontological type of that identifier. Overrides identifier_type.
239
+ # @option params :entity_type [String] the URL of the ontological type defining a "entity"; defaults to 'sio:specialized-object'
240
+ # @option params :entity_type_column [String] the column header for the ontological type of the "entity". Overrides entity_type
241
+ # @option params :entity_label [String] the label for an "entity"; defaults to 'some entity'
242
+ # @option params :entity_label_column [String] column for the label
243
+ # @option params :entity_tag [String] a single-word unique tag for the entity within this model (defaults to "thisEntity"). Does not appear in the output RDF
244
+ # @option params :entity_role_tag [String] a single-word tag for therole (e.g. "patient", "clinician", "drug") the entity plays in this dataset; defaults to "thisRole". This does not appear in the output RDF
245
+ # @option params :role_type [String] the URL for the ontological type of that role; defaults to "obo:OBI_0000093" ("patient")
246
+ # @option params :role_type_column [String] the column header that contains the ontological type of that role. Overrides role_type
247
+ # @option params :role_label [String] the label for that kind of role; defaults to "Some Role"
248
+ # @option params :role_label_column [String] the column header that has the label for that kind of role (overrides role_label)
249
+
250
+ def entity_identifier_role_mappings(params = {})
251
+ @entityid_column = params.fetch(:entityid_column, 'pid')
252
+ @uniqueid_column = params.fetch(:uniqueid_column, 'uniqid')
253
+
254
+ identifier_type = params.fetch(:identifier_type, SIO["identifier"][self.sio_verbose])
255
+ identifier_type_column = params.fetch(:identifier_type_column, nil)
256
+ entity_tag = params.fetch(:entity_tag, 'thisEntity')
257
+ entity_type = params.fetch(:entity_type, SIO["specialized-object"][self.sio_verbose])
258
+ entity_type_column = params.fetch(:entity_type_column, nil)
259
+ entity_label = params.fetch(:entity_label, nil)
260
+ entity_label_column = params.fetch(:entity_label_column, nil)
261
+ entity_role_tag = params.fetch(:entity_role_tag, 'thisRole')
262
+ role_type = params.fetch(:role_type, 'obo:OBI_0000093') # patient
263
+ role_type_column = params.fetch(:role_type_column, nil) #
264
+ role_label = params.fetch(:role_label, 'Some Role') # patient
265
+ role_label_column = params.fetch(:role_label_column, nil) #
266
+
267
+ identifier_type = identifier_type_column ? "$(#{identifier_type_column})":identifier_type
268
+ entity_type = entity_type_column ? "$(#{entity_type_column})":entity_type
269
+ role_type = role_type_column ? "$(#{role_type_column})":role_type
270
+ role_label = role_label_column ? "$(#{role_label_column})":role_label
271
+ entity_label = entity_label_column ? "$(#{entity_label_column})":entity_label
272
+
273
+ abort "You MUST have a @entityid_column and a @uniqueid_column to use this library. Sorry!" unless @entityid_column and @uniqueid_column
274
+ @mappings << mapping_clause(
275
+ "identifier_has_value_for_#{entity_tag}_#{entity_role_tag}",
276
+ ["#{source_tag}-source"],
277
+ "this:individual_#{entity_tag}_$(#{@entityid_column})#ID",
278
+ [[SIO["has-value"][self.sio_verbose], "$(#{@entityid_column})", "xsd:string"]]
279
+ )
280
+
281
+ @mappings << mapping_clause(
282
+ "identifier_denotes_role_#{entity_role_tag}",
283
+ ["#{source_tag}-source"],
284
+ "this:individual_#{entity_tag}_$(#{@entityid_column})#ID",
285
+ [
286
+ ["a", "#{identifier_type}", "iri"],
287
+ ["a", SIO["identifier"][self.sio_verbose], "iri"],
288
+ [SIO["denotes"][self.sio_verbose], "this:individual_#{entity_tag}_$(#{@entityid_column})_$(#{@uniqueid_column})##{entity_role_tag}", "iri"],
289
+ ]
290
+ )
291
+ @mappings << mapping_clause(
292
+ "entity_has_role_#{entity_role_tag}",
293
+ ["#{source_tag}-source"],
294
+ "this:individual_#{entity_tag}_$(#{@entityid_column})#Entity",
295
+ [
296
+ ["a", "#{entity_type}", "iri"],
297
+ ["a", SIO["object"][self.sio_verbose], "iri"],
298
+ [SIO["has-role"][self.sio_verbose], "this:individual_#{entity_tag}_$(#{@entityid_column})_$(#{@uniqueid_column})##{entity_role_tag}", "iri"],
299
+ ]
300
+ )
301
+
302
+ @mappings << mapping_clause(
303
+ "#{entity_role_tag}_annotation",
304
+ ["#{source_tag}-source"],
305
+ "this:individual_#{entity_tag}_$(#{@entityid_column})_$(#{@uniqueid_column})##{entity_role_tag}",
306
+ [
307
+ ["a", "#{role_type}", "iri"],
308
+ ["a", SIO["role"][self.sio_verbose], "iri"],
309
+ ["rdfs:label", " Role: #{role_label}", "xsd:string"],
310
+ ]
311
+ )
312
+ if entity_label
313
+ @mappings << mapping_clause(
314
+ "#{entity_role_tag}_entity_label_annotation",
315
+ ["#{source_tag}-source"],
316
+ "this:individual_#{entity_tag}_$(#{@entityid_column})#Entity",
317
+ [
318
+ ["rdfs:label", " Role: #{entity_label}", "xsd:string"],
319
+ ]
320
+ )
321
+ end
322
+
323
+
324
+
325
+ end
326
+
327
+ # creates the person/identifier/role portion of the CDE
328
+ #
329
+ # Parameters passed as a hash. this is a specification of the entity-identifier-role method, with Patient defaults
330
+ #
331
+ # @param params [Hash] a hash of options
332
+ # @option params :personid_column [String] (required) the column header that contains the anonymous identifier of the person; defaults to "pid"
333
+ # @option params :uniqueid_column [String] (required) the column header that contains unique ID for that row (over ALL datasets! e.g. a hash of a timestamp); defaults to "uniqid"
334
+ # @option params :identifier_type [String] the URL of the ontological type of that identifier; defaults to 'sio:identifier'
335
+ # @option params :identifier_type_column [String] the column header for the ontological type of that identifier. Overrides identifier_type.
336
+ # @option params :person_type [String] the URL of the ontological type defining a "person"; defaults to 'sio:person'
337
+ # @option params :person_type_column [String] the column header for the ontological type of the "individual". Overrides person_type
338
+ # @option params :person_role_tag [String] a single-word label for the kind of role (e.g. "patient", "clinician") the person plays in this dataset; defaults to "thisRole"
339
+ # @option params :role_type [String] the URL for the ontological type of that role; defaults to "obo:OBI_0000093" ("patient")
340
+ # @option params :person_tag [String] a single-word unique tag for the person within this model (defaults to "thisPerson"). Does not appear in the output RDF
341
+ # @option params :role_type_column [String] the column header that contains the ontological type of that role. Overrides role_type
342
+ # @option params :role_label [String] the label for that kind of role; defaults to "Patient"
343
+ # @option params :role_label_column [String] the column header that has the label for that kind of role (overrides role_label)
344
+ # @option params :person_label [String] the label for that person (no default)
345
+ # @option params :person_label_column [String] the column header that has the label for that person (no default)
346
+ #
347
+ def person_identifier_role_mappings(params = {})
348
+ @personid_column = params.fetch(:personid_column, 'pid')
349
+ uniqueid_column = params.fetch(:uniqueid_column, 'uniqid')
350
+
351
+ identifier_type = params.fetch(:identifier_type, SIO["identifier"][self.sio_verbose])
352
+ identifier_type_column = params.fetch(:identifier_type_column, nil)
353
+ person_type = params.fetch(:person_type, SIO["person"][self.sio_verbose])
354
+ person_tag = params.fetch(:person_tag, 'thisPerson')
355
+ person_type_column = params.fetch(:person_type_column, nil)
356
+ person_role_tag = params.fetch(:person_role_tag, 'thisRole')
357
+ role_type = params.fetch(:role_type, 'obo:OBI_0000093') # patient
358
+ role_type_column = params.fetch(:role_type_column, nil) #
359
+ role_label = params.fetch(:role_label, 'Patient Role') # patient
360
+ role_label_column = params.fetch(:role_label_column, nil) #
361
+ person_label = params.fetch(:person_label, nil) # patient
362
+ person_label_column = params.fetch(:person_label_column, nil) #
363
+
364
+ self.entity_identifier_role_mappings({
365
+ entityid_column: @personid_column,
366
+ uniqueid_column: uniqueid_column,
367
+ identifier_type: identifier_type,
368
+ identifier_type_column: identifier_type_column,
369
+ entity_tag: person_tag,
370
+ entity_type: person_type,
371
+ entity_type_column: person_type_column,
372
+ entity_role_tag: person_role_tag,
373
+ role_type: role_type,
374
+ role_type_column: role_type_column,
375
+ role_label: role_label,
376
+ role_label_column: role_label_column,
377
+ entity_label: person_label,
378
+ entity_label_column: person_label_column,
379
+ })
380
+
381
+ end
382
+
383
+
384
+
385
+
386
+
387
+
388
+
389
+ # creates the role_in_process portion of the CDE
390
+ #
391
+ # Parameters passed as a hash
392
+ #
393
+ # @param params [Hash] a hash of options
394
+ # @option params :person_role_tag [String] the tag of the role that is fulfilled in this process (default 'thisRole') - see person_role_tag above, synchronize these tags!
395
+ # @option params :entity_role_tag [String] the tag of the role that is fulfilled in this process (default 'thisRole') - see entity_role_tag above, synchronize these tags!
396
+ # @option params :process_type [String] the URL for the ontological type of the process (defaults to http://semanticscience.org/resource/process)
397
+ # @option params :process_type_column [String] the column header that contains the URL for the ontological type of the process - overrides process_type
398
+ # @option params :process_tag [String] some single-word tag for that process; defaults to "thisprocess"
399
+ # @option params :process_label [String] the label associated with the process type in that row (defaults to "thisprocess")
400
+ # @option params :process_label_column [String] the column header for the label associated with the process type in that row
401
+ # @option params :process_start_column [ISO 8601 date (only date)] (optional) the column header for the datestamp when that process started. NOTE: For instantaneous processes, create ONLY the start date column, and an identical end date will be automatically generated
402
+ # @option params :process_end_column [ISO 8601 date (only date)] (optional) the column header for the datestamp when that process ended
403
+ # @option params :process_duration_column [xsd:int] (optional) the column header for the duration of the event measured in integer numbers of days
404
+ # @option params :make_unique_process [boolean] (true) (optional) if you want the core URI to be globally unique, or based only on the patient ID. this can be used to merge nodes over multiple runs of different yarrrml transforms.
405
+ def role_in_process(params)
406
+ person_role_tag = params.fetch(:person_role_tag, 'thisRole')
407
+ entity_role_tag = params.fetch(:person_role_tag, nil)
408
+ process_type = params.fetch(:process_type, SIO["process"][self.sio_verbose])
409
+ process_type_column = params.fetch(:process_type_column, nil)
410
+ process_tag = params.fetch(:process_tag, 'thisprocess') # some one-word name
411
+ process_label = params.fetch(:process_label, 'Process')
412
+ process_label_column = params.fetch(:process_label_column, nil)
413
+ process_start_column = params.fetch(:process_start_column, nil)
414
+ process_end_column = params.fetch(:process_end_column, nil)
415
+ process_duration_column = params.fetch(:process_end_column, nil)
416
+ make_unique_process = params.fetch(:make_unique_process, true)
417
+
418
+ process_type = process_type_column ? "$(#{process_type_column})":process_type
419
+ process_label = process_label_column ? "$(#{process_label_column})":process_label
420
+
421
+ person_role_tag = entity_role_tag if entity_role_tag
422
+
423
+ root_url = get_root_url(make_unique_process)
424
+
425
+ @mappings << mapping_clause(
426
+ "#{person_role_tag}_realized_#{process_tag}",
427
+ ["#{source_tag}-source"],
428
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})##{person_role_tag}",
429
+ [
430
+ [SIO["is-realized-in"][self.sio_verbose], root_url + "#process_#{process_tag}","iri"]
431
+ ]
432
+ )
433
+
434
+ @mappings << mapping_clause(
435
+ "process_#{process_tag}_process_annotation",
436
+ ["#{source_tag}-source"],
437
+ root_url + "#process_#{process_tag}",
438
+ [
439
+ ["rdf:type",SIO["process"][self.sio_verbose], "iri"],
440
+ ["rdf:type","#{process_type}", "iri"],
441
+ ["rdfs:label","Process: #{process_label}", "xsd:string"],
442
+ ]
443
+ )
444
+
445
+
446
+ if process_start_column
447
+ @mappings << mapping_clause(
448
+ "process_#{process_tag}_process_annotation_start",
449
+ ["#{source_tag}-source"],
450
+ root_url + "#process_#{process_tag}",
451
+ [[SIO["has-start-time"][self.sio_verbose], root_url + "#process_#{process_tag}_startdate_#{process_start_column}", "iri"]]
452
+ )
453
+ @mappings << mapping_clause(
454
+ "process_#{process_tag}_process_annotation_start_value",
455
+ ["#{source_tag}-source"],
456
+ root_url + "#process_#{process_tag}_startdate_$(#{process_start_column})",
457
+ [
458
+ [SIO["has-value"][self.sio_verbose], "$(#{process_start_column})", "xsd:date"],
459
+ ["rdf:type", SIO["start-date"][self.sio_verbose], "iri"],
460
+ ["rdfs:label", "Start Date: $(#{process_start_column})"],
461
+ ]
462
+ )
463
+ # now create the MIRROR (!!!!) end time, if one is not provided
464
+ unless process_end_column
465
+ @mappings << mapping_clause(
466
+ "process_#{process_tag}_process_annotation_end",
467
+ ["#{source_tag}-source"],
468
+ root_url + "#process_#{process_tag}",
469
+ [[SIO["has-end-time"][self.sio_verbose], root_url + "#process_#{process_tag}_enddate_#{process_start_column}", "iri"]]
470
+ )
471
+ @mappings << mapping_clause(
472
+ "process_#{process_tag}_process_annotation_end_value",
473
+ ["#{source_tag}-source"],
474
+ root_url + "#process_#{process_tag}_enddate_$(#{process_start_column})",
475
+ [
476
+ [SIO["has-value"][self.sio_verbose], "$(#{process_start_column})", "xsd:date"],
477
+ ["rdf:type", SIO["end-date"][self.sio_verbose], "iri"],
478
+ ["rdfs:label", "End Date: $(#{process_start_column})"],
479
+ ]
480
+ )
481
+ end
482
+
483
+ end
484
+
485
+ if process_end_column
486
+ @mappings << mapping_clause(
487
+ "process_#{process_tag}_process_annotation_end",
488
+ ["#{source_tag}-source"],
489
+ root_url + "#process_#{process_tag}",
490
+ [[SIO["has-end-time"][self.sio_verbose], root_url + "#process_#{process_tag}_enddate_#{process_end_column}", "iri"]]
491
+ )
492
+ @mappings << mapping_clause(
493
+ "process_#{process_tag}_process_annotation_end_value",
494
+ ["#{source_tag}-source"],
495
+ root_url + "#process_#{process_tag}_enddate_#{process_end_column}",
496
+ [
497
+ [SIO["has-value"][self.sio_verbose], "$(#{process_end_column})", "xsd:date"],
498
+ ["rdf:type", SIO["end-date"][self.sio_verbose], "iri"],
499
+ ["rdfs:label", "End Date: $(#{process_end_column})"],
500
+ ]
501
+ )
502
+ end
503
+
504
+ if process_duration_column
505
+ @mappings << mapping_clause(
506
+ "#{process_tag}_process_annotation_duration",
507
+ ["#{source_tag}-source"],
508
+ root_url + "##{process_tag}",
509
+ [[SIO["exists-at"][self.sio_verbose], root_url + "##{process_tag}_exists_at_#{process_duration_column}", "iri"]]
510
+ )
511
+ @mappings << mapping_clause(
512
+ "#{process_tag}_process_annotation_duration_value",
513
+ ["#{source_tag}-source"],
514
+ root_url + "##{process_tag}_exists_at_#{process_duration_column}",
515
+ [
516
+ [SIO["has-value"][self.sio_verbose], "$(#{process_duration_column})"],
517
+ ["rdf:type", SIO["day"][self.sio_verbose], "iri"],
518
+ ["rdfs:label", "Duration: $(#{process_duration_column}) days"],
519
+ ]
520
+ )
521
+ end
522
+
523
+ end
524
+
525
+
526
+
527
+ # creates the process has annotations portion of the CDE
528
+ #
529
+ # Parameters passed as a hash
530
+ #
531
+ # @param params [Hash] a hash of options
532
+ # @option params :process_tag [String] (required) the same process tag that is used in the "role in process"
533
+ # @option params :process_annotations_columns [Array] ([[predcol, valcol,datatypecol], ...]) (if predol looks like a URI, it will be used as a URI)
534
+ # @option params :process_annotations [Array] ([[pred, valuecolumn,datatype]...])
535
+ # @option params :make_unique_process [boolean] (true) (optional) if you want the core URI to be globally unique, or based only on the patient ID. this can be used to merge nodes over multiple runs of different yarrrml transforms.
536
+ def process_has_annotations(params)
537
+ process_tag = params.fetch(:process_tag, "thisprocess")
538
+ process_annotations_columns = params.fetch(:process_annotations_columns, [])
539
+ process_annotations = params.fetch(:process_annotations, [])
540
+ make_unique_process = params.fetch(:make_unique_process, true)
541
+
542
+ root_url = get_root_url(make_unique_process)
543
+
544
+
545
+ if !process_annotations_columns.empty?
546
+ process_annotations_columns.each do |predicate, value, datatype|
547
+ case
548
+ when datatype =~ /iri/
549
+ datatype = "iri"
550
+ when datatype =~ /^xsd\:/
551
+ datatype = datatype
552
+ when datatype
553
+ datatype = "$(#{datatype})" # its a column header
554
+ else
555
+ datatype = "xsd:string"
556
+ end
557
+
558
+
559
+ if predicate =~ /https?\:\/\//
560
+ predicate = predicate
561
+ else
562
+ predicate = "$(#{predicate})" # if the predicate looks like a URI, assume that it is, rather than a colulmn header
563
+ end
564
+
565
+ next unless predicate and value
566
+ uniqid = get_uniq_id
567
+
568
+ @mappings << mapping_clause(
569
+ "#{uniqid}_process_custom_annotation",
570
+ ["#{source_tag}-source"],
571
+ root_url + "#process_#{process_tag}",
572
+ [[predicate, "$(#{value})", datatype]]
573
+ )
574
+
575
+ end
576
+ elsif !process_annotations.empty?
577
+ process_annotations.each do |predicate, value, datatype|
578
+ datatype = "xsd:string" unless datatype # otherwise make it default
579
+
580
+ next unless predicate and value
581
+ uniqid = get_uniq_id
582
+
583
+ @mappings << mapping_clause(
584
+ "#{uniqid}_process_custom_annotation",
585
+ ["#{source_tag}-source"],
586
+ root_url + "#process_#{process_tag}",
587
+ [[predicate, value, datatype]]
588
+ )
589
+
590
+ end
591
+
592
+ end
593
+
594
+
595
+ end
596
+
597
+
598
+ # creates the process has agent portion of the CDE
599
+ #
600
+ # Parameters passed as a hash
601
+ #
602
+ # @param params [Hash] a hash of options
603
+ # @option params :process_tag [String] (required) the same process tag that is used in the "role in process"
604
+ # @option params :entityid_column [String] (required) default "pid"
605
+ # @option params :entity_tag [String] (required) default "thisEntity". The entity-tag that you used for the entity in the entity/identifier/role clauses
606
+ def process_has_agent(params)
607
+ process_tag = params.fetch(:process_tag, "thisprocess")
608
+ entityid_column = params.fetch(:entityid_column, "pid")
609
+ entity_tag = params.fetch(:entity_tag, "thisEntity")
610
+ make_unique_process = params.fetch(:make_unique_process, true)
611
+
612
+ root_url = get_root_url(make_unique_process)
613
+
614
+
615
+ @mappings << mapping_clause(
616
+ "process_has_agent_#{entity_tag}",
617
+ ["#{source_tag}-source"],
618
+ root_url + "##{process_tag}",
619
+ [[SIO['has-agent'][self.sio_verbose], "this:individual_#{entity_tag}_$(#{entityid_column})#Entity" , 'iri']]
620
+ )
621
+
622
+
623
+ end
624
+
625
+
626
+
627
+
628
+ # creates the process_has_part portion of the CDE
629
+ #
630
+ # Parameters passed as a hash
631
+ #
632
+ # @param params [Hash] a hash of options
633
+ # @option params :parent_process_tag [String] (required) the same process tag that is used in the "role in process" for the parent process
634
+ # @option params :part_process_tag [String] (required) the same process tag that is used in the "role in process" for the process that is a part of the parent
635
+ # @option params :part_process_type [String] (optional) the rdf:type of the child process
636
+ # @option params :part_process_type_column [String] (optional) the rdf:type of the child process
637
+ # @option params :parent_unique_process [boolean] (true) (optional) if you want the core URI to be globally unique, or based only on the patient ID. this can be used to merge nodes over multiple runs of different yarrrml transforms.
638
+ # @option params :part_unique_process [boolean] (true) (optional) if you want the core URI to be globally unique, or based only on the patient ID. this can be used to merge nodes over multiple runs of different yarrrml transforms.
639
+ def process_has_part(params)
640
+ parent_process_tag = params.fetch(:parent_process_tag, nil)
641
+ part_process_tag = params.fetch(:part_process_tag, nil)
642
+ part_process_type = params.fetch(:part_process_type, nil)
643
+ part_process_type_column = params.fetch(:part_process_type_column, nil)
644
+ parent_unique_process = params.fetch(:parent_unique_process, true)
645
+ part_unique_process = params.fetch(:part_unique_process, true)
646
+
647
+ parent_root_url = get_root_url(parent_unique_process)
648
+ part_root_url = get_root_url(part_unique_process)
649
+
650
+ part_process_type = part_process_type_column ? "$(#{part_process_type_column})":part_process_type
651
+
652
+ abort "cannot create part relationship unless both parent and child processes have a tag" unless (parent_process_tag && part_process_tag)
653
+
654
+ #uniqid = get_uniq_id
655
+
656
+ @mappings << mapping_clause(
657
+ "process_#{parent_process_tag}_has_part_#{part_process_tag}",
658
+ ["#{source_tag}-source"],
659
+ parent_root_url + "#process_#{parent_process_tag}",
660
+ [
661
+ [SIO["has-part"][self.sio_verbose], part_root_url + "#process_#{part_process_tag}" , "iri"],
662
+ ]
663
+ )
664
+ @mappings << mapping_clause(
665
+ "process_#{part_process_tag}_process_has_type",
666
+ ["#{source_tag}-source"],
667
+ parent_root_url + "#process_#{part_process_tag}",
668
+ [
669
+ ["rdf:type", SIO["process"][self.sio_verbose], "iri"],
670
+ ]
671
+ )
672
+ if part_process_type
673
+ @mappings << mapping_clause(
674
+ "process_#{part_process_tag}_process_has_specific_type",
675
+ ["#{source_tag}-source"],
676
+ parent_root_url + "#process_#{part_process_tag}",
677
+ [
678
+ ["rdf:type", part_process_type, "iri"],
679
+ ]
680
+ )
681
+ end
682
+
683
+ end
684
+
685
+
686
+
687
+
688
+
689
+ # creates the process has target portion of the CDE
690
+ #
691
+ # Parameters passed as a hash
692
+ #
693
+ # @param params [Hash] a hash of options
694
+ # @option params :process_with_target_tag [String] (required) the same process tag that is used in the "role in process" for which this is the target
695
+ # @option params :target_type_tag [String] a tag to differentiate this target from other targets
696
+ # @option params :target_type [String] the ontological type for the target (e.g. process is targetted at creatinine - http://purl.obolibrary.org/obo/CHEBI_16737)
697
+ # @option params :target_type_column [String] the column header specifying the ontological type for the target node (overrides target_type).
698
+ # @option params :target_type_label [String] the label for all targets
699
+ # @option params :target_type_label_column [String] the label column for each target
700
+ # @option params :make_unique_process [boolean] (true) (optional) if you want the core URI to be globally unique, or based only on the patient ID. this can be used to merge nodes over multiple runs of different yarrrml transforms.
701
+ def process_has_target(params)
702
+ process_with_target_tag = params.fetch(:process_with_target_tag, "thisprocess") # some one-word name
703
+ target_type_tag = params.fetch(:target_type_tag, "thisTarget") # some one-word name
704
+ target_type = params.fetch(:target_type, SIO["information-content-entity"][self.sio_verbose]) # some one-word name
705
+ target_type_column = params.fetch(:target_type_column, nil) # some one-word name
706
+ target_type_label = params.fetch(:target_type_label, "information content entity") # some one-word name
707
+ target_type_label_column = params.fetch(:target_type_label_column, nil) # some one-word name
708
+ make_unique_process = params.fetch(:make_unique_process, true)
709
+
710
+ root_url = get_root_url(make_unique_process)
711
+
712
+
713
+ abort "must specify the process_with_target_tag
714
+ (the identifier of the process that has the input)
715
+ before you can use the process_has_target function" unless process_with_target_tag
716
+
717
+ target_type = target_type_column ? "$(#{target_type_column})":target_type
718
+ target_label = target_type_label_column ? "$(#{target_type_label_column})":target_type_label
719
+
720
+ @mappings << mapping_clause(
721
+ "process_#{process_with_target_tag}_has_target_#{target_type_tag}",
722
+ ["#{source_tag}-source"],
723
+ root_url + "#process_#{process_with_target_tag}",
724
+ [[SIO["has-target"][self.sio_verbose],"this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_target_tag}_Target", "iri"]]
725
+ )
726
+
727
+ @mappings << mapping_clause(
728
+ "process_#{process_with_target_tag}_has_target_#{target_type_tag}_annotation",
729
+ ["#{source_tag}-source"],
730
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_target_tag}_Target",
731
+ [
732
+ ["rdf:type",SIO["information-content-entity"][self.sio_verbose], "iri"],
733
+ ["rdf:type","#{target_type}", "iri"],
734
+ ["rdfs:label","Process Target: #{target_label}", "xsd:string"],
735
+ ]
736
+ )
737
+
738
+ end
739
+
740
+
741
+
742
+
743
+
744
+
745
+ # creates the process is specified by portion of the CDE
746
+ #
747
+ # Parameters passed as a hash
748
+ #
749
+ # @param params [Hash] a hash of options
750
+ # @option params :process_with_protocol_tag [String] (required) the same process tag that is used in the "role in process" for which this is the input
751
+ # @option params :protocol_type_tag [String] a tag to differentiate this input from other inputs
752
+ # @option params :process_type [String] ("sio:process" - process) usually you want to be more specific, like "measuring" or "estimating"
753
+ # @option params :process_type_column [String] ("sio:process" - process)
754
+ # @option params :process_type_label [String] ("protocol")
755
+ # @option params :process_type_label_column [String] ("protocol")
756
+ # @option params :protocol_uri [String] uri of the process protocol for all inputs
757
+ # @option params :protocol_uri_column [String] column header for the protocol uri column
758
+ # @option params :protocol_label [String] label of the process protocol for all inputs
759
+ # @option params :protocol_label_column [String] column header for the label for the protocol uri
760
+ # @option params :make_unique_process [boolean] (true) (optional) if you want the core URI to be globally unique, or based only on the patient ID. this can be used to merge nodes over multiple runs of different yarrrml transforms.
761
+ def process_is_specified_by(params)
762
+ process_with_protocol_tag = params.fetch(:process_with_protocol_tag, "thisprocess") # some one-word name
763
+ protocol_type_tag = params.fetch(:protocol_type_tag, "thisProtocoltype") # some one-word name
764
+ process_type = params.fetch(:processs_type, SIO["process"][self.sio_verbose]) #
765
+ process_type_column = params.fetch(:protocol_type_column, nil) #
766
+ process_type_label = params.fetch(:protocol_type_label, "Process")
767
+ process_type_label_column = params.fetch(:protocol_type_label_column, nil)
768
+ protocol_uri = params.fetch(:protocol_uri, nil) # Protocol
769
+ protocol_uri_column = params.fetch(:protocol_uri_column, nil)
770
+ protocol_label = params.fetch(:protocol_uri, nil) # Protocol
771
+ protocol_label_column = params.fetch(:protocol_uri_column, nil)
772
+ protocol_type = params.fetch(:protocol_type, "http://purl.obolibrary.org/obo/NCIT_C42651") # Protocol
773
+ protocol_type_column = params.fetch(:protocol_type_column, nil)
774
+ make_unique_process = params.fetch(:make_unique_process, true)
775
+
776
+ root_url = get_root_url(make_unique_process)
777
+
778
+
779
+ abort "must specify the process_with_target_tag and the protocol type tag
780
+ (the identifier of the process that has the input)
781
+ before you can use the process_has_target function" unless (process_with_protocol_tag and protocol_type_tag)
782
+
783
+ process_type = process_type_column ? "$(#{process_type_column})":process_type
784
+ process_type_label = process_type_label_column ? "$(#{process_type_label_column})":process_type_label
785
+ protocol_uri = protocol_uri_column ? "$(#{protocol_uri_column})":protocol_uri
786
+ protocol_label = protocol_label_column ? "$(#{protocol_label_column})":protocol_label
787
+ protocol_type = protocol_type_column ? "$(#{protocol_type_column})":protocol_type
788
+
789
+ abort "must specify either a default protocol URI, or a column of protocol URIs" unless protocol_uri
790
+
791
+ @mappings << mapping_clause(
792
+ "#{process_with_protocol_tag}_specified_by_#{protocol_type_tag}_specifictype_annotation",
793
+ ["#{source_tag}-source"],
794
+ root_url + "##{process_with_protocol_tag}",
795
+ [
796
+ ["rdf:type","#{process_type}", "iri"],
797
+ ["rdfs:label","Protocol: #{process_type_label}", "xsd:string"],
798
+ ]
799
+ )
800
+
801
+ @mappings << mapping_clause(
802
+ "#{process_with_protocol_tag}_specified_by_#{protocol_type_tag}",
803
+ ["#{source_tag}-source"],
804
+ root_url + "##{process_with_protocol_tag}",
805
+ [[SIO["is-specified-by"][self.sio_verbose], protocol_uri, "iri"]]
806
+ )
807
+
808
+ @mappings << mapping_clause(
809
+ "#{process_with_protocol_tag}_specified_by_#{protocol_type_tag}_annotation",
810
+ ["#{source_tag}-source"],
811
+ protocol_uri,
812
+ [
813
+ ["rdf:type",SIO["information-content-entity"][self.sio_verbose], "iri"],
814
+ ["rdf:type","http://purl.obolibrary.org/obo/NCIT_C42651", "iri"], # Protocol
815
+ ["rdf:type","#{protocol_type}", "iri"],
816
+ ["rdfs:label","Protocol: #{protocol_label}", "xsd:string"],
817
+ ]
818
+ )
819
+
820
+ end
821
+
822
+
823
+
824
+
825
+
826
+ # creates the process caused by
827
+ #
828
+ # Parameters passed as a hash. there can be only one cause!
829
+ #
830
+ # @param params [Hash] a hash of options
831
+ # @option params :process_with_cause_tag [String] (required) the same process tag that is used in the "role in process" for which this is the input
832
+ # @option params :cause_type [URI] an ontological type for the cause (process or event or entity are all fine)
833
+ # @option params :cause_type_column [string] column header for cause URIs
834
+ # TODO: Allow any existing node to be a cause...
835
+ def process_caused_by(params)
836
+ process_with_cause_tag = params.fetch(:process_with_cause_tag, nil) # some one-word name
837
+ cause_type = params.fetch(:cause_type, nil)
838
+ cause_type_column = params.fetch(:cause_type_column, nil)
839
+ make_unique_process = params.fetch(:make_unique_process, true)
840
+
841
+ root_url = get_root_url(make_unique_process)
842
+
843
+ cause_type = cause_type_column ? "$(#{cause_type_column})":cause_type
844
+
845
+ abort "must specify the process_with_cause_tag" unless process_with_cause_tag
846
+ abort "must specify the cause type" unless (cause_type or cause_type_column)
847
+
848
+ @mappings << mapping_clause(
849
+ "process_#{process_with_cause_tag}_has_cause",
850
+ ["#{source_tag}-source"],
851
+ root_url + "#process_#{process_with_cause_tag}",
852
+ [[SIO["is-causally-related-from"][self.sio_verbose], root_url + "#cause_of_process_#{process_with_cause_tag}", "iri"]]
853
+ )
854
+
855
+ @mappings << mapping_clause(
856
+ "process_#{process_with_cause_tag}_has_cause_annotation",
857
+ ["#{source_tag}-source"],
858
+ root_url + "#cause_of_process_#{process_with_cause_tag}",
859
+ [
860
+ ["rdf:type",SIO["entity"][self.sio_verbose], "iri"],
861
+ ["rdf:type",cause_type, "iri"],
862
+ ]
863
+ )
864
+
865
+ end
866
+
867
+
868
+ # creates the process has_attribute
869
+ #
870
+ # Parameters passed as a hash. there can be only one cause!
871
+ #
872
+ # @param params [Hash] a hash of options
873
+ # @option params :process_with_attribute_tag [String] (required) the same process tag that is used in the "role in process" for which this is the input
874
+ # @option params :attribute_tag [string] the tag of the attribute
875
+ def process_has_attribute(params)
876
+ process_with_attribute_tag = params.fetch(:process_with_attribute_tag, nil) # some one-word name
877
+ attribute_tag = params.fetch(:attribute_tag, nil) # some one-word name
878
+
879
+ make_unique_process = params.fetch(:make_unique_process, true)
880
+
881
+ root_url = get_root_url(make_unique_process)
882
+
883
+ abort "must specify the process_with_attribute_tag" unless process_with_attribute_tag
884
+ abort "must specify the attribute_tag" unless (attribute_tag)
885
+
886
+ @mappings << mapping_clause(
887
+ "process_#{process_with_attribute_tag}_has_attribute_#{attribute_tag}",
888
+ ["#{source_tag}-source"],
889
+ root_url + "#process_#{process_with_attribute_tag}",
890
+ [[SIO["has-attribute"][self.sio_verbose], root_url + "#attribute_#{attribute_tag}", "iri"]]
891
+ )
892
+ end
893
+
894
+
895
+
896
+
897
+ # creates the build attribute clauses
898
+ #
899
+ # Parameters passed as a hash.
900
+ #
901
+ # @param params [Hash] a hash of options
902
+ # @option params :attribute_tag [String] (required) a unique tag for the attribute
903
+ # @option params :attribute_type [URI] an ontological type for the attribute
904
+ # @option params :attribute_type_column [string] column header for attribute URIs
905
+ # @option params :attribute_value_column [string] column header for attribute URIs
906
+ # @option params :attribute_label [string] attribute value label
907
+ # @option params :attribute_label_column [string] column header for attribute value label
908
+ # @option params :attribute_value_unit_column [string] column header for attribute unit URIs
909
+ # @option params :attribute_value_unit_label_column [string] column header for attribute unit labels
910
+ #
911
+ # TODO: Allow any existing node to be a cause...
912
+ def build_attribute(params)
913
+ attribute_tag = params.fetch(:attribute_tag, nil) # some one-word name
914
+ attribute_type = params.fetch(:attribute_type, nil)
915
+ attribute_label = params.fetch(:attribute_label, nil)
916
+ attribute_label_column = params.fetch(:attribute_label_column, nil)
917
+ attribute_type_column = params.fetch(:attribute_type_column, nil)
918
+ attribute_value_column = params.fetch(:attribute_value_column, nil)
919
+ attribute_value_unit_column = params.fetch(:attribute_value_unit_column, nil)
920
+ attribute_value_unit_label_column = params.fetch(:attribute_value_unit_label_column, nil)
921
+ make_unique_process = params.fetch(:make_unique_process, true)
922
+
923
+ root_url = get_root_url(make_unique_process)
924
+
925
+ attribute_type = attribute_type_column ? "$(#{attribute_type_column})":attribute_type
926
+ attribute_label = attribute_label_column ? "$(#{attribute_label_column})":attribute_label
927
+ attribute_value_unit_column = "$(#{attribute_value_unit_column})" if attribute_value_unit_column
928
+ attribute_value_unit_label_column = "$(#{attribute_value_unit_label_column})" if attribute_value_unit_label_column
929
+
930
+ abort "must specify the attribute_tag" unless attribute_tag
931
+ abort "must specify the attribute_type" unless (attribute_type or attribute_type_column)
932
+ abort "must specify both a unit column and a unit label column" if (attribute_value_unit_column and !(attribute_value_unit_label_column))
933
+
934
+ @mappings << mapping_clause(
935
+ "attribute_#{attribute_tag}_annotation",
936
+ ["#{source_tag}-source"],
937
+ root_url + "#attribute_#{attribute_tag}",
938
+ [
939
+ ["rdf:type",SIO["attribute"][self.sio_verbose], "iri"],
940
+ ["rdf:type",attribute_type, "iri"],
941
+ ]
942
+ )
943
+
944
+ if attribute_value_column
945
+ @mappings << mapping_clause(
946
+ "attribute_#{attribute_tag}_measurement",
947
+ ["#{source_tag}-source"],
948
+ root_url + "#attribute_#{attribute_tag}",
949
+ [[SIO["has-measurement-value"][self.sio_verbose], root_url + "#measurement_of_attribute_#{attribute_tag}", "iri"]]
950
+ )
951
+
952
+
953
+ @mappings << mapping_clause(
954
+ "attribute_#{attribute_tag}_measurement_value",
955
+ ["#{source_tag}-source"],
956
+ root_url + "#measurement_of_attribute_#{attribute_tag}",
957
+ [[SIO["has-measurement-value"][self.sio_verbose], root_url + "#measurementvalue_of_attribute_#{attribute_tag}", "iri"]]
958
+ )
959
+ @mappings << mapping_clause(
960
+ "attribute_#{attribute_tag}_measurement_value_value",
961
+ ["#{source_tag}-source"],
962
+ root_url + "#measurementvalue_of_attribute_#{attribute_tag}",
963
+ [
964
+ [SIO["has-value"][self.sio_verbose], "$(#{attribute_value_column})", "xsd:string"],
965
+ ["rdf:type", SIO["information-content-entity"][self.sio_verbose], "iri"],
966
+ ]
967
+ )
968
+ end
969
+
970
+ if attribute_label
971
+ @mappings << mapping_clause(
972
+ "attribute_#{attribute_tag}_measurement_value_label",
973
+ ["#{source_tag}-source"],
974
+ root_url + "#measurementvalue_of_attribute_#{attribute_tag}",
975
+ [["rdfs:label", attribute_label]]
976
+ )
977
+ end
978
+
979
+ if attribute_value_unit_column
980
+ @mappings << mapping_clause(
981
+ "attribute_#{attribute_tag}_measurement_value_unit_node",
982
+ ["#{source_tag}-source"],
983
+ root_url + "#measurementvalue_of_attribute_#{attribute_tag}",
984
+ [
985
+ [SIO["has-unit"][self.sio_verbose], root_url + "#measurementvalue_unit_of_attribute_#{attribute_tag}", "iri"],
986
+ ]
987
+ )
988
+ @mappings << mapping_clause(
989
+ "attribute_#{attribute_tag}_measurement_value_unit_node_type",
990
+ ["#{source_tag}-source"],
991
+ root_url + "#measurementvalue_unit_of_attribute_#{attribute_tag}",
992
+ [
993
+ ["rdf:type", "#{attribute_value_unit_column}", "iri"],
994
+ ["rdfs:label", "#{attribute_value_unit_label_column}"],
995
+ ]
996
+ )
997
+ end
998
+
999
+
1000
+ end
1001
+
1002
+
1003
+
1004
+
1005
+ # creates the process has input portion of the CDE
1006
+ #
1007
+ # Parameters passed as a hash
1008
+ #
1009
+ # @param params [Hash] a hash of options
1010
+ # @option params :process_with_input_tag [String] (required) the same process tag that is used in the "role in process" for which this is the input
1011
+ # @option params :input_is_output_of_process_tag [String] defaults to 'unidentifiedProcess'; if the input is the output of another process, then specify the process tag here (matches the "role in process" which generates taht output
1012
+ # @option params :input_type [String] the ontological type for the input node (default http://semanticscience.org/resource/information-content-entity). Ignored if using output from another process (specify it there!)
1013
+ # @option params :input_type_tag [String] a tag to differentiate this input from other inputs
1014
+ # @option params :input_type_column [String] the column header specifying the ontological type for the input node (overrides input_type). Ignored if using output from another process (specify it there!)
1015
+ # @option params :input_type_label [String] the label for all inputs
1016
+ # @option params :input_type_label_column [String] the label column for each input
1017
+ # @option params :input_has_value [String] the value of the input
1018
+ # @option params :input_has_value_column [String] the column containing the value of the input
1019
+ # @option params :input_has_value_datatype [String] datatype of the value (default xsd:string)
1020
+ # @option params :input_has_value_datatype_column [String] the column containing the datatype of the value of the input )(overrides input_has_value_datatype)
1021
+ # @option params :make_unique_process [boolean] (true) (optional) if you want the core URI to be globally unique, or based only on the patient ID. this can be used to merge nodes over multiple runs of different yarrrml transforms.
1022
+
1023
+
1024
+ # NEED AN INPUT REFERS TO HERE>>>>>>
1025
+
1026
+ def process_has_input(params)
1027
+ process_with_input_tag = params.fetch(:process_with_input_tag, "thisprocess") # some one-word name
1028
+ input_is_output_of_process_tag = params.fetch(:input_is_output_of_process_tag, 'unidentifiedProcess') # some one-word name
1029
+ input_type = params.fetch(:input_type, SIO["information-content-entity"][self.sio_verbose]) # some one-word name
1030
+ input_type_tag = params.fetch(:input_type_tag, "thisInput") # some one-word name
1031
+ input_type_column = params.fetch(:input_type_column, nil) # some one-word name
1032
+ input_type_label = params.fetch(:input_type_label, "information content entity") # some one-word name
1033
+ input_type_label_column = params.fetch(:input_type_label_column, nil) # some one-word name
1034
+ input_has_value = params.fetch(:input_has_value, nil) # some one-word name
1035
+ input_has_value_column = params.fetch(:input_has_value_column, nil) # some one-word name
1036
+ input_has_value_datatype = params.fetch(:input_has_value_datatype, "xsd:string") # some one-word name
1037
+ input_has_value_datatype_column = params.fetch(:input_has_value_datatype_column, nil) # some one-word name
1038
+ make_unique_process = params.fetch(:make_unique_process, true)
1039
+
1040
+ root_url = get_root_url(make_unique_process)
1041
+
1042
+
1043
+ abort "must specify the process_with_input_tag (the identifier of the process that receives the input) before you can use the process_has_input function" unless process_with_input_tag
1044
+
1045
+ input_type = input_type_column ? "$(#{input_type_column})":input_type
1046
+ input_label = input_type_label_column ? "$(#{input_type_label_column})":input_type_label
1047
+ input_value = input_has_value_column ? "$(#{input_has_value_column})":input_has_value
1048
+ input_value_datatype = input_has_value_datatype_column ? "$(#{input_has_value_datatype_column})":input_has_value_datatype
1049
+
1050
+ @mappings << mapping_clause(
1051
+ "process_#{process_with_input_tag}_has_input_#{input_type_tag}",
1052
+ ["#{source_tag}-source"],
1053
+ root_url + "#process_#{process_with_input_tag}",
1054
+ [[SIO["has-input"][self.sio_verbose],"this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{input_is_output_of_process_tag}_Output", "iri"]]
1055
+ )
1056
+
1057
+ @mappings << mapping_clause(
1058
+ "process_#{process_with_input_tag}_has_input_#{input_type_tag}_annotation",
1059
+ ["#{source_tag}-source"],
1060
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{input_is_output_of_process_tag}_Output",
1061
+ [
1062
+ ["rdf:type",SIO["information-content-entity"][self.sio_verbose], "iri"],
1063
+ ["rdf:type","#{input_type}", "iri"],
1064
+ ["rdfs:label","Process Input: #{input_label} - Type: #{input_type_tag}", "xsd:string"],
1065
+ ]
1066
+ )
1067
+
1068
+
1069
+ if input_value
1070
+
1071
+ @mappings << mapping_clause(
1072
+ "input_#{input_type_tag}_has_value",
1073
+ ["#{source_tag}-source"],
1074
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{input_is_output_of_process_tag}_Output",
1075
+ [[SIO["has-value"][self.sio_verbose],"#{input_value}", "#{input_value_datatype}"]]
1076
+ )
1077
+ end
1078
+
1079
+ # TODO: need to allow units here too! ...one day...
1080
+ end
1081
+
1082
+
1083
+
1084
+
1085
+
1086
+
1087
+
1088
+ # creates the process_hasoutput_output portion of the CDE
1089
+ #
1090
+ # TODO allow multiple outputs
1091
+ #
1092
+ # Parameters passed as a hash
1093
+ #
1094
+ # @param params [Hash] a hash of options
1095
+ # @option params :process_with_output_tag [String] Required - the same process tag that is used in the "role in process" for which this is the output
1096
+ # @option params :output_value [String] the default value of that output (defaults to nil, and the output node is not created in the RDF)
1097
+ # @option params :output_value_column [String] the column header for the value of that output (e.g. the column that contains "80" for "80 mmHg")
1098
+ # @option params :output_type [String] the URL associated with the output ontological type (defaults to http://semanticscience.org/resource/realizable-entity)
1099
+ # @option params :output_type_column [String] the column header for the URL associated with the output ontological type (overrides output_type)
1100
+ # @option params :output_type_label [String] the the label of that ontological type (defaults to "measurement-value")
1101
+ # @option params :output_type_label_column [String] the column header for the label of that ontological type (overrides output_type_label)
1102
+ # @option params :output_value_datatype [xsd:type] the xsd:type for that kind of measurement (defaults to xsd:string)
1103
+ # @option params :output_value_datatype_column [String] the column header for the xsd:type for that kind of measurement (overrides output_value_datatype)
1104
+ # @option params :output_comments_column [String] the column header for amy textual comments. text must not contain a comma!! defaults to nil
1105
+ # @option params :output_start_column [xsd:date] the column header for start date, if the observation is time-constrained (e.g. symptoms from 2020-01-01 to 2020-01-05)
1106
+ # @option params :output_end_column [xsd:date] the column header for end date, if the observation is time-constrained (e.g. symptoms from symptoms from 2020-01-01 to 2020-01-05)
1107
+ # @option params :output_measured_at_column [xsd:date] the column header for a time-instant date of the observation
1108
+ # @option params :output_annotations [Array] Array of Arrays of [[predicate, valuecolumn, datatype]...] that will be applied as annotations to the output of the tagged process. predicate may be a full URI or a column reference; value MUST be a column-reference; datatype is options, default xsd:string
1109
+ # @option params :make_unique_process [boolean] (true) (optional) if you want the core URI to be globally unique, or based only on the patient ID. this can be used to merge nodes over multiple runs of different yarrrml transforms.
1110
+ def process_hasoutput_output(params)
1111
+ process_with_output_tag = params.fetch(:process_with_output_tag, "thisprocess") # some one-word name
1112
+ output_value = params.fetch(:output_value, nil)
1113
+ output_value_column = params.fetch(:output_value_column, nil)
1114
+ output_type = params.fetch(:output_type, SIO["information-content-entity"][self.sio_verbose])
1115
+ output_type_column = params.fetch(:output_type_column, nil)
1116
+ output_type_label = params.fetch(:output_type_label, "measurement-value")
1117
+ output_type_label_column = params.fetch(:output_type_label_column, nil)
1118
+ output_value_datatype = params.fetch(:output_value_datatype, "xsd:string")
1119
+ output_value_datatype_column = params.fetch(:output_value_datatype_column, nil)
1120
+ output_comments_column = params.fetch(:output_comments_column, nil)
1121
+ output_start_column = params.fetch(:output_start_column, nil)
1122
+ output_end_column = params.fetch(:output_end_column, nil)
1123
+ output_timeinstant_column = params.fetch(:output_timeinstant_column, nil)
1124
+ output_measured_at_column = params.fetch(:output_measured_at_column, nil)
1125
+ output_annotations = params.fetch(:output_annotations, [])
1126
+ #output_annotations_columns = params.fetch(:output_annotations_columns, [])
1127
+ make_unique_process = params.fetch(:make_unique_process, true)
1128
+
1129
+ output_value = output_value_column ? "$(#{output_value_column})":output_value
1130
+ output_type = output_type_column ? "$(#{output_type_column})":output_type
1131
+ output_type_label = output_type_label_column ? "$(#{output_type_label_column})":output_type_label
1132
+ output_value_datatype = output_value_datatype_column ? "$(#{output_value_datatype_column})":output_value_datatype
1133
+
1134
+
1135
+ root_url = get_root_url(make_unique_process)
1136
+
1137
+ #return unless output_value
1138
+
1139
+ @mappings << mapping_clause(
1140
+ "process_#{process_with_output_tag}_process_has_output",
1141
+ ["#{source_tag}-source"],
1142
+ root_url + "#process_#{process_with_output_tag}",
1143
+ [[SIO["has-output"][self.sio_verbose], "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output", "iri"]]
1144
+ )
1145
+ @mappings << mapping_clause(
1146
+ "process_#{process_with_output_tag}_Output_annotation",
1147
+ ["#{source_tag}-source"],
1148
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output",
1149
+ [["rdf:type",SIO["information-content-entity"][self.sio_verbose], "iri"]]
1150
+ )
1151
+
1152
+ if output_type
1153
+ @mappings << mapping_clause(
1154
+ "process_#{process_with_output_tag}_Output_type_annotation",
1155
+ ["#{source_tag}-source"],
1156
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output",
1157
+ [["rdf:type",output_type, "iri"]]
1158
+ )
1159
+ end
1160
+
1161
+ if output_type_label
1162
+ @mappings << mapping_clause(
1163
+ "process_#{process_with_output_tag}_Output_type_label_annotation",
1164
+ ["#{source_tag}-source"],
1165
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output",
1166
+ [["rdfs:label","Output Type: #{output_type_label}", "xsd:string"]]
1167
+ )
1168
+ end
1169
+
1170
+ if output_value
1171
+ @mappings << mapping_clause(
1172
+ "process_#{process_with_output_tag}_Output_value_annotation",
1173
+ ["#{source_tag}-source"],
1174
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output",
1175
+ [[SIO["has-value"][self.sio_verbose],output_value, output_value_datatype]]
1176
+ )
1177
+ end
1178
+
1179
+ if output_comments_column
1180
+ @mappings << mapping_clause(
1181
+ "process_#{process_with_output_tag}_Output_value_comments",
1182
+ ["#{source_tag}-source"],
1183
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output",
1184
+ [["rdfs:comment","$(#{output_comments_column})", "xsd:string"]]
1185
+ )
1186
+ end
1187
+
1188
+
1189
+ if output_measured_at_column
1190
+
1191
+ @mappings << mapping_clause(
1192
+ "process_#{process_with_output_tag}_output_measured_at_timeinstant",
1193
+ ["#{source_tag}-source"],
1194
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output",
1195
+ [
1196
+ [SIO["measured-at"][self.sio_verbose], "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output_measured_at", "iri"],
1197
+ ]
1198
+ )
1199
+ @mappings << mapping_clause(
1200
+ "process_#{process_with_output_tag}_output_measured_at_timeinstant_value",
1201
+ ["#{source_tag}-source"],
1202
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output_measured_at",
1203
+ [
1204
+ [SIO["has-value"][self.sio_verbose], "$(#{output_timeinstant_column})", "xsd:date"],
1205
+ ["rdf:type", SIO["time-instant"][self.sio_verbose], "iri"],
1206
+ ]
1207
+ )
1208
+ end
1209
+
1210
+
1211
+ if output_start_column # start and end will be attributes of the information object
1212
+
1213
+ @mappings << mapping_clause(
1214
+ "process_#{process_with_output_tag}_output_has_start_atribute",
1215
+ ["#{source_tag}-source"],
1216
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output",
1217
+ [
1218
+ # need to add the start column into this URI so that, if it is empty, the attribute will not be created at all by SDMRDFizer
1219
+ [SIO["has-attribute"][self.sio_verbose], "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output_start_attribute_$(#{output_start_column})", "iri"],
1220
+ ]
1221
+ )
1222
+ @mappings << mapping_clause(
1223
+ "process_#{process_with_output_tag}_output_has_start_attribute_value",
1224
+ ["#{source_tag}-source"],
1225
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output_start_attribute_$(#{output_start_column})",
1226
+ [
1227
+ [SIO["has-value"][self.sio_verbose], "$(#{output_start_column})", "xsd:date"],
1228
+ ["rdf:type", SIO["start-date"][self.sio_verbose], "iri"],
1229
+ ]
1230
+ )
1231
+ end
1232
+
1233
+
1234
+ if output_end_column # start and end will be attributes of the information object
1235
+
1236
+ @mappings << mapping_clause(
1237
+ "process_#{process_with_output_tag}_output_has_end_atribute",
1238
+ ["#{source_tag}-source"],
1239
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output",
1240
+ [
1241
+ # need to add the start column into this URI so that, if it is empty, the attribute will not be created at all by SDMRDFizer
1242
+ [SIO["has-attribute"][self.sio_verbose], "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output_end_attribute_$(#{output_end_column})", "iri"],
1243
+ ]
1244
+ )
1245
+ @mappings << mapping_clause(
1246
+ "process_#{process_with_output_tag}_output_has_end_attribute_value",
1247
+ ["#{source_tag}-source"],
1248
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output_end_attribute_$(#{output_end_column})",
1249
+ [
1250
+ [SIO["has-value"][self.sio_verbose], "$(#{output_end_column})", "xsd:date"],
1251
+ ["rdf:type", SIO["end-date"][self.sio_verbose], "iri"],
1252
+ ]
1253
+ )
1254
+ end
1255
+
1256
+ output_annotations.each do |pred, value, dtype|
1257
+ datatype = "xsd:string"
1258
+ predicate = ""
1259
+ if dtype and dtype =~ /\S+\:\S+/ # URI or qname
1260
+ datatype = dtype
1261
+ elsif dtype
1262
+ datatype = "$(#{datatype})" # make it the column reference if it exists, but isn't a uri
1263
+ end
1264
+
1265
+ if pred and pred =~ /\S+\:\S+/ # URI or qname
1266
+ predicate = pred
1267
+ else
1268
+ predicate = "$(#{pred})" # make it the column reference if it exists, but isn't a uri
1269
+ end
1270
+
1271
+ next unless predicate and value
1272
+ uniqid = get_uniq_id
1273
+
1274
+ @mappings << mapping_clause(
1275
+ "#{uniqid}_output_custom_annotation",
1276
+ ["#{source_tag}-source"],
1277
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_with_output_tag}_Output",
1278
+ [["$(#{predicate})", "$(#{value})", datatype]]
1279
+ )
1280
+
1281
+ end
1282
+
1283
+ end
1284
+
1285
+
1286
+ # creates the input output refers to portion of the CDE
1287
+ #
1288
+ # Parameters passed as a hash
1289
+ #
1290
+ #@param params [Hash] a hash of options
1291
+ #@option params :inout_process_tag [String] ("unidentifiedProcess")
1292
+ #@option params :refers_to_tag [String] (nil) required unique one-word tag of an attribute
1293
+ #@option params :inout_refers_to [String] ([]) an ontology URI
1294
+ #@option params :inout_refers_to_column [String] ([]) column headers for column of ontologyURIs
1295
+ #@option params :inout_refers_to_label [String] ([]) an ontology term label
1296
+ #@option params :inout_refers_to_label_column [String] ([]) column header for column of ontology term labels
1297
+ #@option params :inout_refers_to_uri_column [String] ([]) column header for column containing the URIs of the in/out node (e.g. a specific clinical variant identifier)
1298
+ #@option params :is_attribute [Boolean] (true) is this output an attribute of a patient/entity?
1299
+ #@option params :entity_tag [String] (required) then you must tag the entity or person, defaults to "thisPerson"
1300
+ #@option params :base_types [Array] ([]) an array of ontology terms that will be applied as the rdf:type for all the referred-to quality/attribute
1301
+
1302
+ def input_output_refers_to(params)
1303
+ entityid_column = params.fetch(:entityid_column, 'pid')
1304
+ inout_process_tag = params.fetch(:inout_process_tag, 'unidentifiedProcess')
1305
+ refers_to_tag = params.fetch(:refers_to_tag, nil)
1306
+ inout_refers_to = params.fetch(:inout_refers_to, nil)
1307
+ inout_refers_to_label = params.fetch(:inout_refers_to_label, nil)
1308
+ inout_refers_to_column = params.fetch(:inout_refers_to_column, nil)
1309
+ inout_refers_to_label_column = params.fetch(:inout_refers_to_label_column, nil )
1310
+ inout_refers_to_uri_column = params.fetch(:inout_refers_to_uri_column, nil )
1311
+ is_attribute = params.fetch(:is_attribute, true )
1312
+ entity_tag = params.fetch(:entity_tag, "thisPerson" )
1313
+ base_types = params.fetch(:base_types, [] )
1314
+
1315
+ refers_to = inout_refers_to_column ? "$(#{inout_refers_to_column})":inout_refers_to
1316
+ refers_to_label = inout_refers_to_label_column ? "$(#{inout_refers_to_label_column})":inout_refers_to_label
1317
+
1318
+ abort "must specify in_out_process_tag" unless inout_process_tag
1319
+ abort "must specify refers_to_tag" unless refers_to_tag
1320
+ abort "must have an entity tag" unless entity_tag
1321
+ #$stderr.puts "is an attribute #{is_attribute}"
1322
+
1323
+ attribute_node_uri = inout_refers_to_uri_column ? "$(#{inout_refers_to_uri_column})":"this:individual_#{entity_tag}_$(#{entityid_column})_$(#{@uniqueid_column})##{refers_to_tag}_TypedAttributeNode"
1324
+
1325
+ types = []
1326
+ types << ["rdf:type", SIO["attribute"][self.sio_verbose], "iri"] if is_attribute # add base type if its an attribute
1327
+ types << ["rdf:type", refers_to, "iri"]
1328
+ base_types.each do |b|
1329
+ types << ["rdf:type", b, "iri"]
1330
+ end
1331
+
1332
+ @mappings << mapping_clause(
1333
+ "inout_from_process_#{inout_process_tag}_refers_to_concepts",
1334
+ ["#{source_tag}-source"],
1335
+ "this:individual_#{entity_tag}_$(#{entityid_column})_$(#{@uniqueid_column})#process_#{inout_process_tag}_Output",
1336
+ [
1337
+ [SIO["refers-to"][self.sio_verbose], attribute_node_uri, "iri"]
1338
+ ]
1339
+ )
1340
+
1341
+ if is_attribute
1342
+ @mappings << mapping_clause(
1343
+ "has_attribute_of_inout_from_process_#{inout_process_tag}",
1344
+ ["#{source_tag}-source"],
1345
+ "this:individual_#{entity_tag}_$(#{entityid_column})#Entity",
1346
+ [
1347
+ [SIO["has-attribute"][self.sio_verbose], attribute_node_uri, "iri"]
1348
+ ]
1349
+ )
1350
+ end
1351
+
1352
+ @mappings << mapping_clause(
1353
+ "inout_from_process_#{inout_process_tag}_refers_to_concept_#{refers_to_tag}_type",
1354
+ ["#{source_tag}-source"],
1355
+ attribute_node_uri,
1356
+
1357
+ types
1358
+
1359
+ )
1360
+
1361
+
1362
+ if refers_to_label
1363
+ @mappings << mapping_clause(
1364
+ "inout_from_process_#{inout_process_tag}_refers_to_concept_#{refers_to_tag}_label",
1365
+ ["#{source_tag}-source"],
1366
+ attribute_node_uri,
1367
+ [
1368
+ ["rdfs:label", "Attribute Type: #{refers_to_label}" ]
1369
+ ]
1370
+ )
1371
+ end
1372
+
1373
+
1374
+ end
1375
+
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+ # creates the output_has_unit portion of the CDE
1383
+ #
1384
+ # Parameters passed as a hash
1385
+ # @option params :inout_process_tag [String] ("unidentifiedProcess")
1386
+ # @option params :output_unit [URL] the ontological type of that unit (default nil)
1387
+ # @option params :output_unit_column [String]column containing the ontological type of that unit (overrides output_unit)
1388
+ # @option params :output_unit_label [string] the string label for that unit (e.g. "centimeters" for the ontological type "cm" ) (default nil)
1389
+ # @option params :output_unit_label_column [string] column header containing the string label for that unit (e.g. "centimeters" for the ontological type "cm" )
1390
+
1391
+ def output_has_unit(params)
1392
+ process_tag = params.fetch(:inout_process_tag, 'unidentifiedProcess')
1393
+
1394
+ output_unit = params.fetch(:output_unit, nil) # URI
1395
+ output_unit_column = params.fetch(:output_unit_column, nil) # URI
1396
+ output_unit_label = params.fetch(:output_unit_label, nil)
1397
+ output_unit_label_column = params.fetch(:output_unit_label_column, nil)
1398
+
1399
+ output_unit = output_unit_column ? "$(#{output_unit_column})":output_unit
1400
+ output_unit_label = output_unit_label_column ? "$(#{output_unit_label_column})":output_unit_label
1401
+
1402
+ if output_unit
1403
+ @mappings << mapping_clause(
1404
+ "process_#{process_tag}_Output_hasunit_unit",
1405
+ ["#{source_tag}-source"],
1406
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_tag}_Output",
1407
+ [[SIO["has-unit"][self.sio_verbose], "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_tag}_Output_unit", "iri"]]
1408
+ )
1409
+
1410
+ @mappings << mapping_clause(
1411
+ "process_#{process_tag}_Output_unit_annotation",
1412
+ ["#{source_tag}-source"],
1413
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_tag}_Output_unit",
1414
+ [["rdf:type",output_unit, "iri"]]
1415
+ )
1416
+
1417
+ end
1418
+
1419
+ if output_unit and output_unit_label
1420
+
1421
+ @mappings << mapping_clause(
1422
+ "process_#{process_tag}_Output_unit_label_annotation",
1423
+ ["#{source_tag}-source"],
1424
+ "this:individual_$(#{@personid_column})_$(#{@uniqueid_column})#process_#{process_tag}_Output_unit",
1425
+ [["rdfs:label",output_unit_label,"xsd:string"]
1426
+ ]
1427
+ )
1428
+ end
1429
+
1430
+
1431
+ end
1432
+
1433
+
1434
+
1435
+ # creates the entity has component entity portion of the CDE
1436
+ #
1437
+ # Parameters passed as a hash
1438
+ #
1439
+ # @param params [Hash] a hash of options
1440
+ # @option params :parent_entityid_column [String] (required) the column that contains the parent entity id
1441
+ # @option params :parent_entity_tag [String] (required) default "thisPerson" the tag of the parent entity
1442
+ # @option params :part_entity_tag [String] (required) the tag of the part entity
1443
+ # @option params :part_type_column [String] (required) the column that contains the parent entity id
1444
+ # TODO make it possible to explicitly compose entities from other modelled entities (part entity id column)
1445
+ def entity_has_component(params)
1446
+ parent_entityid_column = params.fetch(:parent_entityid_column, 'pid')
1447
+ parent_entity_tag = params.fetch(:part_entity_tag, "thisPerson")
1448
+ part_entity_tag = params.fetch(:part_entity_tag, nil)
1449
+ part_type = params.fetch(:part_type, nil)
1450
+ part_type_column = params.fetch(:part_type_column, nil)
1451
+
1452
+ part_type = part_type_column ? "$(#{part_type_column})":part_type
1453
+
1454
+ abort "cannot create entity has component without both a part type and part tag" unless (part_type && part_entity_tag)
1455
+
1456
+ #uniqid = get_uniq_id
1457
+
1458
+ @mappings << mapping_clause(
1459
+ "parent_entity_has_part_#{part_entity_tag}",
1460
+ ["#{source_tag}-source"],
1461
+ "this:individual_#{parent_entity_tag}_$(#{parent_entityid_column})#Entity",
1462
+ [[SIO["has-component-part"][self.sio_verbose], "this:individual_#{part_entity_tag}#componentEntity" , "iri"]]
1463
+ )
1464
+
1465
+ @mappings << mapping_clause(
1466
+ "parent_entity_has_part_#{part_entity_tag}",
1467
+ ["#{source_tag}-source"],
1468
+ "this:individual_#{part_entity_tag}#componentEntity",
1469
+ [['rdf:type', part_type , "iri"]]
1470
+ )
1471
+
1472
+ end
1473
+
1474
+
1475
+
1476
+ # creates a time-based locally-unique identifier
1477
+
1478
+ def get_uniq_id
1479
+ return Time.now.to_f.to_s.gsub("\.", "")
1480
+
1481
+ end
1482
+ end
1483
+
1484
+
1485
+