コード例 #1
0
class SubsetDefinition(Element):
    """
    the name and description of a subset
    """
    _inherited_slots: ClassVar[List[str]] = []

    # === element ===
    name: Union[str, SubsetDefinitionName] = None
    id_prefixes: List[Union[str, NCName]] = empty_list()
    aliases: List[str] = empty_list()
    local_names: Union[dict, "LocalName"] = empty_dict()
    mappings: List[Union[str, URIorCURIE]] = empty_list()
    description: Optional[str] = None
    alt_descriptions: Union[dict, "AltDescription"] = empty_dict()
    deprecated: Optional[str] = None
    todos: List[str] = empty_list()
    notes: List[str] = empty_list()
    comments: List[str] = empty_list()
    examples: List[Union[dict, "Example"]] = empty_list()
    in_subset: List[Union[str, SubsetDefinitionName]] = empty_list()
    from_schema: Optional[Union[str, URI]] = None
    imported_from: Optional[str] = None
    see_also: List[Union[str, URIorCURIE]] = empty_list()

    # === subset_definition ===

    def _fix_elements(self):
        super()._fix_elements()
        if self.name is not None and not isinstance(self.name,
                                                    SubsetDefinitionName):
            self.name = SubsetDefinitionName(self.name)
コード例 #2
0
class Element(YAMLRoot):
    """
    a named element in the model
    """
    _inherited_slots: ClassVar[List[str]] = []

    # === element ===
    name: Union[str, ElementName]
    id_prefixes: List[Union[str, NCName]] = empty_list()
    aliases: List[str] = empty_list()
    local_names: Union[dict, "LocalName"] = empty_dict()
    mappings: List[Union[str, URIorCURIE]] = empty_list()
    description: Optional[str] = None
    alt_descriptions: Union[dict, "AltDescription"] = empty_dict()
    deprecated: Optional[str] = None
    todos: List[str] = empty_list()
    notes: List[str] = empty_list()
    comments: List[str] = empty_list()
    examples: List[Union[dict, "Example"]] = empty_list()
    in_subset: List[Union[str, SubsetDefinitionName]] = empty_list()
    from_schema: Optional[Union[str, URI]] = None
    imported_from: Optional[str] = None
    see_also: List[Union[str, URIorCURIE]] = empty_list()

    def _fix_elements(self):
        super()._fix_elements()
        self.id_prefixes = [
            v if isinstance(v, NCName) else NCName(v) for v in self.id_prefixes
        ]
        if not isinstance(self.name, ElementName):
            self.name = ElementName(self.name)
        for k, v in self.local_names.items():
            if not isinstance(v, LocalName):
                self.local_names[k] = LocalName(k, v)
        self.mappings = [
            v if isinstance(v, URIorCURIE) else URIorCURIE(v)
            for v in self.mappings
        ]
        for k, v in self.alt_descriptions.items():
            if not isinstance(v, AltDescription):
                self.alt_descriptions[k] = AltDescription(k, v)
        self.examples = [
            v if isinstance(v, Example) else Example(**v)
            for v in self.examples
        ]
        self.in_subset = [
            v
            if isinstance(v, SubsetDefinitionName) else SubsetDefinitionName(v)
            for v in self.in_subset
        ]
        if self.from_schema is not None and not isinstance(
                self.from_schema, URI):
            self.from_schema = URI(self.from_schema)
        self.see_also = [
            v if isinstance(v, URIorCURIE) else URIorCURIE(v)
            for v in self.see_also
        ]
コード例 #3
0
class ClassDefinition(Definition):
    """
    the definition of a class or interface
    """
    _inherited_slots: ClassVar[List[str]] = ["defining_slots"]

    class_class_uri: ClassVar[URIRef] = META.ClassDefinition
    class_class_curie: ClassVar[str] = "meta:ClassDefinition"
    class_name: ClassVar[str] = "class_definition"
    class_model_uri: ClassVar[URIRef] = META.ClassDefinition

    name: Union[str, ClassDefinitionName] = None
    slots: List[Union[str, SlotDefinitionName]] = empty_list()
    slot_usage: Dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]] = empty_dict()
    attributes: Dict[Union[str, SlotDefinitionName], Union[dict, SlotDefinition]] = empty_dict()
    class_uri: Optional[Union[str, URIorCURIE]] = None
    subclass_of: Optional[Union[str, URIorCURIE]] = None
    union_of: List[Union[str, ClassDefinitionName]] = empty_list()
    defining_slots: List[Union[str, SlotDefinitionName]] = empty_list()
    tree_root: Optional[Bool] = None
    is_a: Optional[Union[str, ClassDefinitionName]] = None
    mixins: List[Union[str, ClassDefinitionName]] = empty_list()
    apply_to: List[Union[str, ClassDefinitionName]] = empty_list()

    def __post_init__(self, **kwargs: Dict[str, Any]):
        if self.name is None:
            raise ValueError(f"name must be supplied")
        if not isinstance(self.name, ClassDefinitionName):
            self.name = ClassDefinitionName(self.name)
        self.slots = [v if isinstance(v, SlotDefinitionName)
                      else SlotDefinitionName(v) for v in ([self.slots] if isinstance(self.slots, str) else self.slots)]
        for k, v in self.slot_usage.items():
            if not isinstance(v, SlotDefinition):
                self.slot_usage[k] = SlotDefinition(name=k, **({} if v is None else v))
        for k, v in self.attributes.items():
            if not isinstance(v, SlotDefinition):
                self.attributes[k] = SlotDefinition(name=k, **({} if v is None else v))
        if self.class_uri is not None and not isinstance(self.class_uri, URIorCURIE):
            self.class_uri = URIorCURIE(self.class_uri)
        if self.subclass_of is not None and not isinstance(self.subclass_of, URIorCURIE):
            self.subclass_of = URIorCURIE(self.subclass_of)
        self.union_of = [v if isinstance(v, ClassDefinitionName)
                         else ClassDefinitionName(v) for v in ([self.union_of] if isinstance(self.union_of, str) else self.union_of)]
        self.defining_slots = [v if isinstance(v, SlotDefinitionName)
                               else SlotDefinitionName(v) for v in ([self.defining_slots] if isinstance(self.defining_slots, str) else self.defining_slots)]
        if self.is_a is not None and not isinstance(self.is_a, ClassDefinitionName):
            self.is_a = ClassDefinitionName(self.is_a)
        self.mixins = [v if isinstance(v, ClassDefinitionName)
                       else ClassDefinitionName(v) for v in ([self.mixins] if isinstance(self.mixins, str) else self.mixins)]
        self.apply_to = [v if isinstance(v, ClassDefinitionName)
                         else ClassDefinitionName(v) for v in ([self.apply_to] if isinstance(self.apply_to, str) else self.apply_to)]
        super().__post_init__(**kwargs)
コード例 #4
0
class Definition(Element):
    """
    base class for definitions
    """
    _inherited_slots: ClassVar[List[str]] = []

    # === element ===
    name: Union[str, DefinitionName] = None
    id_prefixes: List[Union[str, NCName]] = empty_list()
    aliases: List[str] = empty_list()
    local_names: Union[dict, "LocalName"] = empty_dict()
    mappings: List[Union[str, URIorCURIE]] = empty_list()
    description: Optional[str] = None
    alt_descriptions: Union[dict, "AltDescription"] = empty_dict()
    deprecated: Optional[str] = None
    todos: List[str] = empty_list()
    notes: List[str] = empty_list()
    comments: List[str] = empty_list()
    examples: List[Union[dict, "Example"]] = empty_list()
    in_subset: List[Union[str, SubsetDefinitionName]] = empty_list()
    from_schema: Optional[Union[str, URI]] = None
    imported_from: Optional[str] = None
    see_also: List[Union[str, URIorCURIE]] = empty_list()

    # === definition ===
    is_a: Optional[Union[str, DefinitionName]] = None
    abstract: Optional[Bool] = None
    mixin: Optional[Bool] = None
    mixins: List[Union[str, DefinitionName]] = empty_list()
    apply_to: List[Union[str, DefinitionName]] = empty_list()
    values_from: List[Union[str, URIorCURIE]] = empty_list()

    def _fix_elements(self):
        super()._fix_elements()
        if self.is_a is not None and not isinstance(self.is_a, DefinitionName):
            self.is_a = DefinitionName(self.is_a)
        self.mixins = [
            v if isinstance(v, DefinitionName) else DefinitionName(v)
            for v in self.mixins
        ]
        self.apply_to = [
            v if isinstance(v, DefinitionName) else DefinitionName(v)
            for v in self.apply_to
        ]
        self.values_from = [
            v if isinstance(v, URIorCURIE) else URIorCURIE(v)
            for v in self.values_from
        ]
