|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"
}