# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['linkml_owl', 'linkml_owl.util']

package_data = \
{'': ['*']}

install_requires = \
['Jinja2>=3.0.3,<4.0.0',
 'click',
 'funowl>=0.1.10,<0.2.0',
 'linkml-runtime>=1.1.19,<2.0.0',
 'linkml>=1.1.16,<2.0.0',
 'rdflib>=5.0.0,<6.0.0']

entry_points = \
{'console_scripts': ['linkml-data2owl = linkml_owl.owl_dumper:cli']}

setup_kwargs = {
    'name': 'linkml-owl',
    'version': '0.1.0',
    'description': 'OWL mappings for Linked Open Data Modeling Language',
    'long_description': '# linkml-owl\n\nThis is an ALPHA version of a tool for translating LinkML instance data to OWL (TBoxes and ABoxes)\n\n[LinkML](https://linkml/io/linkml) is a general purpose data modeling\nlanguage for authoring schemas to structure data. The perspective of\nlinkml-owl is that elements of an OWL ontology (in particular,\nclasses) are data elements that should conform to a schema\n\n* [EXAMPLES.md](EXAMPLES.md)\n* [SPECIFICATION.md](SPECIFICATION.md)\n\n## Usage\n\n```bash\nlinkml-data2owl -s my_schema.yaml my_data.{yaml,json,tsv,rdf} -o my_ontology.owl.ttl \n```\n\n## Basics\n\nFirst specify your schema\n\n```yaml\nclasses:\n  Class:\n    slots:\n      - id\n      - label\n    class_uri: owl:Class\n  AnatomicalEntityClass:\n    is_a: Class\n    slots:\n      - part_of\n     slot_usage:\n       range: AnatomicalEntityClass\n\nslots:\n  label:\n    slot_uri: rdfs:label\n    annotations:\n      owl: AnnotationAssertion\n  part_of:\n    slot_uri: BFO:0000050\n    annotations:\n      owl: SubClassOf, ObjectSomeValuesFrom\n```\n\nThen provide OWL classes as LinkML data instances using any of the standard ways of providing data in LinkML (see [working with data](https://linkml.io/linkml/data/index.html))\n\nFor example, as TSV or YAML:\n\n```\n\'UBERON:1\':\n  label: eye\n  part_of: [\'UBERON:2\']\n\'UBERON:2\':\n  label: head\n  part_of: [\'UBERON:3\']\n\'UBERON:3\':\n  label: organism\n  part_of: []\n```\n\nthen run this through the command line tool to generate an ontology\n\n```owl\nAnnotationAssertion(rdfs:label UBERON:1 "eye")\nAnnotationAssertion(rdfs:label UBERON:2 "head")\nAnnotationAssertion(rdfs:label UBERON:3 "organism")\nSubClassOf( UBERON:1  ObjectSomeValuesFrom( BFO:0000050 UBERON:2))\nSubClassOf( UBERON:2  ObjectSomeValuesFrom( BFO:0000050 UBERON:3))\n```\n\nSee [EXAMPLES.md](EXAMPLES.md) for a complete set of examples/conformance suite\n\n## Templates and Fstrings\n\nThe above method of annotating slots with OWL interpretations works well for cases where there is a relatively straightforward mapping between slots and axioms.\n\nFor full grained control you can use either\n\n * fstrings, e.g. `SubClassOf({id} {sublass_of})`, for cases with no or minimal logic\n * Jinja2 templates, for cases where control logic or advanced mappings are required\n\nHere is an example of a more advanced schema involving nesting where we might want to model parts with counts - examples include reaction participants with stoichiometry, or protein complexes where members may be present with different counts or activation states:\n\n```yaml\nPartWithCounts:\n    is_a: Anonymous\n    attributes:\n      unit:\n        range: NamedThing\n        multivalued: false\n        annotations:\n          owl: SomeValuesFrom\n      count:\n        range: integer\n        minimum_value: 1\n        annotations:\n          owl: HasValue\n      state:\n        range: ActivationStateEnum\n        annotations:\n          owl: SomeValuesFrom\n\n  CollectionOfPartsWithCounts:\n    is_a: NamedThing\n    slots:\n      - has_part\n    slot_usage:\n      has_part:\n        range: PartWithCounts\n        inlined: true\n    annotations:\n      owl.template: |-\n        {% for p in has_part %}\n        SubClassOf( {{id}}\n                    ObjectSomeValuesFrom( BFO:0000051\n                                          ObjectIntersectionOf( {{p.unit }}\n                                                                ObjectSomeValuesFrom(RO:0000053 {{p.state.meaning}})\n                                                                {% if p.count %}\n                                                                DataHasValue(PATO:0001555 {{p.count}})\n                                                                {% endif %}\n                                                              )\n\n                                         )\n                  )\n        {% endfor %}\n```        \n\nGiven an input file:\n\n```yaml\nid: x:collection\nhas_part:\n  - unit: x:p1\n    count: 2\n    state: ACTIVATED\n  - unit: x:p2\n    count: 3\n    state: ACTIVATED\n```\n\n(note that we use using nesting / a normalized representation here, this is harder to represent in a spreadsheet).\n\nThis will generate the following OWL:\n\n```owl\nSubClassOf( x:collection\n            ObjectSomeValuesFrom( BFO:0000051\n                                  ObjectIntersectionOf(\n                                                       x:p1\n                                                       ObjectSomeValuesFrom( RO:0000053 <http://purl.obolibrary.org/obo/PATO_0002354> )\n                                                       DataHasValue( PATO:0001555 "2"^^xsd:integer ))))\nSubClassOf( x:collection\n            ObjectSomeValuesFrom( BFO:0000051\n                                  ObjectIntersectionOf(\n                                                       x:p2\n                                                       ObjectSomeValuesFrom( RO:0000053 <http://purl.obolibrary.org/obo/PATO_0002354> )\n                                                       DataHasValue( PATO:0001555 "3"^^xsd:integer ))))\n```\n\n## Vocabulary\n\nUse the following keywords to annotate your schema elements:\n\n * Slots\n    - Axiom type designators\n        - SubClassOf\n        - EquivalentClasses\n        - AnnotationAssertion\n        - ...\n    - Expression modifier designators\n        - ObjectSomeValuesFrom\n        - ObjectAllValuesFrom\n        - ...\n    - Collection type designators\n        - ObjectIntersectionOf\n        - ObjectUnionOf\n        - ...\n * Classes\n    - Class\n    - Individual\n    - ...\n    \n\n## Relationship to OWL template languages\n\nAlthough LinkML is robust and stable, LinkML-OWL is alpha software and incomplete. For now, to convert from TSV to OWL you should for now use a dedicated environment:\n\n * dosdp-tools\n * robot-templates\n * ottr\n\nFor most purposes, these frameworks are also simpler and less\noverhead, they treat ontology generation as a *string templating*\nproblem, and the emphasis is on the generation of axioms from\ntemplates over formal descriptions of the source input file.\n\nIn contrast, linkml-owl leverages the linkml framework for rich\nmodeling of the source data structures used to generate the ontology,\nin particular:\n\n * Clear computable description of which columns are required, which columns are multivalued etc\n * Ability to use arbitrarily nested JSON trees or RDF graphs as input\n * Use of [semantic enumerations](https://linkml.io/linkml/intro/tutorial06.html)\n    - for example, a field value may be restricted to two ontology terms such as "off" or "on"\n * Translation of source schema to other formalisms such as JSON-Schema, JSON-LD Contexts, shape languages, SQL, ...\n * Flexible validation of source input files leveraging any combination of JSON-Schema, SHACL, or ShEx\n * Generation of markdown documentation from source schemas\n\nAn example of a domain where this kind of rich data modeling of input\ndata includes generation of chemical entity ontologies from data. See\nthe [chemrof](https://chemkg.github.io/chemrof/) project\n\n## See Also\n\n* [OWL Generator](https://linkml.io/linkml/generators/owl.html) in the LinkML core generates OWL from Schemas, **not** data\n* rdflib_dumper in linkml-runtime generates RDF graphs (ABoxes) from LinkML instances graphs using a standard 1:1 mapping\n',
    'author': 'Chris Mungall',
    'author_email': 'cjmungall@lbl.gov',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/linkml/linkml-owl',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'entry_points': entry_points,
    'python_requires': '>=3.7.1,<4.0.0',
}


setup(**setup_kwargs)