コード例 #5
0
class ResolvedValueSetHeader(YAMLRoot):
    """
    The information required to completely resolve a value set definition.
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = TCCM.ResolvedValueSetHeader
    class_class_curie: ClassVar[str] = "tccm:ResolvedValueSetHeader"
    class_name: ClassVar[str] = "ResolvedValueSetHeader"
    class_model_uri: ClassVar[URIRef] = TCCM.ResolvedValueSetHeader

    resolutionOf: Union[dict, ValueSetDefinitionReference]
    resolvedUsingCodeSystem: Dict[
        Union[str, CodeSystemVersionReferenceName],
        Union[dict, CodeSystemVersionReference]] = empty_dict()
    includesResolvedValueSet: List[Union[
        dict, "ResolvedValueSetHeader"]] = empty_list()

    def __post_init__(self, **kwargs: Dict[str, Any]):
        if self.resolutionOf is None:
            raise ValueError(f"resolutionOf must be supplied")
        if not isinstance(self.resolutionOf, ValueSetDefinitionReference):
            self.resolutionOf = ValueSetDefinitionReference(self.resolutionOf)
        for k, v in self.resolvedUsingCodeSystem.items():
            if not isinstance(v, CodeSystemVersionReference):
                self.resolvedUsingCodeSystem[k] = CodeSystemVersionReference(
                    name=k, **({} if v is None else v))
        self.includesResolvedValueSet = [ResolvedValueSetHeader(*e) for e in self.includesResolvedValueSet.items()] if isinstance(self.includesResolvedValueSet, dict) \
                                         else [v if isinstance(v, ResolvedValueSetHeader) else ResolvedValueSetHeader(**v)
                                               for v in ([self.includesResolvedValueSet] if isinstance(self.includesResolvedValueSet, str) else self.includesResolvedValueSet)]
        super().__post_init__(**kwargs)
コード例 #6
0
class Manager(Employee):
    """
    An employee who manages others
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = URIRef(
        "http://example.org/sample/organization/Manager")
    class_class_curie: ClassVar[str] = None
    class_name: ClassVar[str] = "manager"
    class_model_uri: ClassVar[URIRef] = URIRef(
        "http://example.org/sample/organization/Manager")

    id: Union[str, ManagerId] = None
    last_name: str = None
    has_employees: Dict[Union[str, EmployeeId],
                        Union[dict, Employee]] = empty_dict()

    def __post_init__(self, **kwargs: Dict[str, Any]):
        if self.id is None:
            raise ValueError(f"id must be supplied")
        if not isinstance(self.id, ManagerId):
            self.id = ManagerId(self.id)
        for k, v in self.has_employees.items():
            if not isinstance(v, Employee):
                self.has_employees[k] = Employee(id=k,
                                                 **({} if v is None else v))
        super().__post_init__(**kwargs)
コード例 #7
0
class TypeDefinition(Element):
    """
    A data type definition.
    """
    _inherited_slots: ClassVar[List[str]] = ["base", "uri", "repr"]

    # === element ===
    name: Union[str, TypeDefinitionName] = None
    id_prefixes: List[Union[str, NCName]] = empty_list()
    aliases: List[str] = empty_list()
    local_names: Union[dict, "LocalName"] = empty_dict()
    mappings: List[Union[str, URIorCURIE]] = empty_list()
    description: Optional[str] = None
    alt_descriptions: Union[dict, "AltDescription"] = empty_dict()
    deprecated: Optional[str] = None
    todos: List[str] = empty_list()
    notes: List[str] = empty_list()
    comments: List[str] = empty_list()
    examples: List[Union[dict, "Example"]] = empty_list()
    in_subset: List[Union[str, SubsetDefinitionName]] = empty_list()
    from_schema: Optional[Union[str, URI]] = None
    imported_from: Optional[str] = None
    see_also: List[Union[str, URIorCURIE]] = empty_list()

    # === type_definition ===
    typeof: Optional[Union[str, TypeDefinitionName]] = None
    base: Optional[str] = None
    uri: Optional[Union[str, URIorCURIE]] = None
    repr: Optional[str] = None

    def _fix_elements(self):
        super()._fix_elements()
        if self.name is not None and not isinstance(self.name,
                                                    TypeDefinitionName):
            self.name = TypeDefinitionName(self.name)
        if self.typeof is not None and not isinstance(self.typeof,
                                                      TypeDefinitionName):
            self.typeof = TypeDefinitionName(self.typeof)
        if self.uri is not None and not isinstance(self.uri, URIorCURIE):
            self.uri = URIorCURIE(self.uri)
コード例 #8
0
class ValueSetCatalogEntry(ValueSetCatalogEntryOrReference):
    """
    A ValueSetCatalogEntry carries information about the creators, distributors, purpose, use, etc. about a value set.
    The catalog does not carry the actual definition of a value set as (a) this may vary over time and (b) it is
    possible for more than one definition to be in use at any given point in time.
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = TCCM.ValueSetCatalogEntry
    class_class_curie: ClassVar[str] = "tccm:ValueSetCatalogEntry"
    class_name: ClassVar[str] = "ValueSetCatalogEntry"
    class_model_uri: ClassVar[URIRef] = TCCM.ValueSetCatalogEntry

    id: Union[str, ValueSetCatalogEntryId] = None
    valueSetName: Union[str, ValueSetName] = None
    about: Union[URIorCURIE, ExternalURI] = None
    definitions: Dict[Union[str, ValueSetDefinitionReferenceName],
                      Union[dict, ValueSetDefinitionReference]] = empty_dict()
    currentDefinition: Optional[Union[dict,
                                      ValueSetDefinitionReference]] = None
    currentResolution: Optional[Union[URIorCURIE, RenderingURI]] = None
    releaseDocumentation: Optional[str] = None
    releaseFormat: List[Union[dict, SourceAndNotation]] = empty_list()

    def __post_init__(self, **kwargs: Dict[str, Any]):
        if self.id is None:
            raise ValueError(f"id must be supplied")
        if not isinstance(self.id, ValueSetCatalogEntryId):
            self.id = ValueSetCatalogEntryId(self.id)
        if self.valueSetName is None:
            raise ValueError(f"valueSetName must be supplied")
        if not isinstance(self.valueSetName, ValueSetName):
            self.valueSetName = ValueSetName(self.valueSetName)
        for k, v in self.definitions.items():
            if not isinstance(v, ValueSetDefinitionReference):
                self.definitions[k] = ValueSetDefinitionReference(
                    name=k, **({} if v is None else v))
        if self.currentDefinition is not None and not isinstance(
                self.currentDefinition, ValueSetDefinitionReference):
            self.currentDefinition = ValueSetDefinitionReference(
                self.currentDefinition)
        if self.currentResolution is not None and not isinstance(
                self.currentResolution, RenderingURI):
            self.currentResolution = RenderingURI(self.currentResolution)
        self.releaseFormat = [SourceAndNotation(*e) for e in self.releaseFormat.items()] if isinstance(self.releaseFormat, dict) \
                              else [v if isinstance(v, SourceAndNotation) else SourceAndNotation(**v)
                                    for v in ([self.releaseFormat] if isinstance(self.releaseFormat, str) else self.releaseFormat)]
        super().__post_init__(**kwargs)
コード例 #9
0
ファイル: issue_355.py プロジェクト: blokzincirdev/biolinkml
class Container(YAMLRoot):
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = SCT.Container
    class_class_curie: ClassVar[str] = "sct:Container"
    class_name: ClassVar[str] = "container"
    class_model_uri: ClassVar[URIRef] = SCT.Container

    entry: Optional[Union[Dict[Union[str, ContaineeId], Union[dict,
                                                              "Containee"]],
                          List[Union[dict, "Containee"]]]] = empty_dict()

    def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
        if self.entry is None:
            self.entry = []
        if not isinstance(self.entry, (list, dict)):
            self.entry = [self.entry]
        self._normalize_inlined_slot(slot_name="entry",
                                     slot_type=Containee,
                                     key_name="id",
                                     inlined_as_list=None,
                                     keyed=True)

        super().__post_init__(**kwargs)
コード例 #10
0
class MapVersion(YAMLRoot):
    """
    A specific version of a Map. MapVersion is bound to specific code system versions and/or value set
    versions andreferences a set of mapping entries (mapSet) that, if the resource is FINAL, are fixed with respect
    to this version.
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = TCCM.MapVersion
    class_class_curie: ClassVar[str] = "tccm:MapVersion"
    class_name: ClassVar[str] = "MapVersion"
    class_model_uri: ClassVar[URIRef] = TCCM.MapVersion

    mapVersionName: Union[str, MapVersionName]
    versionOf: Union[dict, MapReference]
    fromValueSetDefinition: Union[dict, ValueSetDefinitionReference]
    toValueSetDefinition: Union[dict, ValueSetDefinitionReference]
    fromCodeSystemVersion: Optional[Union[dict,
                                          CodeSystemVersionReference]] = None
    toCodeSystemVersion: Optional[Union[dict,
                                        CodeSystemVersionReference]] = None
    useCodeSystemVersion: Dict[
        Union[str, CodeSystemVersionReferenceName],
        Union[dict, CodeSystemVersionReference]] = empty_dict()
    applicableContext: Dict[Union[str, ContextReferenceName],
                            Union[dict, ContextReference]] = empty_dict()
    versionTag: Dict[Union[str, VersionTagReferenceName],
                     Union[dict, VersionTagReference]] = empty_dict()

    def __post_init__(self, **kwargs: Dict[str, Any]):
        if self.mapVersionName is None:
            raise ValueError(f"mapVersionName must be supplied")
        if not isinstance(self.mapVersionName, MapVersionName):
            self.mapVersionName = MapVersionName(self.mapVersionName)
        if self.versionOf is None:
            raise ValueError(f"versionOf must be supplied")
        if not isinstance(self.versionOf, MapReference):
            self.versionOf = MapReference(self.versionOf)
        if self.fromValueSetDefinition is None:
            raise ValueError(f"fromValueSetDefinition must be supplied")
        if not isinstance(self.fromValueSetDefinition,
                          ValueSetDefinitionReference):
            self.fromValueSetDefinition = ValueSetDefinitionReference(
                self.fromValueSetDefinition)
        if self.fromCodeSystemVersion is not None and not isinstance(
                self.fromCodeSystemVersion, CodeSystemVersionReference):
            self.fromCodeSystemVersion = CodeSystemVersionReference(
                self.fromCodeSystemVersion)
        if self.toValueSetDefinition is None:
            raise ValueError(f"toValueSetDefinition must be supplied")
        if not isinstance(self.toValueSetDefinition,
                          ValueSetDefinitionReference):
            self.toValueSetDefinition = ValueSetDefinitionReference(
                self.toValueSetDefinition)
        if self.toCodeSystemVersion is not None and not isinstance(
                self.toCodeSystemVersion, CodeSystemVersionReference):
            self.toCodeSystemVersion = CodeSystemVersionReference(
                self.toCodeSystemVersion)
        for k, v in self.useCodeSystemVersion.items():
            if not isinstance(v, CodeSystemVersionReference):
                self.useCodeSystemVersion[k] = CodeSystemVersionReference(
                    name=k, **({} if v is None else v))
        for k, v in self.applicableContext.items():
            if not isinstance(v, ContextReference):
                self.applicableContext[k] = ContextReference(
                    name=k, **({} if v is None else v))
        for k, v in self.versionTag.items():
            if not isinstance(v, VersionTagReference):
                self.versionTag[k] = VersionTagReference(
                    name=k, **({} if v is None else v))
        super().__post_init__(**kwargs)
