edc-reportable


Nameedc-reportable JSON
Version 2.0.2 PyPI version JSON
download
home_pagehttps://github.com/clinicedc/edc-reportable
SummaryReportable clinic events, reference ranges, grading for clinicedc/edc projects
upload_time2025-07-16 16:24:59
maintainerNone
docs_urlNone
authorErik van Widenfelt
requires_python>=3.12
licenseGPL license, see LICENSE
keywords django edc daids reference ranges normal ranges clinicedc clinical trials
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            |pypi| |actions| |codecov|

edc-reportable
--------------

Reportable clinic events, reference ranges, grading

Normal data is kept in model ``NormalData`` and grading data in ``GradingData``.

The two tables are populated by the ``post_migrate`` signal  ``post_migrate_load_reference_ranges``.

The post-migrate signal goes through all apps looking for ``reportables.py`` and loads according
to the attributes in the module.

A ``reportables.py`` might look like this:

.. code-block:: python

    from edc_reportable.data import africa, daids_july_2017

    collection_name = "meta"

    normal_data = africa.normal_data

    grading_data = {}
    grading_data.update(**daids_july_2017.dummies)
    grading_data.update(**daids_july_2017.chemistries)
    grading_data.update(**daids_july_2017.hematology)
    reportable_grades = [3, 4]
    reportable_grades_exceptions = {}

These attributes in ``reportables.py`` are required:

* collection_name
* normal_data
* grading_data
* reportable_grades
* reportable_grades_exceptions

When the post-migrate signal finds a module it calls ``load_reference_ranges``:

.. code-block:: python

    load_reference_ranges(
        reportables_module.collection_name,
        normal_data=reportables_module.normal_data,
        grading_data=reportables_module.grading_data,
        reportable_grades=reportables_module.reportable_grades,
        reportable_grades_exceptions=reportables_module.reportable_grades_exceptions,
    )

Normal data
===========

A normal reference is declared like this:

.. code-block:: python

    normal_data = {
        "albumin": [
            Formula(
                "3.5<=x<=5.0",
                units=GRAMS_PER_DECILITER,
                gender=[MALE, FEMALE],
                **adult_age_options,
            ),
        ],
        ...
    }

Add as many normal references in the dictionary as you like, just ensure the ``lower`` and ``upper`` boundaries don't overlap.

 **Note**: If the lower and upper values of a normal reference overlap
 with another normal reference in the same group, a ``BoundaryOverlap``
 exception will be raised when the value is evaluated.
 Catch this in your tests.

See ``edc_reportable.data.normal_data`` for a complete example.

Grading data
============

A grading reference is declared like this:

.. code-block:: python

    from edc_constants.constants import FEMALE, MALE
    from ...adult_age_options import adult_age_options
    from ...constants import HIGH_VALUE
    from ...units import IU_LITER

    grading_data = {
        amylase=[
            Formula(
                "1.1*ULN<=x<1.5*ULN",
                grade=1,
                units=IU_LITER,
                gender=[MALE, FEMALE],
                **adult_age_options,
            ),
            Formula(
                "1.5*ULN<=x<3.0*ULN",
                grade=2,
                units=IU_LITER,
                gender=[MALE, FEMALE],
                **adult_age_options,
            ),
            Formula(
                "3.0*ULN<=x<5.0*ULN",
                grade=3,
                units=IU_LITER,
                gender=[MALE, FEMALE],
                **adult_age_options,
            ),
            Formula(
                f"5.0*ULN<=x<{HIGH_VALUE}*ULN",
                grade=4,
                units=IU_LITER,
                gender=[MALE, FEMALE],
                **adult_age_options,
            ),
        ],
        ...
    }

Some references are not relative to LLN or ULN and are declared like this:

.. code-block:: python

    grading_data = {
        ldl=[
            Formula(
                "4.90<=x",
                grade=3,
                units=MILLIMOLES_PER_LITER,
                gender=[MALE, FEMALE],
                **adult_age_options,
                fasting=True,
            ),
        ],
        ...
    }


