|pypi| |actions| |codecov| |downloads|
edc-visit-schedule
------------------
Add longitudinal data collection schedules to your EDC project.
Installation
============
Add to settings:
.. code-block:: python
INSTALLED_APPS = [
...
'edc_visit_schedule.apps.AppConfig',
...
]
Overview
========
* A ``Visit Schedule`` lives in your app in ``visit_schedules.py``. Each app can declare and register one or more visit schedules in its ``visit_schedules`` module. Visit schedules are loaded when ``autodiscover`` is called from ``AppConfig``.
* A ``VisitSchedule`` contains ``Schedules`` which contain ``Visits`` which contain ``Crfs`` and ``Requisitions``.
* A ``schedule`` is effectively a "data collection schedule" where each contained ``visit`` represents a data collection timepoint.
* A subject is put on a ``schedule`` by the schedule's ``onschedule`` model and taken off by the schedule's ``offschedule`` model. In the example below we use models ``OnSchedule`` and ``OffSchedule`` to do this for schedule ``schedule1``.
Usage
=====
First, create a file ``visit_schedules.py`` in the root of your app where the visit schedule code below will live.
Next, declare lists of data ``Crfs`` and laboratory ``Requisitions`` to be completed during each visit. For simplicity, we assume that every visit has the same data collection requirement (not usually the case).
.. code-block:: python
from myapp.models import SubjectVisit, OnSchedule, OffSchedule, SubjectDeathReport, SubjectOffstudy
from edc_visit_schedule.site_visit_schedules import site_visit_schedules
from edc_visit_schedule.schedule import Schedule
from edc_visit_schedule.visit import Crf, Requisition, CrfCollection, RequisitionCollection
from edc_visit_schedule.visit_schedule import VisitSchedule
crfs = CrfCollection(
Crf(show_order=10, model='myapp.crfone'),
Crf(show_order=20, model='myapp.crftwo'),
Crf(show_order=30, model='myapp.crfthree'),
Crf(show_order=40, model='myapp.crffour'),
Crf(show_order=50, model='myapp.crffive'),
)
requisitions = RequisitionCollection(
Requisition(
show_order=10, model='myapp.subjectrequisition', panel_name='Research Blood Draw'),
Requisition(
show_order=20, model='myapp.subjectrequisition', panel_name='Viral Load'),
)
Create a new visit schedule:
.. code-block:: python
visit_schedule = VisitSchedule(
name='visit_schedule',
verbose_name='My Visit Schedule',
death_report_model=SubjectDeathReport,
offstudy_model=SubjectOffstudy)
Visit schedules contain ``Schedules`` so create a schedule:
.. code-block:: python
schedule = Schedule(
name='schedule',
onschedule_model='myapp.onschedule',
offschedule_model='myapp.offschedule',
consent_definitions=[consent_definition_v1])
About consent_definitions:
As you will see below, the ``schedule`` is a container for a data collection schedule of forms (CRFs and requisitions)
for a single study timepoint or ``visit``. Ethically, a subject's data may not be collected before the subject has signed and submitted the informed consent form (ICF).
``Schedule`` is configured with information about the ICF that covers the forms it contains. When a form for a subject is validated and submitted, the ``Schedule`` will
provide the consent_definition (or definitions) so that the calling object can confirm the subject is consented. The ICF is represented by
the class ``ConsentDefinition`` from ``edc_consent``.
See also class ``ConsentDefinition`` in ``edc_consent``.
Schedules contains visits, so declare some visits and add to the ``schedule``:
.. code-block:: python
visit0 = Visit(
code='1000',
title='Visit 1000',
timepoint=0,
rbase=relativedelta(days=0),
requisitions=requisitions,
crfs=crfs)
visit1 = Visit(
code='2000',
title='Visit 2000',
timepoint=1,
rbase=relativedelta(days=28),
requisitions=requisitions,
crfs=crfs)
schedule.add_visit(visit=visit0)
schedule.add_visit(visit=visit1)
Add the schedule to your visit schedule:
.. code-block:: python
schedule = visit_schedule.add_schedule(schedule)
Register the visit schedule with the site registry:
.. code-block:: python
visit_schedules.register(visit_schedule)
When Django loads, the visit schedule class will be available in the global ``site_visit_schedules``.
The ``site_visit_schedules`` has a number of methods to help query the visit schedule and some related data.
**Note:** The ``schedule`` above was declared with ``onschedule_model=OnSchedule``. An on-schedule model uses the ``CreateAppointmentsMixin`` from ``edc_appointment``. On ``onschedule.save()`` the method ``onschedule.create_appointments`` is called. This method uses the visit schedule information to create the appointments as per the visit data in the schedule. See also ``edc_appointment``.
OnSchedule and OffSchedule models
=================================
Two models mixins are required for the on-schedule and off-schedule models, ``OnScheduleModelMixin`` and ``OffScheduleModelMixin``. OnSchedule/OffSchedule models are specific to a ``schedule``. The ``visit_schedule_name`` and ``schedule_name`` are declared on the model's ``Meta`` class attribute ``visit_schedule_name``.
For example:
.. code-block:: python
class OnSchedule(OnScheduleModelMixin, BaseUuidModel):
"""A model used by the system. Auto-completed by subject_consent."""
objects = SubjectIdentifierManager()
on_site = CurrentSiteManager()
history = HistoricalRecords()
class Meta(OnScheduleModelMixin.Meta, BaseUuidModel.Meta):
pass
class OffSchedule(ActionModelMixin, OffScheduleModelMixin, BaseUuidModel):
action_name = OFFSCHEDULE_ACTION
class Meta(OffScheduleModelMixin.Meta, BaseUuidModel.Meta):
verbose_name = "Off-schedule"
verbose_name_plural = "Off-schedule"
.. |pypi| image:: https://img.shields.io/pypi/v/edc-visit-schedule.svg
:target: https://pypi.python.org/pypi/edc-visit-schedule
.. |actions| image:: https://github.com/clinicedc/edc-visit-schedule/actions/workflows/build.yml/badge.svg
:target: https://github.com/clinicedc/edc-visit-schedule/actions/workflows/build.yml
.. |codecov| image:: https://codecov.io/gh/clinicedc/edc-visit-schedule/branch/develop/graph/badge.svg
:target: https://codecov.io/gh/clinicedc/edc-visit-schedule
.. |downloads| image:: https://pepy.tech/badge/edc-visit-schedule
:target: https://pepy.tech/project/edc-visit-schedule
Raw data
{
"_id": null,
"home_page": "https://github.com/clinicedc/edc-visit-schedule",
"name": "edc-visit-schedule",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "django edc visit schedule, data collection schedule, clinicedc, clinical trials",
"author": "Erik van Widenfelt",
"author_email": "ew2789@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/35/ab/12871db044a51ef4df15510e60b4bbf1223675583c5468527fe926005941/edc_visit_schedule-4.0.0.tar.gz",
"platform": null,
"description": "|pypi| |actions| |codecov| |downloads|\n\nedc-visit-schedule\n------------------\n\nAdd longitudinal data collection schedules to your EDC project.\n\n\nInstallation\n============\n\nAdd to settings:\n\n.. code-block:: python\n\n INSTALLED_APPS = [\n ...\n 'edc_visit_schedule.apps.AppConfig',\n ...\n ]\n\nOverview\n========\n\n* A ``Visit Schedule`` lives in your app in ``visit_schedules.py``. Each app can declare and register one or more visit schedules in its ``visit_schedules`` module. Visit schedules are loaded when ``autodiscover`` is called from ``AppConfig``.\n* A ``VisitSchedule`` contains ``Schedules`` which contain ``Visits`` which contain ``Crfs`` and ``Requisitions``.\n* A ``schedule`` is effectively a \"data collection schedule\" where each contained ``visit`` represents a data collection timepoint.\n* A subject is put on a ``schedule`` by the schedule's ``onschedule`` model and taken off by the schedule's ``offschedule`` model. In the example below we use models ``OnSchedule`` and ``OffSchedule`` to do this for schedule ``schedule1``.\n\nUsage\n=====\n\nFirst, create a file ``visit_schedules.py`` in the root of your app where the visit schedule code below will live.\n\n\nNext, declare lists of data ``Crfs`` and laboratory ``Requisitions`` to be completed during each visit. For simplicity, we assume that every visit has the same data collection requirement (not usually the case).\n\n.. code-block:: python\n\n from myapp.models import SubjectVisit, OnSchedule, OffSchedule, SubjectDeathReport, SubjectOffstudy\n\n from edc_visit_schedule.site_visit_schedules import site_visit_schedules\n from edc_visit_schedule.schedule import Schedule\n from edc_visit_schedule.visit import Crf, Requisition, CrfCollection, RequisitionCollection\n from edc_visit_schedule.visit_schedule import VisitSchedule\n\n\n crfs = CrfCollection(\n Crf(show_order=10, model='myapp.crfone'),\n Crf(show_order=20, model='myapp.crftwo'),\n Crf(show_order=30, model='myapp.crfthree'),\n Crf(show_order=40, model='myapp.crffour'),\n Crf(show_order=50, model='myapp.crffive'),\n )\n\n requisitions = RequisitionCollection(\n Requisition(\n show_order=10, model='myapp.subjectrequisition', panel_name='Research Blood Draw'),\n Requisition(\n show_order=20, model='myapp.subjectrequisition', panel_name='Viral Load'),\n )\n\nCreate a new visit schedule:\n\n.. code-block:: python\n\n visit_schedule = VisitSchedule(\n name='visit_schedule',\n verbose_name='My Visit Schedule',\n death_report_model=SubjectDeathReport,\n offstudy_model=SubjectOffstudy)\n\n\nVisit schedules contain ``Schedules`` so create a schedule:\n\n.. code-block:: python\n\n schedule = Schedule(\n name='schedule',\n onschedule_model='myapp.onschedule',\n offschedule_model='myapp.offschedule',\n consent_definitions=[consent_definition_v1])\n\nAbout consent_definitions:\n As you will see below, the ``schedule`` is a container for a data collection schedule of forms (CRFs and requisitions)\n for a single study timepoint or ``visit``. Ethically, a subject's data may not be collected before the subject has signed and submitted the informed consent form (ICF).\n ``Schedule`` is configured with information about the ICF that covers the forms it contains. When a form for a subject is validated and submitted, the ``Schedule`` will\n provide the consent_definition (or definitions) so that the calling object can confirm the subject is consented. The ICF is represented by\n the class ``ConsentDefinition`` from ``edc_consent``.\n\n See also class ``ConsentDefinition`` in ``edc_consent``.\n\nSchedules contains visits, so declare some visits and add to the ``schedule``:\n\n.. code-block:: python\n\n visit0 = Visit(\n code='1000',\n title='Visit 1000',\n timepoint=0,\n rbase=relativedelta(days=0),\n requisitions=requisitions,\n crfs=crfs)\n\n visit1 = Visit(\n code='2000',\n title='Visit 2000',\n timepoint=1,\n rbase=relativedelta(days=28),\n requisitions=requisitions,\n crfs=crfs)\n\n schedule.add_visit(visit=visit0)\n schedule.add_visit(visit=visit1)\n\n\nAdd the schedule to your visit schedule:\n\n.. code-block:: python\n\n schedule = visit_schedule.add_schedule(schedule)\n\nRegister the visit schedule with the site registry:\n\n.. code-block:: python\n\n visit_schedules.register(visit_schedule)\n\nWhen Django loads, the visit schedule class will be available in the global ``site_visit_schedules``.\n\nThe ``site_visit_schedules`` has a number of methods to help query the visit schedule and some related data.\n\n **Note:** The ``schedule`` above was declared with ``onschedule_model=OnSchedule``. An on-schedule model uses the ``CreateAppointmentsMixin`` from ``edc_appointment``. On ``onschedule.save()`` the method ``onschedule.create_appointments`` is called. This method uses the visit schedule information to create the appointments as per the visit data in the schedule. See also ``edc_appointment``.\n\nOnSchedule and OffSchedule models\n=================================\n\nTwo models mixins are required for the on-schedule and off-schedule models, ``OnScheduleModelMixin`` and ``OffScheduleModelMixin``. OnSchedule/OffSchedule models are specific to a ``schedule``. The ``visit_schedule_name`` and ``schedule_name`` are declared on the model's ``Meta`` class attribute ``visit_schedule_name``.\n\nFor example:\n\n.. code-block:: python\n\n class OnSchedule(OnScheduleModelMixin, BaseUuidModel):\n\n \"\"\"A model used by the system. Auto-completed by subject_consent.\"\"\"\n\n objects = SubjectIdentifierManager()\n\n on_site = CurrentSiteManager()\n\n history = HistoricalRecords()\n\n class Meta(OnScheduleModelMixin.Meta, BaseUuidModel.Meta):\n pass\n\n\n class OffSchedule(ActionModelMixin, OffScheduleModelMixin, BaseUuidModel):\n\n action_name = OFFSCHEDULE_ACTION\n\n class Meta(OffScheduleModelMixin.Meta, BaseUuidModel.Meta):\n verbose_name = \"Off-schedule\"\n verbose_name_plural = \"Off-schedule\"\n\n\n.. |pypi| image:: https://img.shields.io/pypi/v/edc-visit-schedule.svg\n :target: https://pypi.python.org/pypi/edc-visit-schedule\n\n.. |actions| image:: https://github.com/clinicedc/edc-visit-schedule/actions/workflows/build.yml/badge.svg\n :target: https://github.com/clinicedc/edc-visit-schedule/actions/workflows/build.yml\n\n.. |codecov| image:: https://codecov.io/gh/clinicedc/edc-visit-schedule/branch/develop/graph/badge.svg\n :target: https://codecov.io/gh/clinicedc/edc-visit-schedule\n\n.. |downloads| image:: https://pepy.tech/badge/edc-visit-schedule\n :target: https://pepy.tech/project/edc-visit-schedule\n",
"bugtrack_url": null,
"license": "GPL license, see LICENSE",
"summary": "Base classes for visit reports/tracking in clinicedc/edc",
"version": "4.0.0",
"project_urls": {
"Homepage": "https://github.com/clinicedc/edc-visit-schedule"
},
"split_keywords": [
"django edc visit schedule",
" data collection schedule",
" clinicedc",
" clinical trials"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "da418d23ebbee1bbc6e0a35e4f0a987250ffa5e69596c498e6f720da5db19e1e",
"md5": "6c337e7da3719c259bfe0f6d7a848bda",
"sha256": "b109d8b7cef70a7ef2b8450d375a53dbecd3abcb4312b70b7eb549d0e72be1d3"
},
"downloads": -1,
"filename": "edc_visit_schedule-4.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6c337e7da3719c259bfe0f6d7a848bda",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 115416,
"upload_time": "2024-11-20T22:27:40",
"upload_time_iso_8601": "2024-11-20T22:27:40.863479Z",
"url": "https://files.pythonhosted.org/packages/da/41/8d23ebbee1bbc6e0a35e4f0a987250ffa5e69596c498e6f720da5db19e1e/edc_visit_schedule-4.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "35ab12871db044a51ef4df15510e60b4bbf1223675583c5468527fe926005941",
"md5": "0c681f86473ec55bda0fa6ed9e415f03",
"sha256": "9cd05223bb5308ff97348ccc6d7319d5daedab55aff5f175e086753d185873bd"
},
"downloads": -1,
"filename": "edc_visit_schedule-4.0.0.tar.gz",
"has_sig": false,
"md5_digest": "0c681f86473ec55bda0fa6ed9e415f03",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 81521,
"upload_time": "2024-11-20T22:27:42",
"upload_time_iso_8601": "2024-11-20T22:27:42.112558Z",
"url": "https://files.pythonhosted.org/packages/35/ab/12871db044a51ef4df15510e60b4bbf1223675583c5468527fe926005941/edc_visit_schedule-4.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-20 22:27:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "clinicedc",
"github_project": "edc-visit-schedule",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "edc-visit-schedule"
}