コード例 #11
0
class ValueSetDefinition(ResourceVersionDescription):
    """
    A ValueSetDefinition describes the rules that determine which entity references (value meanings) belong to a
    value set at a given point in time. The definition of what belongs in a value set can evolve over time, and it
    is possible for there to be multiple definitions active at any given point in time - perhaps one for a system
    in general use, a second for a newer system, and a third for testing. A ValueSetDefinition may or may not
    identify a specific version of a code system. The decision of which version is to be used depends on the context
    and needs of the community. ValueSetDefinition and the supporting model has been designed to allow multiple
    variations on the “binding” of definitions to value sets, code system versions to definitions, and the
    combination to concept domains.
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = TCCM.ValueSetDefinition
    class_class_curie: ClassVar[str] = "tccm:ValueSetDefinition"
    class_name: ClassVar[str] = "ValueSetDefinition"
    class_model_uri: ClassVar[URIRef] = TCCM.ValueSetDefinition

    id: Union[str, ValueSetDefinitionId] = None
    about: Union[URIorCURIE, ExternalURI] = None
    entry: List[Union[dict, "ValueSetDefinitionEntry"]] = empty_list()
    definitionOf: Optional[Union[dict, ValueSetReference]] = None
    versionTag: Dict[Union[str, VersionTagReferenceName], Union[dict, VersionTagReference]] = empty_dict()

    def __post_init__(self, **kwargs: Dict[str, Any]):
        if self.id is None:
            raise ValueError(f"id must be supplied")
        if not isinstance(self.id, ValueSetDefinitionId):
            self.id = ValueSetDefinitionId(self.id)
        if self.definitionOf is not None and not isinstance(self.definitionOf, ValueSetReference):
            self.definitionOf = ValueSetReference(self.definitionOf)
        for k, v in self.versionTag.items():
            if not isinstance(v, VersionTagReference):
                self.versionTag[k] = VersionTagReference(name=k, **({} if v is None else v))
        if not isinstance(self.entry, list) or len(self.entry) == 0:
            raise ValueError(f"entry must be a non-empty list")
        self.entry = [ValueSetDefinitionEntry(*e) for e in self.entry.items()] if isinstance(self.entry, dict) \
                      else [v if isinstance(v, ValueSetDefinitionEntry) else ValueSetDefinitionEntry(**v)
                            for v in ([self.entry] if isinstance(self.entry, str) else self.entry)]
        super().__post_init__(**kwargs)
コード例 #12
0
class Element(YAMLRoot):
    """
    a named element in the model
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = META.Element
    class_class_curie: ClassVar[str] = "meta:Element"
    class_name: ClassVar[str] = "element"
    class_model_uri: ClassVar[URIRef] = META.Element

    name: Union[str, ElementName]
    id_prefixes: List[Union[str, NCName]] = empty_list()
    definition_uri: Optional[Union[str, URIorCURIE]] = None
    aliases: List[str] = empty_list()
    local_names: Union[dict, "LocalName"] = empty_dict()
    mappings: List[Union[str, URIorCURIE]] = empty_list()
    description: Optional[str] = None
    alt_descriptions: Union[dict, "AltDescription"] = empty_dict()
    deprecated: Optional[str] = None
    todos: List[str] = empty_list()
    notes: List[str] = empty_list()
    comments: List[str] = empty_list()
    examples: List[Union[dict, "Example"]] = empty_list()
    in_subset: List[Union[str, SubsetDefinitionName]] = empty_list()
    from_schema: Optional[Union[str, URI]] = None
    imported_from: Optional[str] = None
    see_also: List[Union[str, URIorCURIE]] = empty_list()
    exact_mappings: List[Union[str, URIorCURIE]] = empty_list()
    close_mappings: List[Union[str, URIorCURIE]] = empty_list()
    related_mappings: List[Union[str, URIorCURIE]] = empty_list()
    narrow_mappings: List[Union[str, URIorCURIE]] = empty_list()
    broad_mappings: List[Union[str, URIorCURIE]] = empty_list()
    deprecated_element_has_exact_replacement: Optional[Union[str, URIorCURIE]] = None
    deprecated_element_has_possible_replacement: Optional[Union[str, URIorCURIE]] = None
    extensions: List[Union[dict, Extension]] = empty_list()
    annotations: List[Union[dict, Annotation]] = empty_list()

    def __post_init__(self, **kwargs: Dict[str, Any]):
        self.id_prefixes = [v if isinstance(v, NCName)
                            else NCName(v) for v in ([self.id_prefixes] if isinstance(self.id_prefixes, str) else self.id_prefixes)]
        if self.name is None:
            raise ValueError(f"name must be supplied")
        if not isinstance(self.name, ElementName):
            self.name = ElementName(self.name)
        if self.definition_uri is not None and not isinstance(self.definition_uri, URIorCURIE):
            self.definition_uri = URIorCURIE(self.definition_uri)
        for k, v in self.local_names.items():
            if not isinstance(v, LocalName):
                self.local_names[k] = LocalName(k, v)
        self.mappings = [v if isinstance(v, URIorCURIE)
                         else URIorCURIE(v) for v in ([self.mappings] if isinstance(self.mappings, str) else self.mappings)]
        for k, v in self.alt_descriptions.items():
            if not isinstance(v, AltDescription):
                self.alt_descriptions[k] = AltDescription(k, v)
        self.examples = [Example(*e) for e in self.examples.items()] if isinstance(self.examples, dict) \
                         else [v if isinstance(v, Example) else Example(**v)
                               for v in ([self.examples] if isinstance(self.examples, str) else self.examples)]
        self.in_subset = [v if isinstance(v, SubsetDefinitionName)
                          else SubsetDefinitionName(v) for v in ([self.in_subset] if isinstance(self.in_subset, str) else self.in_subset)]
        if self.from_schema is not None and not isinstance(self.from_schema, URI):
            self.from_schema = URI(self.from_schema)
        self.see_also = [v if isinstance(v, URIorCURIE)
                         else URIorCURIE(v) for v in ([self.see_also] if isinstance(self.see_also, str) else self.see_also)]
        self.exact_mappings = [v if isinstance(v, URIorCURIE)
                               else URIorCURIE(v) for v in ([self.exact_mappings] if isinstance(self.exact_mappings, str) else self.exact_mappings)]
        self.close_mappings = [v if isinstance(v, URIorCURIE)
                               else URIorCURIE(v) for v in ([self.close_mappings] if isinstance(self.close_mappings, str) else self.close_mappings)]
        self.related_mappings = [v if isinstance(v, URIorCURIE)
                                 else URIorCURIE(v) for v in ([self.related_mappings] if isinstance(self.related_mappings, str) else self.related_mappings)]
        self.narrow_mappings = [v if isinstance(v, URIorCURIE)
                                else URIorCURIE(v) for v in ([self.narrow_mappings] if isinstance(self.narrow_mappings, str) else self.narrow_mappings)]
        self.broad_mappings = [v if isinstance(v, URIorCURIE)
                               else URIorCURIE(v) for v in ([self.broad_mappings] if isinstance(self.broad_mappings, str) else self.broad_mappings)]
        if self.deprecated_element_has_exact_replacement is not None and not isinstance(self.deprecated_element_has_exact_replacement, URIorCURIE):
            self.deprecated_element_has_exact_replacement = URIorCURIE(self.deprecated_element_has_exact_replacement)
        if self.deprecated_element_has_possible_replacement is not None and not isinstance(self.deprecated_element_has_possible_replacement, URIorCURIE):
            self.deprecated_element_has_possible_replacement = URIorCURIE(self.deprecated_element_has_possible_replacement)
        self.extensions = [Extension(*e) for e in self.extensions.items()] if isinstance(self.extensions, dict) \
                           else [v if isinstance(v, Extension) else Extension(**v)
                                 for v in ([self.extensions] if isinstance(self.extensions, str) else self.extensions)]
        self.annotations = [Annotation(*e) for e in self.annotations.items()] if isinstance(self.annotations, dict) \
                            else [v if isinstance(v, Annotation) else Annotation(**v)
                                  for v in ([self.annotations] if isinstance(self.annotations, str) else self.annotations)]
        super().__post_init__(**kwargs)