See ``edc_reportable.data.grading_data`` for a complete example.

 **Note**: If the lower and upper values of a grade reference overlap
 with another grade reference in the same group, a ``BoundaryOverlap``
 exception will be raised when the value is evaluated.
 Catch this in your tests.


**Important**:
 Writing out references is prone to error. It is better to declare a
 dictionary of normal references and grading references as shown above. Use the ``Formula`` class
 so that you can use a phrase like ``13.5<=x<=17.5`` instead of a listing attributes.

Attempting to grade a value without grading data
++++++++++++++++++++++++++++++++++++++++++++++++
If a value is pased to the evaluator and no grading data exists in the reference lists for
that test, an exception is raised.

Limiting what is "gradeable" for your project
+++++++++++++++++++++++++++++++++++++++++++++
The default tables have grading data for grades 1-4. The evaluator will grade any value
if there is grading data. You can prevent the evaluator from considering grades by passing
``reportable_grades`` when you register the normal and grading data.

For example, in your ``reportables.py``:

.. code-block:: python

    ...
    reportable_grades = [3, 4]
    ...

In the above, by explicitly passing a list of grades, the evaluator will only raise an
exception for grades 3 and 4. If a value meets the criteria for grade 1 or 2, it will be ignored.

Declaring minor exceptions
++++++++++++++++++++++++++

Minor exceptions can be specified using the parameter ``reportable_grades_exceptions``.
For example, you wish to report grades 2,3,4 for Serum Amylase
but grades 3,4 for everything else. You would register as follows:

.. code-block:: python

    ...
    reportable_grades_exceptions={"amylase": [GRADE2, GRADE3, GRADE4]}
    ...


Exporting the reference tables
++++++++++++++++++++++++++++++

You can export your declared references to CSV for further inspection using the management command

.. code-block:: python

    python manage.py export_reportables

    ('/Users/erikvw/my_project_normal_data.csv',
    '/Users/erikvw/my_project_grading_data.csv')

Check a normal value
====================


Check an abnormal value
=======================


Check if a value is "reportable"
================================


.. |pypi| image:: https://img.shields.io/pypi/v/edc-reportable.svg
    :target: https://pypi.python.org/pypi/edc-reportable

.. |actions| image:: https://github.com/clinicedc/edc-reportable/actions/workflows/build.yml/badge.svg
  :target: https://github.com/clinicedc/edc-reportable/actions/workflows/build.yml

