{% extends "prose.html" %}

{% block title %}Related{% endblock %}

{% macro render_circle(value) -%}
    {{ schema_status_map[value] }}
{% endmacro %}

{% macro registry_field_dl(cls, key) -%}
    {% set field = cls.__fields__[key].field_info %}
    <dt>{{ field.title or key.replace("_", " ").title() }}</dt>
    <dd>{{ field.description }}</dd>
{% endmacro %}

{% block styles %}
    {{ super() }}
    <!-- DataTables, see: https://datatables.net/examples/styling/bootstrap4.html-->
    <link
            rel="stylesheet"
            href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css"
    />
{% endblock %}

{% block scripts %}
    {{ super() }}
    <!-- DataTables, see: https://datatables.net/examples/styling/bootstrap4.html-->
    <script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
    <script>
        $(document).ready(function () {
            $("#comparison-datamodel").DataTable({
                scrollX: true,
                paging: false,
                "order": [[1, "desc"]]
            });
            $("#comparison-capabilities").DataTable({
                scrollX: true,
                paging: false
            });
            $("#comparison-governance").DataTable({
                scrollX: true,
                paging: false
            });
        });
    </script>
{% endblock %}

{% block content %}
    <h2>Comparison of Registries</h2>
    <p>
        An overview on registries covering biomedical ontologies, controlled vocabularies, and databases.
    </p>
    <h3>Data Models</h3>
    <p>
        A {{ schema_status_map[True] }} means the field is required. A {{ schema_status_map["present"] }} means it is
        part of the schema, but not required or incomplete on some entries. A {{ schema_status_map[False] }} means that
        it is not part of the metadata schema. For lookup services like the OLS, some fields (i.e.,&nbsp;Example ID,
        Default Provider, Alternate Providers) are omitted because inclusion would be redundant.
    </p>
    <p>
        <b>Caveats:</b> Several of Wikidata's fields can be accessed indirectly with alternative SPARQL queries.
        BioPortal's data is locked behind an API that requires a key and has rate limited access. The Crop Ontology
        Curation Tool does not list homepages because it is the homepage itself. Non-english language registries in the
        OntoPortal Alliance were not included.
    </p>
    <table id="comparison-datamodel" class="table table-striped table-hover table-sm">
        <thead>
        <tr>
            <th>Registry</th>
            <th>Score</th>
            <th>Name</th>
            <th>Homepage</th>
            <th>Description</th>
            <th>Example</th>
            <th>Pattern</th>
            <th>Provider</th>
            <th>Alternate Providers</th>
            <th>Alternate Prefixes</th>
            <th>License</th>
            <th>Version</th>
            <th>Contact</th>
        </tr>
        </thead>
        <tbody>
        {% for registry in registries %}
            <tr>
                <td>
                    <a href="{{ url_for('ui.metaresource', metaprefix=registry.prefix) }}">{{ registry.get_short_name() }}</a>
                </td>
                <td style="text-align: right;">{{ registry.score() }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.name) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.homepage) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.description) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.example) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.pattern) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.provider) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.alternate_providers) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.synonyms) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.license) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.version) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.contact) }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>

    <h3>Capabilities</h3>
    <p>
        This section provides a systematic evaluation and comparison of
        the capabilities of each registry.
    </p>
    <dl>
        {{ registry_field_dl(registry_schema_cls, "fair") }}
        {{ registry_field_dl(registry_schema_cls, "search") }}
        <dt>Provider</dt>
        <dd>
            The registry provides information about its own prefixes either
            in the form of a web page or an API endpoint. These can be accessed
            through a stable URL into wich a prefix can be formatted.
        </dd>
        <dt>Resolver</dt>
        <dd>
            The registry can act as a resolver, i.e., it redirects to an external
            page about a given biomedical concept or entity based on its CURIE and
            the registry's internal metadata data about the prefix's associated
            URI format string.
        </dd>
        <dt>Lookup</dt>
        <dd>
            The registry can act as a lookup service, i.e., it gives information
            about a given biomedical concept or entity based on its CURIE.
        </dd>
    </dl>
    <table id="comparison-capabilities" class="table table-striped table-hover table-sm">
        <thead>
        <tr>
            <th>Registry</th>
            <th>FAIR</th>
            <th>Search</th>
            <th>Provider</th>
            <th>Resolver</th>
            <th>Lookup</th>
        </tr>
        </thead>
        <tbody>
        {% for registry in registries %}
            <tr>
                <td>
                    <a href="{{ url_for('ui.metaresource', metaprefix=registry.prefix) }}">{{ registry.get_short_name() }}</a>
                </td>
                <td style="text-align: center;">{{ render_circle(registry.availability.fair) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.search) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.provider_uri_format is not none) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.resolver_uri_format is not none and registry.resolver_type != "lookup") }}</td>
                <td style="text-align: center;">{{ render_circle(registry.resolver_uri_format is not none and registry.resolver_type == "lookup") }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>

    <h3>Governance</h3>
    <p>
        This section provides a systematic evaluation and comparison of
        the governance and standard operating procedures for each registry.
    </p>
    <dl>
        {{ registry_field_dl(registry_governance_cls, "accepts_external_contributions") }}
        {{ registry_field_dl(registry_governance_cls, "public_version_control") }}
        {{ registry_field_dl(registry_governance_cls, "review_team") }}
        {{ registry_field_dl(registry_governance_cls, "scope") }}
        {{ registry_field_dl(registry_governance_cls, "status") }}
    </dl>
    <table id="comparison-governance" class="table table-striped table-hover table-sm">
        <thead>
        <tr>
            <th>Registry</th>
            <th>Accepts External Contributions</th>
            <th>Public Version Control</th>
            <th>Review Team</th>
            <th>Scope</th>
            <th>Status</th>
        </tr>
        </thead>
        <tbody>
        {% for registry in registries %}
            <tr>
                <td>
                    <a href="{{ url_for('ui.metaresource', metaprefix=registry.prefix) }}">{{ registry.get_short_name() }}</a>
                </td>
                <td style="text-align: center;">{{ render_circle(registry.governance.accepts_external_contributions) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.governance.public_version_control) }}</td>
                <td>{{ registry.governance.review_team }}</td>
                <td>{{ registry.governance.scope }}</td>
                <td>{{ registry.governance.status }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>

    <h2>Related Software</h2>
    <h3>Conversion between CURIEs and IRIs</h3>
    <p>
        The semantic web and ontology communities are bound to the use of IRIs as identifiers and therefore are very
        interested in the interconversion between compact identifiers (i.e., CURIEs) and IRIs. While the Bioregistry
        provides many tools for one way conversion from CURIEs to IRIs, there are several related packages that help
        parse CURIEs from IRIs:
    </p>
    <ul>
        <li>
            The <a href="https://www.npmjs.com/package/@geneontology/dbxrefs">@geneontogy/dbxrefs</a> Node.js package
            translates CURIEs into URLs using the Gene Ontology Registry.
        </li>
        <li>
            The <a href="https://github.com/geneontology/curie-util-py">curie-util-py</a> Python package more generally
            loads JSON-LD files to convert between IRIs and CURIEs.
        </li>
    </ul>
{% endblock %}
