def testCreatesCompositionInGraphSomeRestriction(self): # Prepare data # Build First Graph with the method graph = rdflib.Graph() # Bind the OWL and Digital Buildings name spaces namespace_manager = namespace.NamespaceManager(rdflib.Graph()) namespace_manager.bind('owl', rdflib.OWL) namespace_manager.bind('db', constants.DIGITAL_BUILDINGS_NS) graph.namespace_manager = namespace_manager list_standard_field_name = [ 'cooling_air_flowrate_sensor_1', 'run_command' ] uses_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS['uses'], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) class_owl = infixowl.Class( identifier=constants.DIGITAL_BUILDINGS_NS['DFSS'], graph=graph) graph = rdf_helper.CreateCompositionInGraph( composition_operator='|', list_standard_field_names=list_standard_field_name, restriction=infixowl.some, composition_property=uses_property, class_owl=class_owl, graph=graph) # Build a second graph that is expected expected_graph = rdflib.Graph() # Bind the OWL and Digital Buildings name spaces namespace_manager_expected = namespace.NamespaceManager(rdflib.Graph()) namespace_manager_expected.bind('owl', rdflib.OWL) namespace_manager_expected.bind('db', constants.DIGITAL_BUILDINGS_NS) expected_graph.namespace_manager = namespace_manager_expected class_owl_expected = infixowl.Class( identifier=constants.DIGITAL_BUILDINGS_NS['DFSS'], graph=expected_graph) sfn1_expected = infixowl.Class( identifier=constants. DIGITAL_BUILDINGS_NS['Cooling_air_flowrate_sensor_1'], graph=expected_graph) sfn2_expected = infixowl.Class( identifier=constants.DIGITAL_BUILDINGS_NS['Run_command'], graph=expected_graph) uses_property_expected = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS['uses'], baseType=infixowl.OWL_NS.ObjectProperty, graph=expected_graph) concat = sfn1_expected | sfn2_expected class_owl_expected.subClassOf = [ uses_property_expected | infixowl.some | concat ] # Check if they are similar self.assertTrue(compare.similar(graph, expected_graph))
def create_ontology(identifier): ontology_uri = d1[identifier] o_ns = Namespace(ontology_uri+"#") r = requests.get(ontology_uri) xml = r.text.encode('utf-8') eml = ET.fromstring(xml) g = Graph() g.bind("rdfs", RDFS) g.bind("owl", OWL) ontology = infixowl.Ontology(ontology_uri, graph=g) datasetTitle = eml.find('dataset/title') if datasetTitle is not None: ontology.label = Literal(datasetTitle.text.strip()) ontology.comment = Literal('\n'.join([x.text for x in eml.findall('dataset/abstract/para') if x is not None and x.text is not None]).strip()) # Data Table: i = 0 for datatable in eml.findall("dataset/dataTable"): i += 1 entity_ident = str(i) entity = infixowl.Class(o_ns['_'.join(['d',entity_ident])],graph=g) entity.subClassOf = [oboe.Entity] entityLabel = [] for e in ['entityName','entityDescription']: if datatable.find(e) is not None and datatable.find(e).text is not None: entityLabel.append(datatable.find(e).text.strip()) entity.label = Literal(' '.join(entityLabel)) if datatable.find('entityDescription') is not None and datatable.find('entityDescription').text is not None: entity.comment = Literal(datatable.find('entityDescription').text.strip()) j = 0 for attribute in datatable.findall('attributeList/attribute'): j +=1 attribute_ident = str(j) characteristic = infixowl.Class(o_ns['_'.join(['d',entity_ident,'c',attribute_ident])],graph=g) characteristic.subClassOf = [oboe.Characteristic] label = [] for e in ['.//attributeName','.//attributeLabel','.//attributeDefinition']: if attribute.find(e) is not None and attribute.find(e).text is not None: label.append(attribute.find(e).text.strip()) characteristic.label = Literal(' '.join(label)) if attribute.find('.//attributeDefinition') is not None and attribute.find('.//attributeDefinition').text is not None: characteristic.comment = Literal(datatable.find('.//attributeDefinition').text.strip()) measurement_type = infixowl.Class(o_ns['_'.join(['d',entity_ident,'a',attribute_ident])],graph=g) g.add((measurement_type.identifier, urn.entityId, Literal(entity_ident))) g.add((measurement_type.identifier, urn.attributeId, Literal(attribute_ident))) measurement_type.label = Literal(g.value(entity.identifier,RDFS.label, default="") + " " + g.value(characteristic.identifier,RDFS.label, default="")) measurement_type.comment = Literal(g.value(entity.identifier,RDFS.comment, default="") + " " + g.value(characteristic.identifier,RDFS.comment, default="")) measurement_type.subClassOf = [ oboe.MeasurementType, infixowl.Restriction(oboe.measuresEntity, graph=g, someValuesFrom=entity), infixowl.Restriction(oboe.measuresCharacteristic, graph=g, someValuesFrom=characteristic) ] return g
def add_phenotypes(graph): cell_phenotype = 'ilx:CellPhenotype' neuron_phenotype = 'ilx:NeuronPhenotype' #ephys_phenotype = 'ilx:ElectrophysiologicalPhenotype' #spiking_phenotype = 'ilx:SpikingPhenotype' #i_spiking_phenotype = 'ilx:PetillaInitialSpikingPhenotype' burst_p = 'ilx:PetillaInitialBurstSpikingPhenotype' classical_p = 'ilx:PetillaInitialClassicalSpikingPhenotype' delayed_p = 'ilx:PetillaInitialDelayedSpikingPhenotype' #s_spiking_phenotype = 'ilx:PetillaSustainedSpikingPhenotype' #morpho_phenotype = 'ilx:MorphologicalPhenotype' ac_p = 'ilx:PetillaSustainedAccomodatingPhenotype' nac_p = 'ilx:PetillaSustainedNonAccomodatingPhenotype' st_p = 'ilx:PetillaSustainedStutteringPhenotype' ir_p = 'ilx:PetillaSustainedIrregularPhenotype' #fast = 'ilx:FastSpikingPhenotype' #reg_int = 'ilx:RegularSpikingNonPyramidalPhenotype' graph.add_class(cell_phenotype, autogen=True) graph.add_class(neuron_phenotype, cell_phenotype, autogen=True) graph.add_class(ephys_phenotype, neuron_phenotype, autogen=True) graph.add_class(spiking_phenotype, ephys_phenotype, autogen=True) graph.add_class(fast_phenotype, spiking_phenotype, ('Fast spiking'), autogen=True) graph.add_class(reg_phenotype, spiking_phenotype, ('Non-fast spiking', 'Regular spiking non-pyramidal'), autogen=True) graph.add_class(i_spiking_phenotype, spiking_phenotype, autogen=True) iClass = infixowl.Class(graph.expand(i_spiking_phenotype), graph=graph.g) graph.add_class(burst_p, i_spiking_phenotype, ('burst', ), autogen=True) graph.add_class(classical_p, i_spiking_phenotype, ('classical', ), autogen=True) graph.add_class(delayed_p, i_spiking_phenotype, ('delayed', ), autogen=True) graph.add_class(s_spiking_phenotype, spiking_phenotype, autogen=True) sClass = infixowl.Class(graph.expand(s_spiking_phenotype), graph=graph.g) sClass.disjointWith = [iClass] graph.add_class(ac_p, s_spiking_phenotype, ('accomodating', ), autogen=True) # FIXME this is silly graph.add_class(nac_p, s_spiking_phenotype, ('non accomodating', ), autogen=True) graph.add_class(st_p, s_spiking_phenotype, ('stuttering', ), autogen=True) graph.add_class(ir_p, s_spiking_phenotype, ('irregular', ), autogen=True) graph.add_class(morpho_phenotype, neuron_phenotype, autogen=True)
def create_ontology(identifier): ontology_uri = d1[identifier] o_ns = Namespace(ontology_uri + "#") r = requests.get(ontology_uri) xml = r.text.encode('utf-8') eml = ET.fromstring(xml) g = Graph() g.bind("rdfs", RDFS) g.bind("owl", OWL) ontology = infixowl.Ontology(ontology_uri, graph=g) ontology.label = Literal(eml.find('dataset/title').text.strip()) ontology.comment = Literal('\n'.join( [x.text for x in eml.find('dataset/abstract/para')]).strip()) # Data Table: for datatable in eml.findall("dataset/dataTable"): entity_ident = datatable.attrib['id'] entity = infixowl.Class(o_ns[entity_ident], graph=g) entity.subClassOf = [oboe.Entity] entity.label = Literal(datatable.find('entityName').text.strip()) entity.comment = Literal( datatable.find('entityDescription').text.strip()) for attribute in datatable.findall('attributeList/attribute'): attribute_ident = attribute.attrib['id'] characteristic = infixowl.Class(o_ns[attribute_ident], graph=g) characteristic.subClassOf = [oboe.Characteristic] characteristic.label = Literal( datatable.find('.//attributeLabel').text.strip()) characteristic.comment = Literal( datatable.find('.//attributeDefinition').text.strip()) measurement_type = infixowl.Class(o_ns[entity_ident + "_" + attribute_ident], graph=g) measurement_type.label = Literal( g.label(entity.identifier) + " " + g.label(characteristic.identifier)) measurement_type.subClassOf = [ oboe.MeasurementType, infixowl.Restriction(oboe.measuresEntity, graph=g, someValuesFrom=entity), infixowl.Restriction(oboe.measuresCharacteristic, graph=g, someValuesFrom=characteristic) ] return g
def CreatesStandardFieldNameCompositionInGraph(list_composition, standard_field_name, is_composed_of_property, graph): """Utility function takes a standard_field_name from the ontology and returns its composition constraint. Args: list_composition: a list of composition of standard field name defined by Carson. Example: ['Run', 'Command'] standard_field_name: an ontology standard field name from Carson. Example: run_command is_composed_of_property: the property used to compose the standard field names, such as 'is_composed_of' graph: the global graph, example input run_command -> the returned result - is_composed_of_property only (Run and Command). - run_command subClassOf Command - Command subClassOf Point_type Returns: graph: updated graph with the composition. """ class_owl = infixowl.Class( identifier=constants.FIELDS_NS[standard_field_name.capitalize()], graph=graph) graph = CreateCompositionInGraph( list_standard_field_names=list_composition, composition_operator="&", composition_property=is_composed_of_property, restriction=infixowl.only, class_owl=class_owl, graph=graph, entity_namespace=constants.SUBFIELDS_NS) return graph
def _graphify(self): class_ = infixowl.Class(self.id_, graph=self.out_graph) class_.delete( ) # delete any existing annotations to prevent duplication for pe in self.pes: target = pe._graphify() # restriction or intersection if isinstance(pe, NegPhenotype): class_.disjointWith = [target] else: class_.subClassOf = [target] return class_
def __init__(self, phenotype, ObjectProperty=None, label=None): # label blackholes # TODO implement local names here? or at a layer above? (above) super().__init__() if isinstance(phenotype, Phenotype): # simplifies negation of a phenotype ObjectProperty = phenotype.e phenotype = phenotype.p self.p = self.checkPhenotype(phenotype) if ObjectProperty is None: self.e = self.getObjectProperty(self.p) else: self.e = self.checkObjectProperty( ObjectProperty) # FIXME this doesn't seem to work self._pClass = infixowl.Class(self.p, graph=self.in_graph) self._eClass = infixowl.Class(self.e, graph=self.in_graph) # do not call graphify here because phenotype edges may be reused in multiple places in the graph # use this specify consistent patterns for modifying labels self.labelPostRule = lambda l: l
def add_hierarchy(self, parent, edge, child): """ Helper function to simplify the addition of part_of style objectProperties to graphs. FIXME make a method of makeGraph? """ if type(parent) != rdflib.URIRef: parent = self.check_thing(parent) if type(edge) != rdflib.URIRef: edge = self.check_thing(edge) if type(child) != infixowl.Class: if type(child) != rdflib.URIRef: child = self.check_thing(child) child = infixowl.Class(child, graph=self.g) restriction = infixowl.Restriction(edge, graph=self.g, someValuesFrom=parent) child.subClassOf = [restriction] + [c for c in child.subClassOf]
def _graphify(self, *args, graph=None): # defined """ Lift phenotypeEdges to Restrictions """ if graph is None: graph = self.out_graph members = [self.expand(NIFCELL_NEURON)] for pe in self.pes: target = pe._graphify(graph=graph) if isinstance(pe, NegPhenotype ): # isinstance will match NegPhenotype -> Phenotype #self.Class.disjointWith = [target] # FIXME for defined neurons this is what we need and I think it is strong than the complementOf version djc = infixowl.Class( graph=graph ) # TODO for generic neurons this is what we need djc.complementOf = target members.append(djc) else: members.append(target) # FIXME negative logical phenotypes :/ intersection = infixowl.BooleanClass(members=members, graph=graph) # FIXME dupes ec = [intersection] self.Class.equivalentClass = ec return self.Class
def make_defined(graph, ilx_start, label, phenotype_id, restriction_edge, parent=None): ilx_start += 1 id_ = ilx_base.format(ilx_start) id_ = graph.expand(id_) restriction = infixowl.Restriction(graph.expand(restriction_edge), graph=graph.g, someValuesFrom=phenotype_id) defined = infixowl.Class(id_, graph=graph.g) defined.label = rdflib.Literal(label + ' neuron') intersection = infixowl.BooleanClass(members=(graph.expand(NIFCELL_NEURON), restriction), graph=graph.g) #intersection = infixowl.BooleanClass(members=(restriction,), graph=self.graph.g) defined.equivalentClass = [intersection] if parent is not None: defined.subClassOf = [graph.expand(parent)] return ilx_start
def clean_hbp_cell(): #old graph g = rdflib.Graph() if __name__ == '__main__': embed() path = Path(devconfig.git_local_base, 'methodsOntology/ttl/hbp_cell_ontology.ttl') if not path.exists(): raise devconfig.MissingRepoError(f'repo for {path} does not exist') g.parse(path.as_posix(), format='turtle') g.remove((None, rdflib.OWL.imports, None)) g.remove((None, rdflib.RDF.type, rdflib.OWL.Ontology)) #new graph NAME = 'NIF-Neuron-HBP-cell-import' mg = makeGraph(NAME, prefixes=PREFIXES) ontid = 'http://ontology.neuinfo.org/NIF/ttl/generated/' + NAME + '.ttl' mg.add_trip(ontid, rdflib.RDF.type, rdflib.OWL.Ontology) mg.add_trip(ontid, rdflib.RDFS.label, 'NIF Neuron HBP cell import') mg.add_trip(ontid, rdflib.RDFS.comment, 'this file was automatically using pyontutils/hbp_cells.py') mg.add_trip(ontid, rdflib.OWL.versionInfo, date.isoformat(date.today())) newgraph = mg.g skip = { '0000000':'SAO:1813327414', # cell #'0000001':NEURON, # neuron (equiv) #'0000002':'SAO:313023570', # glia (equiv) #'0000021':'NLXNEURNT:090804', # glut (equiv, but phen) #'0000022':'NLXNEURNT:090803', # gaba (equiv, but phen) '0000003':NEURON, '0000004':NEURON, '0000005':NEURON, '0000006':NEURON, '0000007':NEURON, '0000008':NEURON, '0000009':NEURON, '0000010':NEURON, '0000019':NEURON, '0000020':NEURON, '0000033':NEURON, '0000034':NEURON, '0000070':NEURON, '0000071':NEURON, } to_phenotype = { '0000021':('ilx:hasExpressionPhenotype', 'SAO:1744435799'), # glut, all classes that might be here are equived out '0000022':('ilx:hasExperssionPhenotype', 'SAO:229636300'), # gaba } lookup = {'NIFCELL', 'NIFNEURNT'} missing_supers = { 'HBP_CELL:0000136', 'HBP_CELL:0000137', 'HBP_CELL:0000140', } replace = set() phen = set() equiv = {} for triple in sorted(g.triples((None, None, None))): id_suffix = newgraph.namespace_manager.compute_qname(triple[0].toPython())[2] try: obj_suffix = newgraph.namespace_manager.compute_qname(triple[2].toPython())[2] except: # it wasn't a url pass # equiv insert for help if triple[1] == rdflib.OWL.equivalentClass and id_suffix not in skip and id_suffix not in to_phenotype: qnt = newgraph.namespace_manager.compute_qname(triple[2].toPython()) #print(qnt) if qnt[0] in lookup: try: lab = v.findById(qnt[0] + ':' + qnt[2])['labels'][0] print('REMOTE', qnt[0] + ':' + qnt[2], lab) #mg.add_trip(triple[2], rdflib.RDFS.label, lab) #mg.add_trip(triple[0], PREFIXES['NIFRID'] + 'synonym', lab) # so we can see it except TypeError: if qnt[2].startswith('nlx'): triple = (triple[0], triple[1], expand('NIFSTD:' + qnt[2])) #print('bad identifier') #check for equiv if triple[0] not in equiv: eq = [o for o in g.objects(triple[0], rdflib.OWL.equivalentClass)] if eq and id_suffix not in skip and id_suffix not in to_phenotype: if len(eq) > 1: print(eq) equiv[triple[0]] = eq[0] continue elif triple[0] in equiv: continue # edge replace if triple[1].toPython() == 'http://www.FIXME.org/nsupper#synonym': edge = mg.expand('NIFRID:abbrev') elif triple[1].toPython() == 'http://www.FIXME.org/nsupper#definition': edge = rdflib.namespace.SKOS.definition else: edge = triple[1] # skip or to phenotype or equiv if id_suffix in skip: # have to make a manual edit to rdflib to include 'Nd' in allowed 1st chars replace.add(triple[0]) #print('MEEP MEEP') elif id_suffix in to_phenotype: # have to make a manual edit to rdflib to include 'Nd' in allowed 1st chars phen.add(triple[0]) elif triple[1] == rdflib.RDFS.label: # fix labels if not triple[2].startswith('Hippocampus'): new_label = rdflib.Literal('Neocortex ' + triple[2], lang='en') newgraph.add((triple[0], edge, new_label)) else: newgraph.add((triple[0], edge, triple[2])) elif triple[2] in replace: mg.add_trip(triple[0], edge, skip[obj_suffix]) elif triple[2] in phen: edge_, rst_on = to_phenotype[obj_suffix] edge_ = expand(edge_) rst_on = expand(rst_on) this = triple[0] this = infixowl.Class(this, graph=newgraph) this.subClassOf = [expand(NEURON)] + [c for c in this.subClassOf] restriction = infixowl.Restriction(edge_, graph=newgraph, someValuesFrom=rst_on) this.subClassOf = [restriction] + [c for c in this.subClassOf] elif triple[2] in equiv: newgraph.add((triple[0], edge, equiv[triple[2]])) else: newgraph.add((triple[0], edge, triple[2])) # final cleanup for forward references (since we iterate through sorted) tt = rdflib.URIRef(expand('HBP_CELL:0000033')) tf = rdflib.URIRef(expand('HBP_CELL:0000034')) newgraph.remove((None, None, tt)) newgraph.remove((None, None, tf)) # add missing subClasses for nosub in missing_supers: mg.add_trip(nosub, rdflib.RDFS.subClassOf, NEURON) # cleanup for subClassOf for subject in sorted(newgraph.subjects(rdflib.RDFS.subClassOf, expand(NEURON))): sco = [a for a in newgraph.triples((subject, rdflib.RDFS.subClassOf, None))] #print('U WOT M8') if len(sco) > 1: #print('#############\n', sco) for s, p, o in sco: if 'hbp_cell_ontology' in o or 'NIF-Cell' in o and o != expand(NEURON): #or 'sao2128417084' in o: # neocortex pyramidal cell #print(sco) newgraph.remove((subject, rdflib.RDFS.subClassOf, expand(NEURON))) break # do ilx ilx_start = ilx_get_start() #ilx_conv_mem = memoize('hbp_cell_interlex.json')(ilx_conv) # FIXME NOPE, also need to modify the graph :/ ilx_labels, ilx_replace = ilx_conv(graph=newgraph, prefix='HBP_CELL', ilx_start=ilx_start) ilx_add_ids(ilx_labels) replace_map = ilx_replace for hbp, rep in skip.items(): ori = 'HBP_CELL:'+hbp if ori in replace_map: raise KeyError('identifier already in!??! %s' % ori) replace_map[ori] = rep for hbp, (e, rep) in to_phenotype.items(): ori = 'HBP_CELL:'+hbp if ori in replace_map: raise KeyError('identifier already in!??! %s' % ori) replace_map[ori] = edge, rep for hbp_iri, rep_iri in equiv.items(): hbp = newgraph.compute_qname(hbp_iri)[2] rep = newgraph.qname(rep_iri) ori = 'HBP_CELL:'+hbp if ori in replace_map: raise KeyError('identifier already in!??! %s' % ori) replace_map[ori] = rep return mg, replace_map
def make_neurons(syn_mappings, pedges, ilx_start_, defined_graph): ilx_start = ilx_start_ cheating = { 'vasoactive intestinal peptide': 'VIP', 'star': None, # is a morphological phen that is missing but hits scigraph } ng = makeGraph('NIF-Neuron', prefixes=PREFIXES) #""" It seemed like a good idea at the time... nif_cell = '~/git/NIF-Ontology/ttl/NIF-Cell.ttl' # need to be on neurons branch cg = rdflib.Graph() cg.parse(os.path.expanduser(nif_cell), format='turtle') missing = ( 'NIFCELL:nifext_55', 'NIFCELL:nifext_56', 'NIFCELL:nifext_57', 'NIFCELL:nifext_59', 'NIFCELL:nifext_81', 'NIFCELL:nlx_cell_091205', NIFCELL_NEURON, 'NIFCELL:sao2128417084', 'NIFCELL:sao862606388', # secondary, not explicitly in the hbp import ) for m in missing: m = ng.expand(m) for s, p, o in cg.triples((m, None, None)): ng.add_trip(s, p, o) #cg.remove((None, rdflib.OWL.imports, None)) # DONOTWANT NIF-Cell imports #for t in cg.triples((None, None, None)): #ng.add_trip(*t) # only way to clean prefixes :/ #cg = None #""" hbp_cell = '~/git/NIF-Ontology/ttl/generated/NIF-Neuron-HBP-cell-import.ttl' # need to be on neurons branch _temp = rdflib.Graph() # use a temp to strip nasty namespaces _temp.parse(os.path.expanduser(hbp_cell), format='turtle') for s, p, o in _temp.triples((None, None, None)): if s != rdflib.URIRef( 'http://ontology.neuinfo.org/NIF/ttl/generated/NIF-Neuron-HBP-cell-import.ttl' ): ng.g.add((s, p, o)) base = 'http://ontology.neuinfo.org/NIF/ttl/' ontid = base + ng.name + '.ttl' ng.add_trip(ontid, rdflib.RDF.type, rdflib.OWL.Ontology) ng.add_trip(ontid, rdflib.OWL.imports, base + 'NIF-Neuron-Phenotype.ttl') ng.add_trip(ontid, rdflib.OWL.imports, base + 'NIF-Neuron-Defined.ttl') ng.add_trip(ontid, rdflib.OWL.imports, base + 'hbp-special.ttl') #ng.add_trip(ontid, rdflib.OWL.imports, base + 'NIF-Cell.ttl') # NO! #ng.add_trip(ontid, rdflib.OWL.imports, base + 'external/uberon.owl') #ng.add_trip(ontid, rdflib.OWL.imports, base + 'external/pr.owl') ng.replace_uriref('ilx:hasMolecularPhenotype', 'ilx:hasExpressionPhenotype') #defined_graph = makeGraph('NIF-Neuron-Defined', prefixes=PREFIXES, graph=_g) defined_graph.add_trip(base + defined_graph.name + '.ttl', rdflib.RDF.type, rdflib.OWL.Ontology) defined_graph.add_trip(base + defined_graph.name + '.ttl', rdflib.OWL.imports, base + 'NIF-Neuron-Phenotype.ttl') done = True #False done_ = set() for pedge in pedges: for s, p, o_lit in ng.g.triples((None, pedge, None)): o = o_lit.toPython() success = False true_o = None true_id = None if o in syn_mappings: id_ = syn_mappings[o] ng.add_hierarchy(id_, p, s) ng.g.remove((s, p, o_lit)) #print('SUCCESS, substituting', o, 'for', id_) success = True true_o = o_lit true_id = id_ elif 'Location' in p.toPython() or 'LocatedIn' in p.toPython( ): # lift location to restrictions if o.startswith('http://'): ng.add_hierarchy(o_lit, p, s) ng.g.remove((s, p, o_lit)) data = sgv.findById(o) label = data['labels'][0] ng.add_trip(o, rdflib.RDF.type, rdflib.OWL.Class) ng.add_trip(o, rdflib.RDFS.label, label) success = True true_o = label true_id = o_lit else: if o in cheating: o = cheating[o] data = sgv.findByTerm(o) if data: print('SCIGRAPH', [(d['curie'], d['labels']) for d in data]) for d in data: if 'PR:' in d['curie']: sgt = ng.expand(d['curie']) ng.add_hierarchy(sgt, p, s) ng.g.remove((s, p, o_lit)) label = d['labels'][0] ng.add_trip(sgt, rdflib.RDF.type, rdflib.OWL.Class) ng.add_trip(sgt, rdflib.RDFS.label, label) success = True true_o = label true_id = sgt break if not success: for d in data: if 'NIFMOL:' in d['curie']: sgt = ng.expand(d['curie']) ng.add_hierarchy(sgt, p, s) ng.g.remove((s, p, o_lit)) label = d['labels'][0] ng.add_trip(sgt, rdflib.RDF.type, rdflib.OWL.Class) ng.add_trip(sgt, rdflib.RDFS.label, label) success = True true_o = label true_id = sgt break if o not in done_ and success: done_.add(o) t = tuple( defined_graph.g.triples( (None, rdflib.OWL.someValuesFrom, true_id))) if t: print('ALREADY IN', t) else: ilx_start += 1 id_ = ng.expand(ilx_base.format(ilx_start)) defined_graph.add_trip(id_, rdflib.RDF.type, rdflib.OWL.Class) restriction = infixowl.Restriction(p, graph=defined_graph.g, someValuesFrom=true_id) intersection = infixowl.BooleanClass( members=(defined_graph.expand(NIFCELL_NEURON), restriction), graph=defined_graph.g) this = infixowl.Class(id_, graph=defined_graph.g) this.equivalentClass = [intersection] this.subClassOf = [ defined_graph.expand(defined_class_parent) ] this.label = rdflib.Literal(true_o + ' neuron') print('make_neurons ilx_start', ilx_start, list(this.label)[0]) if not done: embed() done = True defined_graph.add_class(defined_class_parent, NIFCELL_NEURON, label='defined class neuron') defined_graph.add_trip(defined_class_parent, rdflib.namespace.SKOS.definition, 'Parent class For all defined class neurons') defined_graph.write() ng.write() for sub, syn in [ _ for _ in ng.g.subject_objects(ng.expand('NIFRID:synonym')) ] + [_ for _ in ng.g.subject_objects(rdflib.RDFS.label)]: syn = syn.toPython() if syn in syn_mappings: print('ERROR duplicate synonym!', syn, sub) syn_mappings[syn] = sub return ilx_start
def _row_post(self): # defined class lookup = { graph.expand('ilx:AxonPhenotype'): rdflib.URIRef('http://axon.org'), graph.expand('ilx:AxonMorphologicalPhenotype'): None, graph.expand('ilx:DendritePhenotype'): rdflib.URIRef('http://dendrite.org'), graph.expand('ilx:DendriteMorphologicalPhenotype'): None, graph.expand('ilx:SomaPhenotype'): rdflib.URIRef('http://soma.org'), graph.expand('ilx:SomaMorphologicalPhenotype'): None, graph.expand('ilx:NeuronPhenotype'): graph.expand(NIFCELL_NEURON), graph.expand('ilx:CellPhenotype'): None, graph.expand('ilx:Phenotype'): graph.expand('ilx:Phenotype'), } if self.id_ in lookup: return #elif 'Petilla' in self.id_: #return #else: #print(self.id_) # hidden label for consturctions graph2.add_trip(self.id_, rdflib.namespace.SKOS.hiddenLabel, self._label.rsplit(' Phenotype')[0]) self.ilx_start += 1 id_ = defined_graph.expand(ilx_base.format(self.ilx_start)) defined = infixowl.Class(id_, graph=defined_graph.g) #defined.label = rdflib.Literal(self._label.rstrip(' Phenotype') + ' neuron') # the extra space in rstrip removes 'et ' as well WTF! defined.label = rdflib.Literal( self._label.rstrip('Phenotype') + 'neuron') #print(self._label) print('_row_post ilx_start', self.ilx_start, list(defined.label)[0]) def getPhenotypeEdge(phenotype): print(phenotype) edge = 'ilx:hasPhenotype' # TODO in neuronManager... return edge edge = getPhenotypeEdge(self.id_) restriction = infixowl.Restriction(graph.expand(edge), graph=defined_graph.g, someValuesFrom=self.id_) parent = [p for p in self.child_parent_map[self.id_] if p] if parent: parent = parent[0] while 1: if parent == defined_graph.expand('ilx:NeuronPhenotype'): #defined.subClassOf = [graph.expand(defined_class_parent)] # XXX this does not produce what we want break #else: #print(parent, graph.expand('ilx:NeuronPhenotype')) #print('xxxxxxxxxxxxxxxx', parent) new_parent = [ p for p in self.child_parent_map[parent] if p ] if new_parent: parent = new_parent[0] else: break phenotype_equiv = lookup[parent] else: return intersection = infixowl.BooleanClass(members=(phenotype_equiv, restriction), graph=defined_graph.g) ##intersection = infixowl.BooleanClass(members=(restriction,), graph=self.graph.g) defined.equivalentClass = [intersection]
def GenerateGraph(yaml_object, graph, entity_namespace): """Utility function updates an RDF graph with the yaml content. Updates an RDF graph with the yaml content Args: yaml_object: the yaml content. graph: the global graph where the ontology is being built in RDF. entity_namespace: the namespace to be attributed to the given types Returns: a graph with the contents of the yaml file merged """ # Ignore entities implementing the following keywords in their definition ignore_generation_set = { "DEPRECATED", "INCOMPLETE", "IGNORE", "REMAP_REQUIRED" } field = rdflib.URIRef(constants.FIELDS_NS["Field"]) # Prepare properties to be added to the graph and not in the yaml uses_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["uses"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) uses_property_optionally = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["usesOptional"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) is_composed_of_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["isComposedOf"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) infixowl.Class(identifier=constants.SUBFIELDS_NS["Point_type"], graph=graph) # Traverse the yaml content for clazz, clazz_content in yaml_object.items(): class_name = clazz.capitalize() implements = clazz_content.get("implements") # implements content will decide if the class is added to the graph or not ignore_class = False if implements is not None: for implements_item in implements: if implements_item in ignore_generation_set: ignore_class = True # Generate the class if it does not have implements field # or no (DEPRECATED or INCOMPLETE) if ignore_class: continue # Create the class parent = (entity_namespace[implements[0].capitalize()] if implements is not None else namespace.OWL.Thing) graph, _ = rdf_helper.CreateClassInGraph( graph=graph, class_name=class_name, class_description=clazz_content.get("description"), parent_clazz=parent, entity_namespace=entity_namespace) # update parents only if implements is not None if implements is not None: for implements_item in implements[1:]: graph.add((entity_namespace[class_name.capitalize()], rdflib.RDFS.subClassOf, entity_namespace[implements_item.capitalize()])) # check the mandatory fields uses = clazz_content.get("uses") if uses is not None and isinstance(uses, list): for each_item in uses: list_composition = rdf_helper.DecomposeStandardFieldName( each_item) graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=graph, list_composition=list_composition, standard_field_name=each_item, is_composed_of_property=is_composed_of_property) class_owl = infixowl.Class( identifier=entity_namespace[class_name], graph=graph, subClassOf=[parent]) graph = rdf_helper.CreateCompositionInGraph( list_standard_field_names=uses, composition_operator="&", composition_property=uses_property, restriction=infixowl.only, class_owl=class_owl, graph=graph, entity_namespace=constants.FIELDS_NS, sub_class_of=[field]) # check the optional fields opt_uses = clazz_content.get("opt_uses") if opt_uses is not None and isinstance(opt_uses, list): for each_item in opt_uses: list_composition = rdf_helper.DecomposeStandardFieldName( each_item) graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=graph, list_composition=list_composition, standard_field_name=each_item, is_composed_of_property=is_composed_of_property) class_owl = infixowl.Class( identifier=entity_namespace[class_name], graph=graph, subClassOf=[parent]) graph = rdf_helper.CreateCompositionInGraph( list_standard_field_names=opt_uses, composition_operator="|", composition_property=uses_property_optionally, restriction=infixowl.some, class_owl=class_owl, graph=graph, entity_namespace=constants.FIELDS_NS, sub_class_of=[field]) return graph
def GenerateGraph(yaml_object, graph): """Utility function updates an RDF graph with the yaml content. Updates an RDF graph with the yaml content Args: yaml_object: the yaml content. graph: the global graph where the ontology is being built in RDF. Returns: a graph with the contents of the yaml file merged """ # Create the node to add to the Graph physical_location = rdflib.URIRef( constants.FACILITIES_NS["PhysicalLocation"]) entity_type = rdflib.URIRef(constants.DIGITAL_BUILDINGS_NS["EntityType"]) has_physical_location = rdflib.URIRef( constants.DIGITAL_BUILDINGS_NS["hasPhysicalLocation"]) has_floor = rdflib.URIRef(constants.DIGITAL_BUILDINGS_NS["hasFloor"]) has_room = rdflib.URIRef(constants.DIGITAL_BUILDINGS_NS["hasRoom"]) has_room_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["hasRoom"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) has_floor_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["hasFloor"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) # Add the OWL data to the graph graph.add((physical_location, rdflib.RDF.type, rdflib.OWL.Class)) graph.add((physical_location, rdflib.RDFS.subClassOf, entity_type)) graph.add((physical_location, rdflib.RDFS.label, rdflib.Literal("PhysicalLocation"))) graph.add((physical_location, rdflib.RDFS.comment, rdflib.Literal("The class of all physical locations"))) # Construct the classes and the subclasses map_name_object = {} for clazz in yaml_object.keys(): clazz_content = yaml_object.get(clazz) description = clazz_content.get("description") clazz_object = rdf_helper.CreateClassInGraph( graph, clazz.capitalize(), description, physical_location, entity_namespace=constants.FACILITIES_NS) map_name_object[clazz.capitalize()] = clazz_object # Construct the object properties graph.add( (has_physical_location, rdflib.RDF.type, rdflib.OWL.ObjectProperty)) graph.add((has_physical_location, rdflib.RDF.type, rdflib.OWL.TransitiveProperty)) graph.add((has_floor, rdflib.RDF.type, rdflib.OWL.ObjectProperty)) graph.add((has_room, rdflib.RDF.type, rdflib.OWL.ObjectProperty)) # Construct the sub object properties graph.add((has_floor, rdflib.RDFS.subPropertyOf, has_physical_location)) graph.add((has_room, rdflib.RDFS.subPropertyOf, has_physical_location)) # Link the graph together, done manually until the yaml evolves class_floor = infixowl.Class(identifier=constants.FACILITIES_NS["Floor"], graph=graph) class_room = infixowl.Class(identifier=constants.FACILITIES_NS["Room"], graph=graph) class_building = infixowl.Class( identifier=constants.FACILITIES_NS["Building"], graph=graph) class_building.subClassOf = [ has_floor_property | infixowl.only | class_floor ] class_floor.subClassOf = [has_room_property | infixowl.only | class_room] return graph
def GenerateGraph(yaml_object, graph): """Utility function updates an RDF graph with the yaml content of the GeneralTypes.yaml. The content of each object is similar to the following: CHL: id: "9950288448474578944" description: "Tag for chillers." is_abstract: true implements: - EQUIPMENT opt_uses: - cooling_thermal_power_capacity - power_capacity - efficiency_percentage_specification - flowrate_requirement Updates an RDF graph with the yaml content. Args: yaml_object: the yaml content. graph: the global graph where the ontology is being built in RDF. Returns: a graph with the contents of the yaml file merged """ # Applications Set used to avoid recreating applications again in the graph applications_set = {"Equipment"} # Prepare classes to be added to the graph and not in the yaml equipment = rdflib.URIRef(constants.DIGITAL_BUILDINGS_NS["Equipment"]) entity_type = rdflib.URIRef(constants.DIGITAL_BUILDINGS_NS["EntityType"]) field = rdflib.URIRef(constants.FIELDS_NS["Field"]) infixowl.Class(identifier=constants.FIELDS_NS["Field"], graph=graph) infixowl.Class(identifier=constants.SUBFIELDS_NS["Point_type"], graph=graph) graph, application_class = rdf_helper.CreateClassInGraph( graph=graph, class_name="Application", class_description=None, parent_clazz=entity_type) graph, _ = rdf_helper.CreateClassInGraph(graph=graph, class_name="Equipment", class_description=None, parent_clazz=entity_type) # Prepare properties to be added to the graph and not in the yaml uses_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["uses"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) uses_property_optionally = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["usesOptional"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) is_composed_of_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["isComposedOf"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) # Traverse the yaml content for clazz in yaml_object.keys(): clazz_content = yaml_object.get(clazz) class_name = clazz.capitalize() implements = clazz_content.get("implements") # implements will decide if the entity gets generated in the graph, # for now the mother class is equipment, this might change in the near # future due to changes in the ontology, keeping the implementation as it is if implements is None: continue else: mother_class = equipment # Create the class graph, clazz_object = rdf_helper.CreateClassInGraph( graph=graph, class_name=class_name, class_description=clazz_content.get("description"), parent_clazz=mother_class, entity_namespace=constants.HVAC_NS) if implements is not None: graph, applications_set = rdf_helper.CreatesImplementsInGraph( graph=graph, implements_list=implements, applications_set=applications_set, application_class=application_class, class_object=clazz_object) uses = clazz_content.get("uses") if uses is not None: if isinstance(uses, list): for each_item in uses: list_composition = rdf_helper.DecomposeStandardFieldName( each_item) graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=graph, list_composition=list_composition, standard_field_name=each_item, is_composed_of_property=is_composed_of_property) class_owl = infixowl.Class( identifier=constants.HVAC_NS[class_name], graph=graph, sub_class_of=[equipment]) graph = rdf_helper.CreateCompositionInGraph( list_standard_field_names=uses, composition_operator="&", composition_property=uses_property, restriction=infixowl.only, class_owl=class_owl, graph=graph, entity_namespace=constants.FIELDS_NS, sub_class_of=[field]) opt_uses = clazz_content.get("opt_uses") if opt_uses is not None: if isinstance(opt_uses, list): for each_item in opt_uses: list_composition = rdf_helper.DecomposeStandardFieldName( each_item) graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=graph, list_composition=list_composition, standard_field_name=each_item, is_composed_of_property=is_composed_of_property) class_owl = infixowl.Class( identifier=constants.HVAC_NS[class_name], graph=graph, subClassOf=[equipment]) graph = rdf_helper.CreateCompositionInGraph( list_standard_field_names=opt_uses, composition_operator="|", composition_property=uses_property_optionally, restriction=infixowl.some, class_owl=class_owl, graph=graph, entity_namespace=constants.FIELDS_NS, sub_class_of=[field]) return graph
def GenerateGraph(graph): """Utility function prepares the RDF graph with owl classes before the yaml content gets converted. Updates an RDF graph with the yaml content Args: graph: the global graph where the ontology is being built in RDF. Returns: a graph with the contents of the yaml file merged """ # Create the entities to be added to the Graph entity_type = rdflib.URIRef(constants.DIGITAL_BUILDINGS_NS["EntityType"]) physical_location = rdflib.URIRef(constants.FACILITIES_NS["PhysicalLocation"]) multi_state = rdflib.URIRef(constants.STATES_NS["State"]) field = rdflib.URIRef(constants.FIELDS_NS["Field"]) application = rdflib.URIRef(constants.DIGITAL_BUILDINGS_NS["Application"]) equipment = rdflib.URIRef(constants.DIGITAL_BUILDINGS_NS["Equipment"]) functionality = rdflib.URIRef(constants.HVAC_NS["Functionality"]) # Create the classes physical_location_class = infixowl.Class( identifier=constants.FACILITIES_NS["PhysicalLocation"], graph=graph, subClassOf=[entity_type]) application_class = infixowl.Class( identifier=constants.DIGITAL_BUILDINGS_NS["Application"], graph=graph, subClassOf=[entity_type]) equipment_class = infixowl.Class( identifier=constants.DIGITAL_BUILDINGS_NS["Equipment"], graph=graph, subClassOf=[entity_type]) functionality_class = infixowl.Class( identifier=constants.HVAC_NS["Functionality"], graph=graph, subClassOf=[entity_type]) # Make them disjoint with each other to avoid reasoning inconsistencies physical_location_class.disjointWith = [ application_class, equipment_class, functionality_class ] application_class.disjointWith = [ physical_location_class, equipment_class, functionality_class ] equipment_class.disjointWith = [ application_class, physical_location_class, functionality_class ] functionality_class.disjointWith = [ application_class, equipment_class, physical_location_class ] # Add the OWL Classes to the graph # EntityType graph.add((entity_type, rdflib.RDF.type, rdflib.OWL.Class)) graph.add((entity_type, rdflib.RDFS.subClassOf, rdflib.OWL.Thing)) # PhysicalLocation graph.add((physical_location, rdflib.RDF.type, rdflib.OWL.Class)) graph.add((physical_location, rdflib.RDFS.subClassOf, entity_type)) graph.add((physical_location, rdflib.RDFS.label, rdflib.Literal("PhysicalLocation"))) graph.add((physical_location, rdflib.RDFS.comment, rdflib.Literal("The class of all physical locations"))) # MultiState graph.add((multi_state, rdflib.RDF.type, rdflib.OWL.Class)) graph.add((multi_state, rdflib.RDFS.subClassOf, rdflib.OWL.Thing)) graph.add((multi_state, rdflib.RDFS.label, rdflib.Literal("State"))) graph.add((multi_state, rdflib.RDFS.comment, rdflib.Literal("The class of all states"))) # Functionality graph.add((functionality, rdflib.RDF.type, rdflib.OWL.Class)) graph.add((functionality, rdflib.RDFS.subClassOf, entity_type)) graph.add((functionality, rdflib.RDFS.label, rdflib.Literal("Functionality"))) graph.add((functionality, rdflib.RDFS.comment, rdflib.Literal("The class of all functionalities"))) # Field graph.add((field, rdflib.RDF.type, rdflib.OWL.Class)) graph.add((field, rdflib.RDFS.subClassOf, rdflib.OWL.Thing)) graph.add((field, rdflib.RDFS.label, rdflib.Literal("Field"))) graph.add( (field, rdflib.RDFS.comment, rdflib.Literal("The class of all fields"))) # Application graph.add((application, rdflib.RDF.type, rdflib.OWL.Class)) graph.add((application, rdflib.RDFS.subClassOf, entity_type)) graph.add((application, rdflib.RDFS.label, rdflib.Literal("Application"))) graph.add((application, rdflib.RDFS.comment, rdflib.Literal("The class of all applications"))) # Equipment graph.add((equipment, rdflib.RDF.type, rdflib.OWL.Class)) graph.add((equipment, rdflib.RDFS.subClassOf, entity_type)) graph.add((equipment, rdflib.RDFS.label, rdflib.Literal("Equipment"))) graph.add((equipment, rdflib.RDFS.comment, rdflib.Literal("The class of all equipment"))) return graph
def __init__(self, *phenotypeEdges, id_=None): super().__init__() self.ORDER = [ # FIXME it may make more sense to manage this in the NeuronArranger # so that it can interconvert the two representations # this is really high overhead to load this here self._predicates.hasInstanceInSpecies, self._predicates.hasTaxonRank, self._predicates.hasSomaLocatedIn, # hasSomaLocation? self._predicates.hasLayerLocationPhenotype, # TODO soma naming... self._predicates.hasDendriteMorphologicalPhenotype, self._predicates.hasDendriteLocatedIn, self._predicates.hasAxonLocatedIn, self._predicates.hasMorphologicalPhenotype, self._predicates.hasElectrophysiologicalPhenotype, #self._predicates.hasSpikingPhenotype, # TODO do we need this? self.expand('ilx:hasSpikingPhenotype'), # legacy support self._predicates.hasExpressionPhenotype, self._predicates. hasProjectionPhenotype, # consider inserting after end, requires rework of code... ] self._localContext = self.__context phenotypeEdges = tuple(set(self.__context + phenotypeEdges)) # remove dupes if id_ and phenotypeEdges: raise TypeError( 'This has not been implemented yet. This could serve as a way to validate a match or assign an id manually?' ) elif id_: self.id_ = self.expand(id_) elif phenotypeEdges: #asdf = str(tuple(sorted((_.e, _.p) for _ in phenotypeEdges))) # works except for logical phenotypes self.id_ = self.expand( ILXREPLACE(str(tuple(sorted(phenotypeEdges)))) ) # XXX beware changing how __str__ works... really need to do this else: raise TypeError('Neither phenotypeEdges nor id_ were supplied!') if not phenotypeEdges and id_ is not None: self.Class = infixowl.Class(self.id_, graph=self.in_graph) # IN phenotypeEdges = self.bagExisting( ) # rebuild the bag from the -class- id self.Class = infixowl.Class( self.id_, graph=self.out_graph ) # once we get the data from existing, prep to dump OUT self.pes = tuple( sorted(sorted(phenotypeEdges), key=lambda pe: self.ORDER.index(pe.e) if pe.e in self.ORDER else len(self.ORDER) + 1)) self.phenotypes = set((pe.p for pe in self.pes)) self.edges = set((pe.e for pe in self.pes)) self._pesDict = {} for pe in self.pes: # FIXME TODO if pe.e in self._pesDict: self._pesDict[pe.e].append(pe) else: self._pesDict[pe.e] = [pe] if self in self.existing_pes and self.Class.graph is self.existing_pes[ self].graph: self.Class = self.existing_pes[self] else: self.Class = self._graphify() self.Class.label = rdflib.Literal(self.label) self.existing_pes[self] = self.Class
def testCreatesStandardFieldNameCompositionInGraph(self): # Prepare data # Build First Graph with the method graph = rdflib.Graph() # Bind the OWL and Digital Buildings name spaces namespace_manager = namespace.NamespaceManager(graph) namespace_manager.bind('owl', rdflib.OWL) namespace_manager.bind('db', constants.DIGITAL_BUILDINGS_NS) graph.namespace_manager = namespace_manager list_composition = ['Cooling', 'Air', 'Flowrate', 'Sensor'] standard_field_name = 'cooling_air_flowrate_sensor_1' is_composed_of_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS['isComposedOf'], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) point_type = infixowl.Class( identifier=constants.SUBFIELDS_NS['Point_type'], graph=graph) infixowl.Class(identifier=constants.SUBFIELDS_NS['Sensor'], graph=graph, subClassOf=[point_type]) field = infixowl.Class(identifier=constants.FIELDS_NS['Field'], graph=graph) infixowl.Class( identifier=constants.FIELDS_NS['Cooling_air_flowrate_sensor_1'], graph=graph, subClassOf=[field]) graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( list_composition=list_composition, standard_field_name=standard_field_name, is_composed_of_property=is_composed_of_property, graph=graph) # Build a second graph that is expected expected_graph = rdflib.Graph() # Bind the OWL and Digital Buildings name spaces namespace_manager_expected = namespace.NamespaceManager(expected_graph) namespace_manager_expected.bind('owl', rdflib.OWL) namespace_manager_expected.bind('db', constants.DIGITAL_BUILDINGS_NS) expected_graph.namespace_manager = namespace_manager_expected field_expected = infixowl.Class( identifier=constants.FIELDS_NS['Field'], graph=expected_graph) point_type_expected = infixowl.Class( identifier=constants.SUBFIELDS_NS['Point_type'], graph=expected_graph) cooling_expected = infixowl.Class( identifier=constants.SUBFIELDS_NS['Cooling'], graph=expected_graph) air_expected = infixowl.Class(identifier=constants.SUBFIELDS_NS['Air'], graph=expected_graph) flowrate_expected = infixowl.Class( identifier=constants.SUBFIELDS_NS['Flowrate'], graph=expected_graph) sensor_expected = infixowl.Class( identifier=constants.SUBFIELDS_NS['Sensor'], graph=expected_graph, subClassOf=[point_type_expected]) sfn_expected = infixowl.Class( identifier=constants.FIELDS_NS['Cooling_air_flowrate_sensor_1'], graph=expected_graph, subClassOf=[field_expected]) is_composed_of_property_expected = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS['isComposedOf'], baseType=infixowl.OWL_NS.ObjectProperty, graph=expected_graph) concat = sensor_expected & flowrate_expected concat += air_expected concat += cooling_expected sfn_expected.subClassOf = [ is_composed_of_property_expected | infixowl.only | concat ] # Check if they are similar self.assertTrue(compare.similar(graph, expected_graph))
def GenerateGraph(yaml_object, graph): """Utility function updates an RDF graph with the yaml content of the Abstract.yaml. The content of each object is similar to the following: DXRC: description: "Compressor run control on return air side (RC)." opt_uses: discharge_air_temperature_sensor leaving_cooling_coil_temperature_sensor cooling_thermal_power_capacity uses: return_air_temperature_setpoint return_air_temperature_sensor compressor_run_command compressor_run_status implements: CONTROL Updates an RDF graph with the yaml content. Args: yaml_object: the yaml content. graph: the global graph where the ontology is being built in RDF. Returns: a graph with the contents of the yaml file merged """ # Applications Set used to avoid recreating applications again in the graph applications_set = set() # Prepare classes to be added to the graph and not in the yaml functionality = rdflib.URIRef(constants.HVAC_NS["Functionality"]) entity_type = rdflib.URIRef(constants.DIGITAL_BUILDINGS_NS["EntityType"]) field = rdflib.URIRef(constants.FIELDS_NS["Field"]) infixowl.Class(identifier=constants.FIELDS_NS["Field"], graph=graph) infixowl.Class(identifier=constants.SUBFIELDS_NS["Point_type"], graph=graph) graph, _ = rdf_helper.CreateClassInGraph( graph=graph, class_name="Functionality", class_description=None, parent_clazz=entity_type, entity_namespace=constants.HVAC_NS) graph, application_class = rdf_helper.CreateClassInGraph( graph=graph, class_name="Application", class_description=None, parent_clazz=entity_type) # Prepare properties to be added to the graph and not in the yaml uses_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["uses"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) uses_property_optionally = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["usesOptional"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) is_composed_of_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS["isComposedOf"], baseType=infixowl.OWL_NS.ObjectProperty, graph=graph) # Traverse the yaml content for clazz, clazz_content in yaml_object.items(): class_name = clazz.capitalize() graph, clazz_object = rdf_helper.CreateClassInGraph( graph=graph, class_name=class_name, class_description=clazz_content.get("description"), parent_clazz=functionality, entity_namespace=constants.HVAC_NS) implements = clazz_content.get("implements") if implements is not None: graph, applications_set = rdf_helper.CreatesImplementsInGraph( graph=graph, implements_list=implements, applications_set=applications_set, application_class=application_class, class_object=clazz_object) uses = clazz_content.get("uses") if uses is not None: if isinstance(uses, list): for each_item in uses: list_composition = rdf_helper.DecomposeStandardFieldName( each_item) graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=graph, list_composition=list_composition, standard_field_name=each_item, is_composed_of_property=is_composed_of_property) class_owl = infixowl.Class( identifier=constants.HVAC_NS[class_name], graph=graph, subClassOf=[functionality]) graph = rdf_helper.CreateCompositionInGraph( list_standard_field_names=uses, composition_operator="&", composition_property=uses_property, restriction=infixowl.only, class_owl=class_owl, graph=graph, entity_namespace=constants.FIELDS_NS, sub_class_of=[field]) opt_uses = clazz_content.get("opt_uses") if opt_uses is not None: if isinstance(opt_uses, list): for each_item in opt_uses: list_composition = rdf_helper.DecomposeStandardFieldName( each_item) graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=graph, list_composition=list_composition, standard_field_name=each_item, is_composed_of_property=is_composed_of_property) class_owl = infixowl.Class( identifier=constants.HVAC_NS[class_name], graph=graph, subClassOf=[functionality]) graph = rdf_helper.CreateCompositionInGraph( list_standard_field_names=opt_uses, composition_operator="|", composition_property=uses_property_optionally, restriction=infixowl.some, class_owl=class_owl, graph=graph, entity_namespace=constants.FIELDS_NS, sub_class_of=[field]) return graph
def CreateCompositionInGraph(list_standard_field_names, composition_operator, composition_property, restriction, class_owl, graph, entity_namespace=constants.DIGITAL_BUILDINGS_NS, sub_class_of=None): """Utility function that creates composition from a given list based on a composition operator and a restriction. the created composition is conform to the following pattern: class_owl = [composition_property | restriction | list_standard_field_names[i] | composition_operator | list_standard_field_names [j] with i != j Args: list_standard_field_names: a list of standard field name defined by Carson. Example [compressor_run_status_4, supply_water_temperature_sensor, supply_water_temperature_setpoint] composition_operator: an '&' or '|' operator composition_property: the property which will relate the class and the list of standard field names restriction: the restriction imposed on the composition, 'only' or 'some' class_owl: the class where the composition is attached to. graph: the global graph entity_namespace: the name space for the composition elements sub_class_of: the subClass of the composition elements Returns: graph: updated graph with the composition. """ index = 0 if list_standard_field_names: # Prepare the first element first_element = infixowl.Class(identifier=entity_namespace[ list_standard_field_names[index].capitalize()], graph=graph, subClassOf=sub_class_of) index += 1 # Prepare the second element since the '&' operator is needed to determine # the nature of the composition if index < len(list_standard_field_names): if composition_operator == "&": concat = first_element & infixowl.Class( identifier=entity_namespace[ list_standard_field_names[index].capitalize()], graph=graph, subClassOf=sub_class_of) elif composition_operator == "|": concat = first_element | infixowl.Class( identifier=entity_namespace[ list_standard_field_names[index].capitalize()], graph=graph, subClassOf=sub_class_of) else: logging.error("Unknown operator %s", composition_operator) return graph else: # there is only one element class_owl.subClassOf = [ composition_property | restriction | first_element ] return graph index += 1 # append the rest of the elements while index < len(list_standard_field_names): concat += infixowl.Class(identifier=entity_namespace[ list_standard_field_names[index].capitalize()], graph=graph, subClassOf=sub_class_of) index += 1 class_owl.subClassOf = [composition_property | restriction | concat] return graph
def make_table1(syn_mappings, ilx_start, phenotypes): # TODO when to explicitly subClassOf? I think we want this when the higher level phenotype bag is shared # it may turn out that things like the disjointness exist at a higher level while correlated properties # should be instantiated together as sub classes, for example if cck and # FIXME disagreement about nest basket cells # TODO hasPhenotypes needs to be function to get phenotypeOf to work via reasoner??? this seems wrong. # this also works if phenotypeOf is inverseFunctional # hasPhenotype shall be asymmetric, irreflexive, and intransitive # XXX in answer to Maryann's question about why we need the morphological phenotypes by themselves: # if we don't have them we can't agregate across orthogonal phenotypes since owl correctly keeps the classes distinct # TODO disjointness axioms work really well on defined classes and propagate excellently # TODO add 'Petilla' or something like that to the phenotype definitions # we want this because 'Petilla' denotes the exact ANALYSIS used to determine the phenotype # there are some additional 'protocol' related restrictions on what you can apply analysis to # but we don't have to model those explicitly which would be a nightmare and break the # orthogonality of the cell type decomposition # TODO to make this explicit we need to include that phenotypes require 2 things # 1) a type of data (data type?) 2) a way to classify that data (analysis protocol) # # need a full type restriction... property chain? graph = makeGraph('hbp-special', prefixes=PREFIXES) # XXX fix all prefixes with open(refile(__file__, 'resources/26451489 table 1.csv'), 'rt') as f: rows = [list(r) for r in zip(*csv.reader(f))] base = 'http://ontology.neuinfo.org/NIF/ttl/' ontid = base + graph.name + '.ttl' graph.add_trip(ontid, rdflib.RDF.type, rdflib.OWL.Ontology) graph.add_trip(ontid, rdflib.OWL.imports, base + 'NIF-Neuron-Phenotype.ttl') graph.add_trip(ontid, rdflib.OWL.imports, base + 'NIF-Neuron-Defined.ttl') def lsn(word): syn_mappings[word] = graph.expand( sgv.findByTerm(word)[0]['curie']) # cheating lsn('Parvalbumin') lsn('neuropeptide Y') lsn('VIP peptides') lsn('somatostatin') syn_mappings['calbindin'] = graph.expand('PR:000004967') # cheating syn_mappings['calretinin'] = graph.expand('PR:000004968') # cheating t = table1(graph, rows, syn_mappings, ilx_start) ilx_start = t.ilx_start # adding fake mouse data #with open(refile(__file__, 'resources/26451489 table 1.csv'), 'rt') as f: # FIXME annoying #rows = [list(r) for r in zip(*csv.reader(f))] #t2 = table1(graph, rows, syn_mappings, ilx_start, species='NCBITaxon:10090') # FIXME double SOM+ phenos etc #ilx_start = t2.ilx_start def do_graph(d): sgt = graph.expand(d['curie']) label = d['labels'][0] graph.add_trip(sgt, rdflib.RDF.type, rdflib.OWL.Class) graph.add_trip(sgt, rdflib.RDFS.label, label) done = set() for s, p, o in graph.g.triples( (None, None, None)): #(rdflib.RDFS.subClassOf,rdflib.OWL.Thing)): if o not in done and type(o) == rdflib.term.URIRef: done.add(o) if not [_ for _ in graph.g.objects((o, rdflib.RDFS.label))]: d = sgv.findById(o) if d: if 'PR:' in d['curie']: do_graph(d) elif 'NIFMOL:' in d['curie']: do_graph(d) elif 'UBERON:' in d['curie']: do_graph(d) elif 'NCBITaxon:' in d['curie']: do_graph(d) elif 'NIFCELL:' in d['curie']: do_graph(d) # FIXME this is a dupe with defined_class #graph.add_trip(defined_class_parent, rdflib.RDF.type, rdflib.OWL.Class) #graph.add_trip(defined_class_parent, rdflib.RDFS.label, 'defined class neuron') #graph.add_trip(defined_class_parent, rdflib.namespace.SKOS.description, 'Parent class For all defined class neurons') #graph.add_trip(defined_class_parent, rdflib.RDFS.subClassOf, NIFCELL_NEURON) #graph.add_trip(morpho_defined, rdflib.RDFS.subClassOf, defined_class_parent) #graph.add_trip(morpho_defined, rdflib.RDFS.label, 'Morphologically classified neuron') # FIXME -- need asserted in here... #graph.add_trip(ephys_defined, rdflib.RDFS.subClassOf, defined_class_parent) #graph.add_trip(ephys_defined, rdflib.RDFS.label, 'Electrophysiologically classified neuron') graph.add_class(expression_defined, NIFCELL_NEURON, autogen=True) graph.add_class('ilx:NeuroTypeClass', NIFCELL_NEURON, label='Neuron TypeClass') graph.g.commit() phenotype_dju_dict = add_types(graph, phenotypes) for pheno, disjoints in phenotype_dju_dict.items(): name = ' '.join(re.findall( r'[A-Z][a-z]*', pheno.split(':')[1])[:-1]) #-1: drops Phenotype ilx_start += 1 # = make_defined(graph, ilx_start, name + ' neuron type', pheno, 'ilx:hasPhenotype') id_ = graph.expand(ilx_base.format(ilx_start)) typeclass = infixowl.Class(id_, graph=graph.g) typeclass.label = rdflib.Literal(name + ' neuron type') restriction = infixowl.Restriction(graph.expand('ilx:hasPhenotype'), graph=graph.g, someValuesFrom=pheno) #typeclass.subClassOf = [restriction, graph.expand('ilx:NeuroTypeClass')] ntc = graph.expand('ilx:NeuroTypeClass') intersection = infixowl.BooleanClass(members=(ntc, restriction), graph=graph.g) typeclass.equivalentClass = [intersection] # FIXME not clear that we should be doing typeclasses this way.... :/ # requires more thought, on the plus side you do get better reasoning... disjointunion = disjointUnionOf(graph=graph.g, members=list(disjoints)) graph.add_trip(id_, rdflib.OWL.disjointUnionOf, disjointunion) graph.write() return t
def testAbstractGraphGeneration(self): fake_abstract = 'fake_resources/Abstract.yaml' file_contents = rdf_helper.ReadFile(fake_abstract) yaml_abstract = yaml_handler.ImportYamlFiles(file_contents) # Create global graph graph = rdflib.Graph() # Generate the graph by the function handler graph = rdflib_function_handler.GenerateGraph(yaml_abstract, graph) # Build a second graph manually in order to compare it with the one above: # DD: # description: "Dual duct flow control (hot deck, cold deck)." # is_abstract: true # opt_uses: # - discharge_air_temperature_sensor # - run_command # uses: # - heating_air_flowrate_sensor # - heating_air_flowrate_setpoint # implements: # - CONTROL expected_graph = rdflib.Graph() # Main Types functionality = rdflib.URIRef(constants.HVAC_NS['Functionality']) entity_type = rdflib.URIRef( constants.DIGITAL_BUILDINGS_NS['EntityType']) dd_description = 'Dual duct flow control (hot deck, cold deck).' # Main Classes dd_expected = infixowl.Class(identifier=constants.HVAC_NS['Dd'], graph=expected_graph, subClassOf=[functionality]) expected_graph, _ = rdf_helper.CreateClassInGraph( graph=expected_graph, class_name='Dd', class_description=dd_description, parent_clazz=functionality, entity_namespace=constants.HVAC_NS) infixowl.Class(identifier=constants.SUBFIELDS_NS['Point_type'], graph=expected_graph) uses_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS['uses'], baseType=infixowl.OWL_NS.ObjectProperty, graph=expected_graph) is_composed_of_property = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS['isComposedOf'], baseType=infixowl.OWL_NS.ObjectProperty, graph=expected_graph) uses_property_optionally = infixowl.Property( identifier=constants.DIGITAL_BUILDINGS_NS['usesOptional'], baseType=infixowl.OWL_NS.ObjectProperty, graph=expected_graph) infixowl.Class(identifier=constants.SUBFIELDS_NS['Air'], graph=expected_graph) infixowl.Class(identifier=constants.SUBFIELDS_NS['Flowrate'], graph=expected_graph) infixowl.Class(identifier=constants.SUBFIELDS_NS['Heating'], graph=expected_graph) infixowl.Class(identifier=constants.SUBFIELDS_NS['Run'], graph=expected_graph) infixowl.Class(identifier=constants.SUBFIELDS_NS['Command'], graph=expected_graph) infixowl.Class(identifier=constants.SUBFIELDS_NS['Discharge'], graph=expected_graph) infixowl.Class(identifier=constants.SUBFIELDS_NS['Temperature'], graph=expected_graph) infixowl.Class(identifier=constants.SUBFIELDS_NS['Sensor'], graph=expected_graph) infixowl.Class(identifier=constants.FIELDS_NS['Field'], graph=expected_graph) heating_air_flowrate_sensor = infixowl.Class( identifier=constants.FIELDS_NS['Heating_air_flowrate_sensor'], graph=expected_graph, subClassOf=[constants.FIELDS_NS['Field']]) heating_air_flowrate_setpoint = infixowl.Class( identifier=constants.FIELDS_NS['Heating_air_flowrate_setpoint'], graph=expected_graph, subClassOf=[constants.FIELDS_NS['Field']]) concat = heating_air_flowrate_sensor & heating_air_flowrate_setpoint dd_expected.subClassOf = [uses_property | infixowl.only | concat] discharge_air_temperature_sensor = infixowl.Class( identifier=constants.FIELDS_NS['Discharge_air_temperature_sensor'], graph=expected_graph, subClassOf=[constants.FIELDS_NS['Field']]) run_command = infixowl.Class( identifier=constants.FIELDS_NS['Run_command'], graph=expected_graph, subClassOf=[constants.FIELDS_NS['Field']]) concat2 = discharge_air_temperature_sensor | run_command dd_expected.subClassOf = [ uses_property_optionally | infixowl.some | concat2 ] list_composition = rdf_helper.DecomposeStandardFieldName( 'Discharge_air_temperature_sensor') expected_graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=expected_graph, list_composition=list_composition, standard_field_name='Discharge_air_temperature_sensor', is_composed_of_property=is_composed_of_property) list_composition = rdf_helper.DecomposeStandardFieldName('Run_command') expected_graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=expected_graph, list_composition=list_composition, standard_field_name='Run_command', is_composed_of_property=is_composed_of_property) list_composition = rdf_helper.DecomposeStandardFieldName( 'Heating_air_flowrate_sensor') expected_graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=expected_graph, list_composition=list_composition, standard_field_name='Heating_air_flowrate_sensor', is_composed_of_property=is_composed_of_property) list_composition = rdf_helper.DecomposeStandardFieldName( 'Heating_air_flowrate_setpoint') expected_graph = rdf_helper.CreatesStandardFieldNameCompositionInGraph( graph=expected_graph, list_composition=list_composition, standard_field_name='Heating_air_flowrate_setpoint', is_composed_of_property=is_composed_of_property) expected_graph, functionality_class = rdf_helper.CreateClassInGraph( graph=expected_graph, class_name='Functionality', class_description=None, parent_clazz=entity_type, entity_namespace=constants.HVAC_NS) expected_graph, application = rdf_helper.CreateClassInGraph( graph=expected_graph, class_name='Application', class_description=None, parent_clazz=entity_type) expected_graph, control = rdf_helper.CreateClassInGraph( graph=expected_graph, class_name='Control', class_description=None, parent_clazz=application[0]) expected_graph, _ = rdf_helper.CreateClassInGraph( graph=expected_graph, class_name='Dd', class_description=dd_description, parent_clazz=functionality_class[0], entity_namespace=constants.HVAC_NS) expected_graph, _ = rdf_helper.CreateClassInGraph( graph=expected_graph, class_name='Dd', class_description=dd_description, parent_clazz=control[0], entity_namespace=constants.HVAC_NS) # Check if they are similar self.assertTrue(compare.similar(graph, expected_graph))
def ilx_id(self, value): self.id_ = graph2.expand(value) self.Class = infixowl.Class(self.id_, graph=graph2.g) label = ' '.join(re.findall(r'[A-Z][a-z]*', self.id_.split(':')[1])) self._label = label