.. |codecov| image:: https://codecov.io/gh/clinicedc/edc-reportable/branch/develop/graph/badge.svg
  :target: https://codecov.io/gh/clinicedc/edc-reportable

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/clinicedc/edc-reportable",
    "name": "edc-reportable",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "django, edc, DAIDS, reference ranges, normal ranges, clinicedc, clinical trials",
    "author": "Erik van Widenfelt",
    "author_email": "ew2789@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/74/4d/67dd196ad9af4afa2c67db3ca15e8ea88d09c231d8d68b9ce3335b0ecbbe/edc_reportable-2.0.2.tar.gz",
    "platform": null,
    "description": "|pypi| |actions| |codecov|\n\nedc-reportable\n--------------\n\nReportable clinic events, reference ranges, grading\n\nNormal data is kept in model ``NormalData`` and grading data in ``GradingData``.\n\nThe two tables are populated by the ``post_migrate`` signal  ``post_migrate_load_reference_ranges``.\n\nThe post-migrate signal goes through all apps looking for ``reportables.py`` and loads according\nto the attributes in the module.\n\nA ``reportables.py`` might look like this:\n\n.. code-block:: python\n\n    from edc_reportable.data import africa, daids_july_2017\n\n    collection_name = \"meta\"\n\n    normal_data = africa.normal_data\n\n    grading_data = {}\n    grading_data.update(**daids_july_2017.dummies)\n    grading_data.update(**daids_july_2017.chemistries)\n    grading_data.update(**daids_july_2017.hematology)\n    reportable_grades = [3, 4]\n    reportable_grades_exceptions = {}\n\nThese attributes in ``reportables.py`` are required:\n\n* collection_name\n* normal_data\n* grading_data\n* reportable_grades\n* reportable_grades_exceptions\n\nWhen the post-migrate signal finds a module it calls ``load_reference_ranges``:\n\n.. code-block:: python\n\n    load_reference_ranges(\n        reportables_module.collection_name,\n        normal_data=reportables_module.normal_data,\n        grading_data=reportables_module.grading_data,\n        reportable_grades=reportables_module.reportable_grades,\n        reportable_grades_exceptions=reportables_module.reportable_grades_exceptions,\n    )\n\nNormal data\n===========\n\nA normal reference is declared like this:\n\n.. code-block:: python\n\n    normal_data = {\n        \"albumin\": [\n            Formula(\n                \"3.5<=x<=5.0\",\n                units=GRAMS_PER_DECILITER,\n                gender=[MALE, FEMALE],\n                **adult_age_options,\n            ),\n        ],\n        ...\n    }\n\nAdd as many normal references in the dictionary as you like, just ensure the ``lower`` and ``upper`` boundaries don't overlap.\n\n **Note**: If the lower and upper values of a normal reference overlap\n with another normal reference in the same group, a ``BoundaryOverlap``\n exception will be raised when the value is evaluated.\n Catch this in your tests.\n\nSee ``edc_reportable.data.normal_data`` for a complete example.\n\nGrading data\n============\n\nA grading reference is declared like this:\n\n.. code-block:: python\n\n    from edc_constants.constants import FEMALE, MALE\n    from ...adult_age_options import adult_age_options\n    from ...constants import HIGH_VALUE\n    from ...units import IU_LITER\n\n    grading_data = {\n        amylase=[\n            Formula(\n                \"1.1*ULN<=x<1.5*ULN\",\n                grade=1,\n                units=IU_LITER,\n                gender=[MALE, FEMALE],\n                **adult_age_options,\n            ),\n            Formula(\n                \"1.5*ULN<=x<3.0*ULN\",\n                grade=2,\n                units=IU_LITER,\n                gender=[MALE, FEMALE],\n                **adult_age_options,\n            ),\n            Formula(\n                \"3.0*ULN<=x<5.0*ULN\",\n                grade=3,\n                units=IU_LITER,\n                gender=[MALE, FEMALE],\n                **adult_age_options,\n            ),\n            Formula(\n                f\"5.0*ULN<=x<{HIGH_VALUE}*ULN\",\n                grade=4,\n                units=IU_LITER,\n                gender=[MALE, FEMALE],\n                **adult_age_options,\n            ),\n        ],\n        ...\n    }\n\nSome references are not relative to LLN or ULN and are declared like this:\n\n.. code-block:: python\n\n    grading_data = {\n        ldl=[\n            Formula(\n                \"4.90<=x\",\n                grade=3,\n                units=MILLIMOLES_PER_LITER,\n                gender=[MALE, FEMALE],\n                **adult_age_options,\n                fasting=True,\n            ),\n        ],\n        ...\n    }\n\n\nSee ``edc_reportable.data.grading_data`` for a complete example.\n\n **Note**: If the lower and upper values of a grade reference overlap\n with another grade reference in the same group, a ``BoundaryOverlap``\n exception will be raised when the value is evaluated.\n Catch this in your tests.\n\n\n**Important**:\n Writing out references is prone to error. It is better to declare a\n dictionary of normal references and grading references as shown above. Use the ``Formula`` class\n so that you can use a phrase like ``13.5<=x<=17.5`` instead of a listing attributes.\n\nAttempting to grade a value without grading data\n++++++++++++++++++++++++++++++++++++++++++++++++\nIf a value is pased to the evaluator and no grading data exists in the reference lists for\nthat test, an exception is raised.\n\nLimiting what is \"gradeable\" for your project\n+++++++++++++++++++++++++++++++++++++++++++++\nThe default tables have grading data for grades 1-4. The evaluator will grade any value\nif there is grading data. You can prevent the evaluator from considering grades by passing\n``reportable_grades`` when you register the normal and grading data.\n\nFor example, in your ``reportables.py``:\n\n.. code-block:: python\n\n    ...\n    reportable_grades = [3, 4]\n    ...\n\nIn the above, by explicitly passing a list of grades, the evaluator will only raise an\nexception for grades 3 and 4. If a value meets the criteria for grade 1 or 2, it will be ignored.\n\nDeclaring minor exceptions\n++++++++++++++++++++++++++\n\nMinor exceptions can be specified using the parameter ``reportable_grades_exceptions``.\nFor example, you wish to report grades 2,3,4 for Serum Amylase\nbut grades 3,4 for everything else. You would register as follows:\n\n.. code-block:: python\n\n    ...\n    reportable_grades_exceptions={\"amylase\": [GRADE2, GRADE3, GRADE4]}\n    ...\n\n\nExporting the reference tables\n++++++++++++++++++++++++++++++\n\nYou can export your declared references to CSV for further inspection using the management command\n\n.. code-block:: python\n\n    python manage.py export_reportables\n\n    ('/Users/erikvw/my_project_normal_data.csv',\n    '/Users/erikvw/my_project_grading_data.csv')\n\nCheck a normal value\n====================\n\n\nCheck an abnormal value\n=======================\n\n\nCheck if a value is \"reportable\"\n================================\n\n\n.. |pypi| image:: https://img.shields.io/pypi/v/edc-reportable.svg\n    :target: https://pypi.python.org/pypi/edc-reportable\n\n.. |actions| image:: https://github.com/clinicedc/edc-reportable/actions/workflows/build.yml/badge.svg\n  :target: https://github.com/clinicedc/edc-reportable/actions/workflows/build.yml\n\n.. |codecov| image:: https://codecov.io/gh/clinicedc/edc-reportable/branch/develop/graph/badge.svg\n  :target: https://codecov.io/gh/clinicedc/edc-reportable\n",
    "bugtrack_url": null,
    "license": "GPL license, see LICENSE",
    "summary": "Reportable clinic events, reference ranges, grading for clinicedc/edc projects",
    "version": "2.0.2",
    "project_urls": {
        "Homepage": "https://github.com/clinicedc/edc-reportable"
    },
    "split_keywords": [
        "django",
        " edc",
        " daids",
        " reference ranges",
        " normal ranges",
        " clinicedc",
        " clinical trials"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "567be2d257e7bf7fe2a53816df735497fe7ce0571d0027f825e225aed40dbaa6",
                "md5": "a8241813f78e27ab343a34458c3250db",
                "sha256": "788725d9659e19a70b052c59e942711cac0627474cba937577821bc7813760a3"
            },
            "downloads": -1,
            "filename": "edc_reportable-2.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "a8241813f78e27ab343a34458c3250db",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 77862,
            "upload_time": "2025-07-16T16:24:58",
            "upload_time_iso_8601": "2025-07-16T16:24:58.472438Z",
            "url": "https://files.pythonhosted.org/packages/56/7b/e2d257e7bf7fe2a53816df735497fe7ce0571d0027f825e225aed40dbaa6/edc_reportable-2.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "744d67dd196ad9af4afa2c67db3ca15e8ea88d09c231d8d68b9ce3335b0ecbbe",
                "md5": "2bc190e6dea9b2c4acbd420ec117cd20",
                "sha256": "a7ca71ebf37efa7637af45b501cea4d5b17b49359c92cbc6b8197ff14465c0bb"
            },
            "downloads": -1,
            "filename": "edc_reportable-2.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "2bc190e6dea9b2c4acbd420ec117cd20",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 60224,
            "upload_time": "2025-07-16T16:24:59",
            "upload_time_iso_8601": "2025-07-16T16:24:59.599009Z",
            "url": "https://files.pythonhosted.org/packages/74/4d/67dd196ad9af4afa2c67db3ca15e8ea88d09c231d8d68b9ce3335b0ecbbe/edc_reportable-2.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-16 16:24:59",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "clinicedc",
    "github_project": "edc-reportable",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "edc-reportable"
}
        
Elapsed time: 0.65687s