{% extends "prose.html" %}

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

{% macro render_circle(value, link=None) -%}
    {% if link %}
        <a href="{{ link }}">{{ schema_status_map[value] }}</a>
    {% else %}
        {{ schema_status_map[value] }}
    {% endif %}
{% endmacro %}

{% macro registry_field_dl(cls, key) -%}
    {% if is_pydantic_1 %}
        {% set field = cls.__fields__[key].field_info %}
        <dt>{{ field.title or key.replace("_", " ").title() }}</dt>
        <dd>{{ field.description }}</dd>
    {% else %}
        {% set field = cls.__fields__[key] %}
        <dt>{{ field.title or key.replace("_", " ").title() }}</dt>
        <dd>{{ field.description }}</dd>
    {% endif %}
{% 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>
    <dl>
        <dt>Data Model Score</dt>
        <dd>
            The weighted sum of green dots, less valuable yellow dots, and some negatively weighted red dots. Higher is
            better.
        </dd>
        {{ registry_field_dl(registry_schema_cls, "name") }}
        {{ registry_field_dl(registry_schema_cls, "homepage") }}
        {{ registry_field_dl(registry_schema_cls, "description") }}
        {{ registry_field_dl(registry_schema_cls, "example") }}
        {{ registry_field_dl(registry_schema_cls, "pattern") }}
        {{ registry_field_dl(registry_schema_cls, "provider") }}
        {{ registry_field_dl(registry_schema_cls, "alternate_providers") }}
        {{ registry_field_dl(registry_schema_cls, "synonyms") }}
        {{ registry_field_dl(registry_schema_cls, "license") }}
        {{ registry_field_dl(registry_schema_cls, "version") }}
        {{ registry_field_dl(registry_schema_cls, "contact") }}
    </dl>
    <table id="comparison-datamodel" class="table table-striped table-hover table-sm">
        <thead>
        <tr>
            <th>Registry</th>
            <th>Data Model 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('metaregistry_ui.metaresource', metaprefix=registry.prefix) }}">{{ registry.get_short_name() }}</a>
                </td>
                <td style="text-align: right;">{{ registry.availability.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>

    <p>
        <b>Notes:</b> Several of Wikidata's fields can be accessed indirectly with alternative SPARQL queries.
        Non-english language registries in the OntoPortal Alliance were not considered.
    </p>

    <h3>Capabilities and Qualities</h3>
    <p>
        This section provides a systematic evaluation and comparison of
        the capabilities of each registry.
    </p>
    <dl>
        <dt>Quality Score</dt>
        <dd>The sum of the number of green dots across each row.</dd>
        {{ registry_field_dl(registry_qualities_cls, "structured_data") }}
        {{ registry_field_dl(registry_qualities_cls, "bulk_data") }}
        {{ registry_field_dl(registry_qualities_cls, "no_authentication") }}
        {{ registry_field_dl(registry_qualities_cls, "automatable_download") }}
        <dt>Permissive License</dt>
        <dd>
            This field denotes if the registry uses a license that permits reuse and or remixing? Based on the OBO
            Foundry's <a href="https://obofoundry.org/principles/fp-001-open.html">FP-001 "openness" principle</a>, this
            includes Creative Commons CC BY 3.0, CC BY 4.0, and CC Zero. This explicitly does not include resources
            licensed with share-alike clauses, no derivatives clauses, or ones that are missing license statements
            entirely.
        </dd>
        {{ registry_field_dl(registry_schema_cls, "search") }}
        <dt>Prefix Provider</dt>
        <dd>
            This field denotes if 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 which a prefix from the registry can be formatted.
        </dd>
        <dt>CURIE Resolver</dt>
        <dd>
            This field denotes if 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>CURIE Lookup</dt>
        <dd>
            This field denotes if the registry 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>Mappings</th>
            <th>Quality Score</th>
            <th>Structured Data</th>
            <th>Bulk Data</th>
            <th>Requires Authentication</th>
            <th>Automatable Download</th>
            <th>Permissive License</th>
            <th>Prefix Search</th>
            <th>Prefix Provider</th>
            <th>CURIE Resolver</th>
            <th>CURIE Lookup</th>
        </tr>
        </thead>
        <tbody>
        {% for registry in registries %}
            <tr>
                <td>
                    <a href="{{ url_for('metaregistry_ui.metaresource', metaprefix=registry.prefix) }}">{{ registry.get_short_name() }}</a>
                </td>
                <td style="text-align: right;">{{ mapping_counts[registry.prefix] }}</td>
                <td style="text-align: right;">{{ registry.get_quality_score() }}</td>
                <td style="text-align: center;">{{ render_circle(registry.qualities.structured_data) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.qualities.bulk_data) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.qualities.no_authentication) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.qualities.automatable_download) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.has_permissive_license) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.availability.search) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.is_prefix_provider) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.is_resolver) }}</td>
                <td style="text-align: center;">{{ render_circle(registry.is_lookup) }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>

    <h3>Community and Governance</h3>
    <p>
        This section provides a systematic evaluation and comparison of
        the governance and standard operating procedures for each registry. We generated the following list of
        objective,
        measurable metrics:
    </p>
    <ul>
        <li>Are there clear, public policies on what content can be added to the registry?</li>
        <li>Are there clear, public policies on who is allowed to add content to the registry?</li>
        <li>
            Are there clear, public policies on why/how content is edited, deprecated, or removed from the registry?
        </li>
        <li>
            Are community members able to petition for updates to resources that they do not "own", for example, if
            there is a typo in the metadata?
        </li>
        <li>
            Does the community have clear, public policies for handling records that have been abandoned by the
            submitter/responsible person?
        </li>
        <li>
            Are there clear, public guidelines on how to contribute to the registry? We argue that open contribution,
            e.g., via a request in an issue tracker or directly by creating a pull
            request is better due to the ability to better engage other community members and stakeholders
        </li>
        <li>
            Does the registry make its data available under a data-appropriate, permissive, well-understood license
            (e.g., CC Zero or CC BY 4.0)?
        </li>
        <li>Does the registry make its underlying code open source under version control?</li>
        <li>
            Are there similar appropriate policies for the code with respect to contribution and moderation as
            previously described for the content of the registry?
        </li>
        <li>
            Does the community have a public issue tracker related to both curation and technical issues with the
            registry? A counter-example is that some communities require petitioning the moderator(s) privately by
            email.
        </li>
        <li>
            Are there clear, public, up-to-date resources listing who has the technical ability to make updates to the
            registry (i.e., the community moderator(s))?
        <li>
            Are the community moderators responsive on the issue tracker? This can be compared between communities using
            measurements like how many total issues are open on the tracker, how many have been unanswered by a
            moderator for more than a certain amount of time, how quickly issues are closed on average, etc.
        </li>
        <li>Is there a clear, public governance structure for inducting/removing community moderators?</li>
        <li>Are the moderators from heterogeneous institutions/scientific domains?</li>
        <li>
            Are contributions from the community attributed (both on a technical level, e.g., by associating ORCID
            identifiers to records, and also during scientific publication, e.g., as acknowledgments or including
            contributors as co-authors)?
        </li>
        <li>Does the community have a clear, public code of conduct?</li>
        <li>Do the moderators (or wider community) organize discussions, such as community meetings or workshops?</li>
    </ul>
    <p>
        We have made a survey of a subset of these questions which are presented in the table below, but, first, an
        explanation of each field is given.
    </p>
    <dl>
        <dt>Governance Score</dt>
        <dd>
            The sum of the following boolean fields and some additional logic. One point is deducted from registries
            with internal-focused scope.
        </dd>
        {{ registry_field_dl(registry_governance_cls, "accepts_external_contributions") }}
        {{ registry_field_dl(registry_governance_cls, "public_version_controlled_data") }}
        {{ registry_field_dl(registry_governance_cls, "issue_tracker") }}
        {{ 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>Score</th>
            <th>Accepts External Contributions</th>
            <th>Public Version-Controlled Data</th>
            <th>Issue Tracker</th>
            <th>Review Team</th>
            <th>Scope</th>
            <th>Status</th>
        </tr>
        </thead>
        <tbody>
        {% for registry in registries %}
            <tr>
                <td>
                    <a href="{{ url_for('metaregistry_ui.metaresource', metaprefix=registry.prefix) }}">{{ registry.get_short_name() }}</a>
                </td>
                <td style="text-align: right;">{{ registry.governance.score() }}</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_controlled_data, registry.governance.data_repository) }}</td>
                <td style="text-align: center;">
                    {% if registry.governance.issue_tracker %}
                        <a href="{{ registry.governance.issue_tracker }}">
                            <i class="fa fa-external-link" aria-hidden="true"></i>
                        </a>
                    {% endif %}
                </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 %}