コード例 #13
0
class SlotDefinition(Definition):
    """
    the definition of a property or a slot
    """
    _inherited_slots: ClassVar[List[str]] = [
        "domain", "range", "multivalued", "inherited", "readonly", "ifabsent",
        "required", "inlined", "key", "identifier"
    ]

    # === element ===
    name: Union[str, SlotDefinitionName] = None
    id_prefixes: List[Union[str, NCName]] = empty_list()
    aliases: List[str] = empty_list()
    local_names: Union[dict, "LocalName"] = empty_dict()
    mappings: List[Union[str, URIorCURIE]] = empty_list()
    description: Optional[str] = None
    alt_descriptions: Union[dict, "AltDescription"] = empty_dict()
    deprecated: Optional[str] = None
    todos: List[str] = empty_list()
    notes: List[str] = empty_list()
    comments: List[str] = empty_list()
    examples: List[Union[dict, "Example"]] = empty_list()
    in_subset: List[Union[str, SubsetDefinitionName]] = empty_list()
    from_schema: Optional[Union[str, URI]] = None
    imported_from: Optional[str] = None
    see_also: List[Union[str, URIorCURIE]] = empty_list()

    # === definition ===
    abstract: Optional[Bool] = None
    mixin: Optional[Bool] = None
    values_from: List[Union[str, URIorCURIE]] = empty_list()

    # === slot_definition ===
    domain: Union[str, ClassDefinitionName] = None
    is_a: Optional[Union[str, SlotDefinitionName]] = None
    mixins: List[Union[str, SlotDefinitionName]] = empty_list()
    apply_to: List[Union[str, SlotDefinitionName]] = empty_list()
    singular_name: Optional[str] = None
    range: Optional[Union[str, ElementName]] = None
    slot_uri: Optional[Union[str, URI]] = None
    multivalued: Optional[Bool] = None
    inherited: Optional[Bool] = None
    readonly: Optional[str] = None
    ifabsent: Optional[str] = None
    required: Optional[Bool] = None
    inlined: Optional[Bool] = None
    key: Optional[Bool] = None
    identifier: Optional[Bool] = None
    alias: Optional[str] = None
    subproperty_of: Optional[Union[str, URIorCURIE]] = None
    is_usage_slot: Optional[Bool] = None

    def _fix_elements(self):
        super()._fix_elements()
        if self.name is not None and not isinstance(self.name,
                                                    SlotDefinitionName):
            self.name = SlotDefinitionName(self.name)
        if self.is_a is not None and not isinstance(self.is_a,
                                                    SlotDefinitionName):
            self.is_a = SlotDefinitionName(self.is_a)
        self.mixins = [
            v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v)
            for v in self.mixins
        ]
        self.apply_to = [
            v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v)
            for v in self.apply_to
        ]
        if self.domain is not None and not isinstance(self.domain,
                                                      ClassDefinitionName):
            self.domain = ClassDefinitionName(self.domain)
        if self.range is not None and not isinstance(self.range, ElementName):
            self.range = ElementName(self.range)
        if self.slot_uri is not None and not isinstance(self.slot_uri, URI):
            self.slot_uri = URI(self.slot_uri)
        if self.subproperty_of is not None and not isinstance(
                self.subproperty_of, URIorCURIE):
            self.subproperty_of = URIorCURIE(self.subproperty_of)
コード例 #14
0
class SchemaDefinition(Element):
    """
    a collection of subset, type, slot and class definitions
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = META.SchemaDefinition
    class_class_curie: ClassVar[str] = "meta:SchemaDefinition"
    class_name: ClassVar[str] = "schema_definition"
    class_model_uri: ClassVar[URIRef] = META.SchemaDefinition

    name: Union[str, SchemaDefinitionName] = None
    id: Union[str, URI] = None
    title: Optional[str] = None
    version: Optional[str] = None
    imports: List[Union[str, URIorCURIE]] = empty_list()
    license: Optional[str] = None
    prefixes: Union[dict, "Prefix"] = empty_dict()
    emit_prefixes: List[Union[str, NCName]] = empty_list()
    default_curi_maps: List[str] = empty_list()
    default_prefix: Optional[str] = None
    default_range: Optional[Union[str, TypeDefinitionName]] = None
    subsets: Dict[Union[str, SubsetDefinitionName], Union[dict, "SubsetDefinition"]] = empty_dict()
    types: Dict[Union[str, TypeDefinitionName], Union[dict, "TypeDefinition"]] = empty_dict()
    slots: Dict[Union[str, SlotDefinitionName], Union[dict, "SlotDefinition"]] = empty_dict()
    classes: Dict[Union[str, ClassDefinitionName], Union[dict, "ClassDefinition"]] = empty_dict()
    metamodel_version: Optional[str] = None
    source_file: Optional[str] = None
    source_file_date: Optional[Union[str, XSDDateTime]] = None
    source_file_size: Optional[int] = None
    generation_date: Optional[Union[str, XSDDateTime]] = None

    def __post_init__(self, **kwargs: Dict[str, Any]):
        if self.default_prefix is None:
            self.default_prefix = sfx(str(self.id))
        if self.name is None:
            raise ValueError(f"name must be supplied")
        if not isinstance(self.name, SchemaDefinitionName):
            self.name = SchemaDefinitionName(self.name)
        if self.id is None:
            raise ValueError(f"id must be supplied")
        if not isinstance(self.id, URI):
            self.id = URI(self.id)
        self.imports = [v if isinstance(v, URIorCURIE)
                        else URIorCURIE(v) for v in ([self.imports] if isinstance(self.imports, str) else self.imports)]
        for k, v in self.prefixes.items():
            if not isinstance(v, Prefix):
                self.prefixes[k] = Prefix(k, v)
        self.emit_prefixes = [v if isinstance(v, NCName)
                              else NCName(v) for v in ([self.emit_prefixes] if isinstance(self.emit_prefixes, str) else self.emit_prefixes)]
        if self.default_range is not None and not isinstance(self.default_range, TypeDefinitionName):
            self.default_range = TypeDefinitionName(self.default_range)
        for k, v in self.subsets.items():
            if not isinstance(v, SubsetDefinition):
                self.subsets[k] = SubsetDefinition(name=k, **({} if v is None else v))
        for k, v in self.types.items():
            if not isinstance(v, TypeDefinition):
                self.types[k] = TypeDefinition(name=k, **({} if v is None else v))
        for k, v in self.slots.items():
            if not isinstance(v, SlotDefinition):
                self.slots[k] = SlotDefinition(name=k, **({} if v is None else v))
        for k, v in self.classes.items():
            if not isinstance(v, ClassDefinition):
                self.classes[k] = ClassDefinition(name=k, **({} if v is None else v))
        if self.source_file_date is not None and not isinstance(self.source_file_date, XSDDateTime):
            self.source_file_date = XSDDateTime(self.source_file_date)
        if self.generation_date is not None and not isinstance(self.generation_date, XSDDateTime):
            self.generation_date = XSDDateTime(self.generation_date)
        super().__post_init__(**kwargs)
コード例 #15
0
ファイル: termci_schema.py プロジェクト: jiaola/TermCI-model
class Package(YAMLRoot):
    """
    A collection of ConceptSystems
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = TERMCI.Package
    class_class_curie: ClassVar[str] = "termci:Package"
    class_name: ClassVar[str] = "Package"
    class_model_uri: ClassVar[URIRef] = TERMCI.Package

    system: Optional[Union[Dict[Union[str, ConceptSystemNamespace], Union[dict, ConceptSystem]], List[Union[dict, ConceptSystem]]]] = empty_dict()

    def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
        if self.system is None:
            self.system = []
        if not isinstance(self.system, (list)):
            self.system = [self.system]
        self._normalize_inlined_slot(slot_name="system", slot_type=ConceptSystem, key_name="namespace", inlined_as_list=True, keyed=True)

        super().__post_init__(**kwargs)
コード例 #16
0
ファイル: termci_schema.py プロジェクト: jiaola/TermCI-model
class ConceptSystem(YAMLRoot):
    """
    A terminological resource (ontology, classification scheme, concept system, etc.)
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = SKOS.ConceptScheme
    class_class_curie: ClassVar[str] = "skos:ConceptScheme"
    class_name: ClassVar[str] = "ConceptSystem"
    class_model_uri: ClassVar[URIRef] = TERMCI.ConceptSystem

    namespace: Union[str, ConceptSystemNamespace] = None
    prefix: str = None
    description: Optional[str] = None
    reference: Optional[Union[Union[str, URI], List[Union[str, URI]]]] = empty_list()
    root_concept: Optional[Union[Union[str, ConceptReferenceUri], List[Union[str, ConceptReferenceUri]]]] = empty_list()
    contents: Optional[Union[Dict[Union[str, ConceptReferenceUri], Union[dict, ConceptReference]], List[Union[dict, ConceptReference]]]] = empty_dict()

    def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
        if self.namespace is None:
            raise ValueError("namespace must be supplied")
        if not isinstance(self.namespace, ConceptSystemNamespace):
            self.namespace = ConceptSystemNamespace(self.namespace)

        if self.prefix is None:
            raise ValueError("prefix must be supplied")
        if not isinstance(self.prefix, str):
            self.prefix = str(self.prefix)

        if self.description is not None and not isinstance(self.description, str):
            self.description = str(self.description)

        if self.reference is None:
            self.reference = []
        if not isinstance(self.reference, list):
            self.reference = [self.reference]
        self.reference = [v if isinstance(v, URI) else URI(v) for v in self.reference]

        if self.root_concept is None:
            self.root_concept = []
        if not isinstance(self.root_concept, list):
            self.root_concept = [self.root_concept]
        self.root_concept = [v if isinstance(v, ConceptReferenceUri) else ConceptReferenceUri(v) for v in self.root_concept]

        if self.contents is None:
            self.contents = []
        if not isinstance(self.contents, (list)):
            self.contents = [self.contents]
        self._normalize_inlined_slot(slot_name="contents", slot_type=ConceptReference, key_name="uri", inlined_as_list=True, keyed=True)

        super().__post_init__(**kwargs)
コード例 #17
0
class SchemaDefinition(Element):
    """
    a collection of subset, type, slot and class definitions
    """
    _inherited_slots: ClassVar[List[str]] = []

    # === element ===
    name: Union[str, SchemaDefinitionName] = None
    id_prefixes: List[Union[str, NCName]] = empty_list()
    aliases: List[str] = empty_list()
    local_names: Union[dict, "LocalName"] = empty_dict()
    mappings: List[Union[str, URIorCURIE]] = empty_list()
    description: Optional[str] = None
    alt_descriptions: Union[dict, "AltDescription"] = empty_dict()
    deprecated: Optional[str] = None
    todos: List[str] = empty_list()
    notes: List[str] = empty_list()
    comments: List[str] = empty_list()
    examples: List[Union[dict, "Example"]] = empty_list()
    in_subset: List[Union[str, SubsetDefinitionName]] = empty_list()
    from_schema: Optional[Union[str, URI]] = None
    imported_from: Optional[str] = None
    see_also: List[Union[str, URIorCURIE]] = empty_list()

    # === schema_definition ===
    id: Union[str, URI] = None
    title: Optional[str] = None
    version: Optional[str] = None
    imports: List[Union[str, URI]] = empty_list()
    license: Optional[str] = None
    prefixes: Union[dict, "Prefix"] = empty_dict()
    emit_prefixes: List[Union[str, NCName]] = empty_list()
    default_curi_maps: List[str] = empty_list()
    default_prefix: Optional[str] = None
    default_range: Optional[Union[str, DefinitionName]] = None
    subsets: Dict[Union[str, SubsetDefinitionName],
                  Union[dict, "SubsetDefinition"]] = empty_dict()
    types: Dict[Union[str, TypeDefinitionName],
                Union[dict, "TypeDefinition"]] = empty_dict()
    slots: Dict[Union[str, SlotDefinitionName],
                Union[dict, "SlotDefinition"]] = empty_dict()
    classes: Dict[Union[str, ClassDefinitionName],
                  Union[dict, "ClassDefinition"]] = empty_dict()
    metamodel_version: Optional[str] = None
    source_file: Optional[str] = None
    source_file_date: Optional[Union[str, XSDDate]] = None
    source_file_size: Optional[int] = None
    generation_date: Optional[Union[str, XSDDate]] = None

    def _fix_elements(self):
        super()._fix_elements()
        if self.name is not None and not isinstance(self.name,
                                                    SchemaDefinitionName):
            self.name = SchemaDefinitionName(self.name)
        if self.id is not None and not isinstance(self.id, URI):
            self.id = URI(self.id)
        self.imports = [
            v if isinstance(v, URI) else URI(v) for v in self.imports
        ]
        for k, v in self.prefixes.items():
            if not isinstance(v, Prefix):
                self.prefixes[k] = Prefix(k, v)
        self.emit_prefixes = [
            v if isinstance(v, NCName) else NCName(v)
            for v in self.emit_prefixes
        ]
        if self.default_range is not None and not isinstance(
                self.default_range, DefinitionName):
            self.default_range = DefinitionName(self.default_range)
        for k, v in self.subsets.items():
            if not isinstance(v, SubsetDefinition):
                self.subsets[k] = SubsetDefinition(name=k,
                                                   **({} if v is None else v))
        for k, v in self.types.items():
            if not isinstance(v, TypeDefinition):
                self.types[k] = TypeDefinition(name=k,
                                               **({} if v is None else v))
        for k, v in self.slots.items():
            if not isinstance(v, SlotDefinition):
                self.slots[k] = SlotDefinition(name=k,
                                               **({} if v is None else v))
        for k, v in self.classes.items():
            if not isinstance(v, ClassDefinition):
                self.classes[k] = ClassDefinition(name=k,
                                                  **({} if v is None else v))
        if self.source_file_date is not None and not isinstance(
                self.source_file_date, XSDDate):
            self.source_file_date = XSDDate(self.source_file_date)
        if self.generation_date is not None and not isinstance(
                self.generation_date, XSDDate):
            self.generation_date = XSDDate(self.generation_date)
コード例 #18
0
class ClassDefinition(Definition):
    """
    the definition of a class or interface
    """
    _inherited_slots: ClassVar[List[str]] = ["defining_slots"]

    # === element ===
    name: Union[str, ClassDefinitionName] = None
    id_prefixes: List[Union[str, NCName]] = empty_list()
    aliases: List[str] = empty_list()
    local_names: Union[dict, "LocalName"] = empty_dict()
    mappings: List[Union[str, URIorCURIE]] = empty_list()
    description: Optional[str] = None
    alt_descriptions: Union[dict, "AltDescription"] = empty_dict()
    deprecated: Optional[str] = None
    todos: List[str] = empty_list()
    notes: List[str] = empty_list()
    comments: List[str] = empty_list()
    examples: List[Union[dict, "Example"]] = empty_list()
    in_subset: List[Union[str, SubsetDefinitionName]] = empty_list()
    from_schema: Optional[Union[str, URI]] = None
    imported_from: Optional[str] = None
    see_also: List[Union[str, URIorCURIE]] = empty_list()

    # === definition ===
    abstract: Optional[Bool] = None
    mixin: Optional[Bool] = None
    values_from: List[Union[str, URIorCURIE]] = empty_list()

    # === class_definition ===
    is_a: Optional[Union[str, ClassDefinitionName]] = None
    mixins: List[Union[str, ClassDefinitionName]] = empty_list()
    apply_to: List[Union[str, ClassDefinitionName]] = empty_list()
    slots: List[Union[str, SlotDefinitionName]] = empty_list()
    slot_usage: Dict[Union[str, SlotDefinitionName],
                     Union[dict, SlotDefinition]] = empty_dict()
    class_uri: Optional[Union[str, URIorCURIE]] = None
    subclass_of: Optional[Union[str, URIorCURIE]] = None
    defining_slots: List[Union[str, SlotDefinitionName]] = empty_list()

    def _fix_elements(self):
        super()._fix_elements()
        if self.name is not None and not isinstance(self.name,
                                                    ClassDefinitionName):
            self.name = ClassDefinitionName(self.name)
        if self.is_a is not None and not isinstance(self.is_a,
                                                    ClassDefinitionName):
            self.is_a = ClassDefinitionName(self.is_a)
        self.mixins = [
            v if isinstance(v, ClassDefinitionName) else ClassDefinitionName(v)
            for v in self.mixins
        ]
        self.apply_to = [
            v if isinstance(v, ClassDefinitionName) else ClassDefinitionName(v)
            for v in self.apply_to
        ]
        self.slots = [
            v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v)
            for v in self.slots
        ]
        for k, v in self.slot_usage.items():
            if not isinstance(v, SlotDefinition):
                self.slot_usage[k] = SlotDefinition(name=k,
                                                    **({} if v is None else v))
        if self.class_uri is not None and not isinstance(
                self.class_uri, URIorCURIE):
            self.class_uri = URIorCURIE(self.class_uri)
        if self.subclass_of is not None and not isinstance(
                self.subclass_of, URIorCURIE):
            self.subclass_of = URIorCURIE(self.subclass_of)
        self.defining_slots = [
            v if isinstance(v, SlotDefinitionName) else SlotDefinitionName(v)
            for v in self.defining_slots
        ]
コード例 #19
0
class EntityReferenceList(YAMLRoot):
    """
    A collection (set) of zero or more entity references that belong to the same scoping namespace
    """
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = TCCM.EntityReferenceList
    class_class_curie: ClassVar[str] = "tccm:EntityReferenceList"
    class_name: ClassVar[str] = "EntityReferenceList"
    class_model_uri: ClassVar[URIRef] = TCCM.EntityReferenceList

    namespaceURI: Union[URIorCURIE, EntityReferenceListNamespaceURI]
    namespaceName: Optional[Union[str, CodeSystemName]] = None
    entities: Dict[Union[str, EntityReferenceCode], Union[dict, "EntityReference"]] = empty_dict()

    def __post_init__(self, **kwargs: Dict[str, Any]):
        if self.namespaceURI is None:
            raise ValueError(f"namespaceURI must be supplied")
        if not isinstance(self.namespaceURI, EntityReferenceListNamespaceURI):
            self.namespaceURI = EntityReferenceListNamespaceURI(self.namespaceURI)
        if self.namespaceName is not None and not isinstance(self.namespaceName, CodeSystemName):
            self.namespaceName = CodeSystemName(self.namespaceName)
        for k, v in self.entities.items():
            if not isinstance(v, EntityReference):
                self.entities[k] = EntityReference(code=k, **({} if v is None else v))
        super().__post_init__(**kwargs)
コード例 #20
0
class SchemaSynopsis:
    schema: SchemaDefinition = field(repr=False, compare=False)

    # References by type -- set by add_ref
    typerefs: Dict[TypeDefinitionName, References] = empty_dict()       # Type name to all references
    slotrefs: Dict[SlotDefinitionName, References] = empty_dict()       # Slot name to all references
    classrefs: Dict[ClassDefinitionName, References] = empty_dict()     # Class name to all references
    subsetrefs: Dict[SubsetDefinitionName, References] = empty_dict()            # Subset name to references

    # Type specific
    typebases: Dict[str, Set[TypeDefinitionName]] = empty_dict()          # Base referencing types (direct and indirect)
    typeofs: Dict[TypeDefinitionName, TypeDefinitionName] = empty_dict()  # Type to specializations

    # Slot specific
    slotclasses: Dict[SlotDefinitionName, Set[ClassDefinitionName]] = empty_dict()    # Slot to including classes
    definingslots: Dict[SlotDefinitionName, Set[ClassDefinitionName]] = empty_dict()  # Slot to defining decls
    slotusages: Dict[SlotDefinitionName, Set[ClassDefinitionName]] = empty_dict()     # Slot to overriding classes
    owners: Dict[SlotDefinitionName, Set[ClassDefinitionName]] = empty_dict()         # Slot to owning classes (sb. 1)
    inverses: Dict[str, Set[str]] = empty_dict()                        # Slots declared as inverses of other slots

    # Class specific
    ownslots: Dict[ClassDefinitionName, Set[SlotDefinitionName]] = empty_dict() # Slots directly owned by class

    # Class to slot domains == class.slots

    # Slot or Class (Definition) specific
    roots: References = empty_references()                      # Definitions with no parents
    isarefs: Dict[DefinitionName, References] = empty_dict()    # Definition to isa references
    mixinrefs: Dict[DefinitionName, References] = empty_dict()  # Mixin to referencing classes or slots
    mixins: References = empty_references()                     # Definitions declared as mixin
    abstracts: References = empty_references()                  # Definitions declared as abstract
    applytos: References = empty_references()                   # Definitions that include applytos
    applytorefs: Dict[DefinitionName, References] = empty_dict()  # Definition to applyier

    # Slot or Type specific
    rangerefs: Dict[ElementName, Set[SlotDefinitionName]] = empty_dict()  # Type or class to range slot

    # Element - any type
    inschema: Dict[str, References] = empty_references()        # Schema name to elements

    def __post_init__(self):
        for k, v in self.schema.slots.items():
            self.summarize_slot_definition(k, v)
        for k, v in self.schema.types.items():
            self.summarize_type_definition(k, v)
        for k, v in self.schema.classes.items():
            self.summarize_class_definition(k, v)

        # Generate a list of slots owned exclusively by cls
        for cls in self.schema.classes.values():
            non_owned_slots = set()
            if cls.is_a:
                non_owned_slots = set(self.schema.classes[cls.is_a].slots)
            for mixin in cls.mixins:
                non_owned_slots.update(set(self.schema.classes[mixin].slots))
            owned_slots = set(cls.slots) - non_owned_slots
            self.ownslots[cls.name] = set(cls.slots) - non_owned_slots
            for slotname in owned_slots:
                self.owners.setdefault(slotname, set()).add(cls.name)


    def summarize_slot_definition(self, k: SlotDefinitionName, v: SlotDefinition) -> None:
        """
        Summarize a slot definition
        :param k: slot name
        :param v: slot definition
        :return:
        """
        self.summarize_definition(SlotType, k, v)
        if v.domain:
            self.add_ref(SlotType, k, ClassType, v.domain)
        self.rangerefs.setdefault(v.range, set()).add(k)
        self.add_ref(SlotType, k, ClassType if v.range in self.schema.classes else TypeType, v.range)

    def summarize_type_definition(self, k: TypeDefinitionName, v: TypeDefinition):
        """
        Summarize type definition

        :param k: Type name
        :param v: Type definition
        :return:
        """
        self.summarize_element(TypeType, k, v)
        if v.typeof:
            self.typeofs.setdefault(v.typeof, set()).add(k)
            self.add_ref(TypeType, k, TypeType, v.typeof)
        if v.base:
            self.typebases.setdefault(v.base, set()).add(k)

    def summarize_class_definition(self, k: ClassDefinitionName, v: ClassDefinition) -> None:
        """
        Summarize class definition element

        :param k: Class name
        :param v: Class definition
        :return:
        """
        self.summarize_definition(ClassType, k, v)
        for slotname in v.slots:
            self.add_ref(ClassType, k, SlotType, slotname)
        for slotname, usage in v.slot_usage.items():
            self.slotusages.setdefault(slotname, set()).add(k)
            self.add_ref(ClassType, k, SlotType, slotname)
            slot_alias = self.schema.slots[slotname].alias
            if slot_alias:
                self.add_ref(SlotType, slotname, SlotType, cast(SlotDefinitionName, slot_alias))
                self.add_ref(ClassType, k, SlotType, cast(SlotDefinitionName, slot_alias))

    def summarize_definition(self, typ: RefType, k: DefinitionName, v: Definition) -> None:
        """
        Summarize slot and class definitions

        :param typ: type (slot or class)
        :param k: name
        :param v: definition
        :return:
        """
        self.summarize_element(typ, k, v)
        if v.is_a:
            self.isarefs.setdefault(v.is_a, References()).addref(typ, k)
            self.add_ref(typ, k, typ, v.is_a)
        else:
            self.roots.addref(typ, k)
        if v.abstract:
            self.abstracts.addref(typ, k)
        if v.mixin:
            self.mixins.addref(typ, k)
        for mixin in v.mixins:
            self.mixinrefs.setdefault(mixin, References()).addref(typ, k)
            self.add_ref(typ, k, typ, mixin)
        if v.apply_to:
            self.applytos.addref(typ, k)
        for applyto in v.apply_to:
            self.applytorefs.setdefault(applyto, References()).addref(typ, k)
            self.add_ref(typ, k, typ, applyto)

    def summarize_element(self, typ: RefType, k: ElementName, v: Element) -> None:
        """
         Summarize element level items

        :param typ: element type
        :param k: element name
        :param v: element deffinition
        :return:
        """
        if k != v.name:
            raise ValueError("{typ} name mismatch: {k} != {v.name}")        # should never happen
        for subset in v.in_subset:
            self.add_ref(typ, k, SubsetType, subset)

    def add_ref(self, fromtype: RefType, fromname: ElementName, totype: RefType, toname: ElementName, ) -> None:
        """ Add an inverse reference, indicating that to type/name is referenced by from type/name

        :param fromtype: Referencer type
        :param fromname: Referencer name
        :param totype: Referencee type
        :param toname: Referencee name
        :return:
        """
        if totype is ClassType:
            self.classrefs.setdefault(cast(ClassDefinitionName, toname), References()).addref(fromtype, fromname)
        elif totype is SlotType:
            self.slotrefs.setdefault(cast(SlotDefinitionName, toname), References()).addref(fromtype, fromname)
        elif totype is TypeType:
            self.typerefs.setdefault(cast(TypeDefinitionName, toname), References()).addref(fromtype, fromname)
        elif totype is SubsetType:
            self.subsetrefs.setdefault(cast(SubsetDefinitionName, toname), References()).addref(fromtype, fromname)
        else:
            raise TypeError("Unknown typ: {typ}")

    def _ancestor_is_owned(self, slot: SlotDefinition) -> bool:
        return bool(slot.is_a) and (slot.is_a in self.owners or self._ancestor_is_owned(self.schema.slots[slot.is_a]))

    def errors(self) -> List[str]:

        rval = []
        undefined_classes = set(self.classrefs.keys()) - set(self.schema.classes.keys())
        if undefined_classes:
            rval += [f"\tUndefined class references: {', '.join(undefined_classes)}"]
        undefined_slots = set(self.slotrefs.keys()) - set(self.schema.slots.keys())
        if undefined_slots:
            rval += [f"\tUndefined slot references: {', '.join(undefined_slots)}"]
        undefined_types = set(self.typerefs.keys()) - set(self.schema.types.keys())
        if undefined_types:
            rval += [f"\tUndefined type references: {', '.join(undefined_types)}"]
        undefined_subsets = set(self.subsetrefs.keys()) - set(self.schema.subsets.keys())
        if undefined_subsets:
            rval += [f"\tUndefined subset references: {', '.join(undefined_subsets)}"]

        # Look for slot domain / class slot mismatches
        for slotname, owners in self.owners.items():
            owners = list(owners)
            # if len(owners) > 1:
            #     owners_str = ', '.join(owners)
            #     rval += [f"\tSlot {slotname} has multiple owners: ({owners_str})"]
            real_owner = self.schema.slots[slotname].owner
            if real_owner is None or (real_owner != slotname and real_owner != owners[0]):
                rval += [f'\tSlot "{slotname}" owner ({self.schema.slots[slotname].owner}) does not match {owners[0]}']
        for slotname, slot in sorted(self.schema.slots.items(), key=lambda e: e[0]):
            if slotname not in self.owners:
                # Lack of ownership is no longer a sin
                # if not self._ancestor_is_owned(slot):
                #     rval += [f"\tSlot {slotname} has no owners"]
                pass
            else:
                owner = self.owners[slotname]
                if slot.domain and (slot.domain not in self.ownslots or slotname not in self.ownslots[slot.domain]):
                    rval += [f'\tDomain mismatch: slot "{slotname}" domain is: '
                            f'"{slot.domain}" class "{owner}" claims ownership']

        # Inlined slots must be multivalued (not a inviolable rule, but we make assumptions about this elsewhere in
        # the python generator
        for slot in self.schema.slots.values():
            if slot.inlined and not slot.multivalued and slot.identifier:
                rval += [f'\tSlot {slot.name} is declared inline but single valued']
        return rval

    def summary(self) -> str:

        def summarize_refs(refs: Dict[ElementName, References]) -> str:
            clsrefs, slotrefs, typerefs = set(), set(), set()
            if refs is not None:
                for cr in refs.values():
                    clsrefs.update(cr.classrefs)
                    slotrefs.update(cr.slotrefs)
                    typerefs.update(cr.typerefs)
            return f"\tReferenced by: {len(clsrefs)} classes, {len(slotrefs)} slots, {len(typerefs)} types "

        def recurse_types(typ: TypeDefinitionName, indent: str='\t\t\t') -> List[str]:
            rval = [f"{indent}{typ}" + (':' if typ in self.typeofs else '')]
            if typ in sorted(self.typeofs):
                for tr in sorted(self.typeofs[typ]):
                    rval += recurse_types(tr, indent + '\t')
            return rval

        rval = ['']
        rval += [f"Classes: {len(self.schema.classes.keys())}"]
        rval += [summarize_refs(self.classrefs)]

        rval += [f"\tRoot: {len(self.roots.classrefs)}"]
        leaves = set(self.classrefs.keys()) - set(self.isarefs.keys())
        rval += [f"\tLeaf: {len(leaves)}"]
        # Standalone ar classes that are both roots and leaves
        rval += [f"\tStandalone: {len(set(self.roots.classrefs).union(set(leaves)))}"]
        rval += [f"\tDeclared mixin: {len(self.mixins.classrefs)}"]
        undeclared_mixins = set(self.mixinrefs.keys())\
            .intersection(set(self.schema.classes.keys()) - set(self.mixins.classrefs))
        rval += [f"\tUndeclared mixin: {len(undeclared_mixins)}"]
        if undeclared_mixins:
            for udm in sorted(undeclared_mixins):
                rval += [f"\t\t{udm}"]
        rval += [f"\tAbstract: {len(self.abstracts.classrefs)}"]
        undefined_classes = set(self.classrefs.keys()) - set(self.schema.classes.keys())
        if undefined_classes:
            rval += [f"\tUndefined references: {', '.join(undefined_classes)}"]

        rval += ['']
        rval += [f"Slots: {len(self.schema.slots.keys())}"]
        rval += [summarize_refs(self.slotrefs)]
        rval += [f"\tRoot: {len(self.roots.slotrefs)}"]
        leaves = set(self.slotrefs.keys()) - set(self.isarefs.keys())
        rval += [f"\tLeaf: {len(leaves)}"]
        rval += [f"\tStandalone: {len(set(self.roots.classrefs).union(set(leaves)))}"]
        rval += [f"\tDeclared mixin: {len(self.mixins.slotrefs)}"]
        undeclared_mixins = set(self.mixinrefs.keys()) \
            .intersection(set(self.schema.slots.keys()) - set(self.mixins.slotrefs))
        rval += [f"\tUndeclared mixin: {len(undeclared_mixins)}"]
        if undeclared_mixins:
            for udm in sorted(undeclared_mixins):
                rval += [f"\t\t{udm}"]
        rval += [f"\tAbstract: {len(self.abstracts.slotrefs)}"]

        # Slots that are referenced but not defined
        undefined_slots = set(self.slotrefs.keys()) - set(self.schema.slots.keys())
        if undefined_slots:
            rval += [f"\tUndefined: {len(undefined_slots)}"]

        # Slots that are defined but do not (directly) occur in any class
        n_unreferenced_descendants: int = 0
        unowned_slots: Set[SlotDefinitionName] = set()
        for slotname, slot in sorted(self.schema.slots.items(), key=lambda e: e[0]):
            if slotname not in self.owners:
                if slot.domain:
                    if self._ancestor_is_owned(slot):
                        n_unreferenced_descendants += 1
                    else:
                        unowned_slots.add(slotname)
        if n_unreferenced_descendants:
            rval += [f"\tUnreferenced descendants of owned slots: {n_unreferenced_descendants}"]
        if unowned_slots:
            rval += [f"\t* Unowned slots: {', '.join(sorted(unowned_slots))}"]


        not_in_domain: Set[SlotDefinitionName] = set()
        domain_mismatches: Set[SlotDefinitionName] = set()
        unkdomains: Set[SlotDefinitionName] = set()
        emptydomains: Set[SlotDefinitionName] = set()

        for slot in self.schema.slots.values():
            if not slot.domain:
                emptydomains.add(slot.name)
            elif slot.domain in self.schema.classes:
                if slot.name in self.schema.classes[slot.domain].slots:
                    pass
                elif slot.name not in self.slotclasses:
                    not_in_domain.add(slot.name)
                else:
                    domain_mismatches.add(slot.name)
            else:
                unkdomains.add(f"{slot.name}: {slot.domain}")
        if not_in_domain:
            rval += [f"\tNot in domain: {len(not_in_domain)}"]
            rval += ["\t\tslot.name: slot.domain"]
            rval += ["\t\t---------  -----------"]
            for slotname in sorted(not_in_domain):
                rval.append(f'\t\t"{slotname}": "{self.schema.slots[slotname].domain}"')
        if domain_mismatches:
            rval += [f"\t\tMismatches: {len(domain_mismatches)}"]
            for slotname in sorted(domain_mismatches):
                rval.append(f'\t\t\tSlot: "{slotname}" declared domain: "{self.schema.slots[slotname].domain}" '
                            f'actual domain(s): {", ".join(self.slotclasses[slotname])}')
        if unkdomains:
            rval += [f"\t* Unknown domain: {', '.join(sorted(unkdomains))}"]
        if emptydomains:
            rval += [f"\tDomain unspecified: {len(emptydomains)}"]

        rval += ["\tRanges:"]
        rval += ["\t\tType:"]
        for rng, slots in sorted(self.rangerefs.items()):
            if rng in self.schema.types:
                rval += [f"\t\t\t{rng}: {len(slots)}"]
        rval += ["\t\tClass:"]
        for rng, slots in sorted(self.rangerefs.items()):
            if rng in self.schema.classes:
                rval += [f"\t\t\t{rng}: {len(slots)}"]
        unknowns = []
        for rng, slots in sorted(self.rangerefs.items()):
            if rng not in self.schema.types and rng not in self.schema.classes:
                unknowns += [f"\t\t\t{rng}: {len(slots)}"]
        if unknowns:
            rval += ["\t\tUnknown:"] + unknowns

        shared_class_slots = set(self.schema.classes.keys()).intersection(set(self.schema.slots.keys()))
        if shared_class_slots:
            rval += ["\nClasses and Slots with the same name:"]
            for ssc in sorted(shared_class_slots):
                rval += [f"\t{ssc}"]

        rval += ['']
        rval += [f"Types: {len(self.schema.types)}"]
        rval += [summarize_refs(self.typerefs)]
        rval += ["\tBases:"]
        for base in sorted(self.typebases.keys()):
            rval += [f"\t\t{base}:"]
            for typ in sorted(self.typebases[base]):
                if not self.schema.types[typ].typeof:
                    rval += recurse_types(typ)

        return '\n'.join(rval)
コード例 #21
0
ファイル: specimen.py プロジェクト: mbrush/ccdhmodel
class Specimen(Entity):
    _inherited_slots: ClassVar[List[str]] = []

    class_class_uri: ClassVar[URIRef] = SPECIMEN.Specimen
    class_class_curie: ClassVar[str] = "specimen:Specimen"
    class_name: ClassVar[str] = "Specimen"
    class_model_uri: ClassVar[URIRef] = SPECIMEN.Specimen

    id: Union[str, SpecimenId] = None
    identifier: List[Union[dict, Identifier]] = empty_list()
    description: Optional[Union[str, Literal]] = None
    specimen_type: Optional[Union[dict, Coding]] = None
    analyte_type: Optional[Union[dict, Coding]] = None
    associated_project: Optional[Union[dict, Project]] = None
    provided_by: Optional[Union[dict, Organization]] = None
    source_material_type: Optional[Union[dict, Coding]] = None
    derived_from_specimen: Dict[Union[str, SpecimenId], Union[dict, "Specimen"]] = empty_dict()
    derived_from_subject: Optional[Union[dict, PatientOrBiologicallyDerivedMaterial]] = None
    subject_diagnosis: Dict[Union[str, ConditionDiagnosisId], Union[dict, ConditionDiagnosis]] = empty_dict()
    creation: Optional[Union[dict, SpecimenCreationActivity]] = None
    processing: List[Union[dict, SpecimenProcessingActivity]] = empty_list()
    storage: Optional[Union[dict, SpecimenStorageActivity]] = None
    transport: Optional[Union[dict, SpecimenTransportActvity]] = None
    contained_in: Optional[Union[dict, SpecimenContainer]] = None
    current_weight: List[Union[dict, Quantity]] = empty_list()
    volume: List[Union[dict, Quantity]] = empty_list()
    dimensional_measure: Optional[Union[dict, DataContainer]] = None
    analyte_concentration: Optional[Union[dict, Quantity]] = None
    analyte_concentration_method: Optional[Union[dict, Coding]] = None
    cellular_composition: Optional[Union[dict, Coding]] = None
    compositional_measure: Optional[Union[dict, DataContainer]] = None
    specimen_quality_measure: List[Union[dict, DataContainer]] = empty_list()
    general_tissue_morphology: Optional[Union[dict, Coding]] = None
    specific_tissue_morphology: Optional[Union[dict, Coding]] = None
    morphology_pathologically_confirmed: Optional[Bool] = None
    related_document: Dict[Union[str, DocumentReferenceId], Union[dict, DocumentReference]] = empty_dict()
    related_specimen: List[Union[dict, Relationship]] = empty_list()
    derived_product: List[Union[dict, BiologicallyDerivedProduct]] = empty_list()
    qualification_status_flag: Optional[Union[dict, Coding]] = None
    reference_status_flag: Optional[Bool] = None
    matched_normal_flag: List[Union[dict, Coding]] = empty_list()
    selected_normal_flag: Optional[Union[dict, Coding]] = None
    paired_specimen_genotype_match_flag: Optional[Union[dict, Coding]] = None
    source_body_structure: List[Union[dict, BodyStructure]] = empty_list()
    distance_from_paired_specimen: Optional[Union[str, Literal]] = None

    def __post_init__(self, **kwargs: Dict[str, Any]):
        if self.id is None:
            raise ValueError(f"id must be supplied")
        if not isinstance(self.id, SpecimenId):
            self.id = SpecimenId(self.id)
        self.identifier = [Identifier(*e) for e in self.identifier.items()] if isinstance(self.identifier, dict) \
                           else [v if isinstance(v, Identifier) else Identifier(**v)
                                 for v in ([self.identifier] if isinstance(self.identifier, str) else self.identifier)]
        if self.description is not None and not isinstance(self.description, Literal):
            self.description = Literal(self.description)
        if self.specimen_type is not None and not isinstance(self.specimen_type, Coding):
            self.specimen_type = Coding()
        if self.analyte_type is not None and not isinstance(self.analyte_type, Coding):
            self.analyte_type = Coding()
        if self.associated_project is not None and not isinstance(self.associated_project, Project):
            self.associated_project = Project(**self.associated_project)
        if self.provided_by is not None and not isinstance(self.provided_by, Organization):
            self.provided_by = Organization(**self.provided_by)
        if self.source_material_type is not None and not isinstance(self.source_material_type, Coding):
            self.source_material_type = Coding()
        for k, v in self.derived_from_specimen.items():
            if not isinstance(v, Specimen):
                self.derived_from_specimen[k] = Specimen(id=k, **({} if v is None else v))
        if self.derived_from_subject is not None and not isinstance(self.derived_from_subject, PatientOrBiologicallyDerivedMaterial):
            self.derived_from_subject = PatientOrBiologicallyDerivedMaterial()
        for k, v in self.subject_diagnosis.items():
            if not isinstance(v, ConditionDiagnosis):
                self.subject_diagnosis[k] = ConditionDiagnosis(id=k, **({} if v is None else v))
        if self.creation is not None and not isinstance(self.creation, SpecimenCreationActivity):
            self.creation = SpecimenCreationActivity()
        self.processing = [SpecimenProcessingActivity(*e) for e in self.processing.items()] if isinstance(self.processing, dict) \
                           else [v if isinstance(v, SpecimenProcessingActivity) else SpecimenProcessingActivity(**v)
                                 for v in ([self.processing] if isinstance(self.processing, str) else self.processing)]
        if self.storage is not None and not isinstance(self.storage, SpecimenStorageActivity):
            self.storage = SpecimenStorageActivity()
        if self.transport is not None and not isinstance(self.transport, SpecimenTransportActvity):
            self.transport = SpecimenTransportActvity()
        if self.contained_in is not None and not isinstance(self.contained_in, SpecimenContainer):
            self.contained_in = SpecimenContainer()
        self.current_weight = [Quantity(*e) for e in self.current_weight.items()] if isinstance(self.current_weight, dict) \
                               else [v if isinstance(v, Quantity) else Quantity(**v)
                                     for v in ([self.current_weight] if isinstance(self.current_weight, str) else self.current_weight)]
        self.volume = [Quantity(*e) for e in self.volume.items()] if isinstance(self.volume, dict) \
                       else [v if isinstance(v, Quantity) else Quantity(**v)
                             for v in ([self.volume] if isinstance(self.volume, str) else self.volume)]
        if self.dimensional_measure is not None and not isinstance(self.dimensional_measure, DataContainer):
            self.dimensional_measure = DataContainer()
        if self.analyte_concentration is not None and not isinstance(self.analyte_concentration, Quantity):
            self.analyte_concentration = Quantity()
        if self.analyte_concentration_method is not None and not isinstance(self.analyte_concentration_method, Coding):
            self.analyte_concentration_method = Coding()
        if self.cellular_composition is not None and not isinstance(self.cellular_composition, Coding):
            self.cellular_composition = Coding()
        if self.compositional_measure is not None and not isinstance(self.compositional_measure, DataContainer):
            self.compositional_measure = DataContainer()
        self.specimen_quality_measure = [DataContainer(*e) for e in self.specimen_quality_measure.items()] if isinstance(self.specimen_quality_measure, dict) \
                                         else [v if isinstance(v, DataContainer) else DataContainer(**v)
                                               for v in ([self.specimen_quality_measure] if isinstance(self.specimen_quality_measure, str) else self.specimen_quality_measure)]
        if self.general_tissue_morphology is not None and not isinstance(self.general_tissue_morphology, Coding):
            self.general_tissue_morphology = Coding()
        if self.specific_tissue_morphology is not None and not isinstance(self.specific_tissue_morphology, Coding):
            self.specific_tissue_morphology = Coding()
        for k, v in self.related_document.items():
            if not isinstance(v, DocumentReference):
                self.related_document[k] = DocumentReference(id=k, **({} if v is None else v))
        self.related_specimen = [Relationship(*e) for e in self.related_specimen.items()] if isinstance(self.related_specimen, dict) \
                                 else [v if isinstance(v, Relationship) else Relationship(**v)
                                       for v in ([self.related_specimen] if isinstance(self.related_specimen, str) else self.related_specimen)]
        self.derived_product = [BiologicallyDerivedProduct(*e) for e in self.derived_product.items()] if isinstance(self.derived_product, dict) \
                                else [v if isinstance(v, BiologicallyDerivedProduct) else BiologicallyDerivedProduct(**v)
                                      for v in ([self.derived_product] if isinstance(self.derived_product, str) else self.derived_product)]
        if self.qualification_status_flag is not None and not isinstance(self.qualification_status_flag, Coding):
            self.qualification_status_flag = Coding()
        self.matched_normal_flag = [Coding(*e) for e in self.matched_normal_flag.items()] if isinstance(self.matched_normal_flag, dict) \
                                    else [v if isinstance(v, Coding) else Coding(**v)
                                          for v in ([self.matched_normal_flag] if isinstance(self.matched_normal_flag, str) else self.matched_normal_flag)]
        if self.selected_normal_flag is not None and not isinstance(self.selected_normal_flag, Coding):
            self.selected_normal_flag = Coding()
        if self.paired_specimen_genotype_match_flag is not None and not isinstance(self.paired_specimen_genotype_match_flag, Coding):
            self.paired_specimen_genotype_match_flag = Coding()
        self.source_body_structure = [BodyStructure(*e) for e in self.source_body_structure.items()] if isinstance(self.source_body_structure, dict) \
                                      else [v if isinstance(v, BodyStructure) else BodyStructure(**v)
                                            for v in ([self.source_body_structure] if isinstance(self.source_body_structure, str) else self.source_body_structure)]
        if self.distance_from_paired_specimen is not None and not isinstance(self.distance_from_paired_specimen, Literal):
            self.distance_from_paired_specimen = Literal(self.distance_from_paired_specimen)
        super().__post_init__(**kwargs)