meta-edc 1.0.6__py3-none-any.whl → 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. meta_ae/action_items.py +10 -2
  2. meta_ae/baker_recipes.py +1 -2
  3. meta_ae/tests/tests/test_actions.py +1 -2
  4. meta_analytics/dataframes/__init__.py +3 -0
  5. meta_analytics/dataframes/constants.py +1 -1
  6. meta_analytics/dataframes/get_eos_df.py +15 -2
  7. meta_analytics/dataframes/get_glucose_df.py +149 -0
  8. meta_analytics/dataframes/get_glucose_fbg_df.py +27 -0
  9. meta_analytics/dataframes/get_glucose_fbg_ogtt_df.py +22 -0
  10. meta_analytics/dataframes/glucose_endpoints/endpoint_by_date.py +106 -120
  11. meta_analytics/dataframes/glucose_endpoints/glucose_endpoints_by_date.py +36 -227
  12. meta_analytics/dataframes/utils.py +18 -4
  13. meta_analytics/notebooks/anu.ipynb +95 -0
  14. meta_analytics/notebooks/appointment_planning.ipynb +329 -0
  15. meta_analytics/notebooks/arvs.ipynb +103 -0
  16. meta_analytics/notebooks/cleaning/consent_v1_ext.ipynb +227 -0
  17. meta_analytics/notebooks/cleaning/offschedule_eos.ipynb +353 -0
  18. meta_analytics/notebooks/dsmc/renal_dysfunction.ipynb +435 -0
  19. meta_analytics/notebooks/endpoints/meta_endpoints_by_date.ipynb +664 -0
  20. meta_analytics/notebooks/followup_examination.ipynb +141 -0
  21. meta_analytics/notebooks/hba1c.ipynb +136 -0
  22. meta_analytics/notebooks/hiv_regimens.ipynb +429 -0
  23. meta_analytics/notebooks/incidence.ipynb +232 -0
  24. meta_analytics/notebooks/liver.ipynb +389 -0
  25. meta_analytics/notebooks/magreth.ipynb +645 -0
  26. meta_analytics/notebooks/monitoring_report.ipynb +1751 -0
  27. meta_analytics/notebooks/pharmacy.ipynb +1070 -0
  28. meta_analytics/notebooks/pharmacy_stock_202410.ipynb +306 -0
  29. meta_analytics/notebooks/steering.ipynb +61 -0
  30. meta_analytics/notebooks/undiagnosed/meta3_screening_consort_chart.ipynb +1176 -0
  31. meta_analytics/notebooks/undiagnosed/meta3_screening_undiagnosed.ipynb +519 -0
  32. meta_analytics/notebooks/undiagnosed/meta_screening_table2.ipynb +964 -0
  33. meta_analytics/notebooks/undiagnosed/screen_undiagnosed_or.ipynb +296 -0
  34. meta_analytics/notebooks/undiagnosed/screening.ipynb +273 -0
  35. meta_analytics/notebooks/undiagnosed/screening2.ipynb +958 -0
  36. meta_analytics/notebooks/undiagnosed/screening_undiagnosed_20241002.ipynb +958 -0
  37. meta_analytics/notebooks/ven.ipynb +191 -0
  38. meta_analytics/notebooks/vitals.ipynb +263 -0
  39. meta_analytics/utils.py +81 -0
  40. meta_edc/settings/debug.py +3 -2
  41. meta_edc/urls.py +1 -0
  42. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info}/METADATA +6 -5
  43. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info}/RECORD +77 -36
  44. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info}/WHEEL +1 -1
  45. meta_edc-1.1.0.dist-info/licenses/AUTHORS.rst +8 -0
  46. meta_labs/reportables.py +14 -11
  47. meta_labs/tests/test_reportables.py +33 -12
  48. meta_pharmacy/notebooks/pharmacy.ipynb +41 -0
  49. meta_prn/migrations/0063_historicaloffstudymedication_singleton_field_and_more.py +37 -0
  50. meta_prn/migrations/0064_auto_20250602_2143.py +18 -0
  51. meta_prn/models/end_of_study.py +2 -0
  52. meta_prn/models/off_study_medication.py +2 -0
  53. meta_reports/migrations/0054_auto_20250422_2003.py +81 -0
  54. meta_reports/migrations/0055_alter_glucosesummary_table.py +17 -0
  55. meta_reports/migrations/0056_auto_20250422_2214.py +54 -0
  56. meta_reports/migrations/0057_auto_20250422_2224.py +54 -0
  57. meta_reports/migrations/0058_auto_20250422_2232.py +54 -0
  58. meta_reports/models/dbviews/glucose_summary/unmanaged_model.py +13 -1
  59. meta_reports/models/dbviews/glucose_summary/view_definition.py +8 -5
  60. meta_screening/eligibility/eligibility_part_three/base_eligibility_part_three.py +59 -47
  61. meta_screening/form_validators/screening_part_three.py +6 -1
  62. meta_screening/tests/meta_test_case_mixin.py +3 -0
  63. meta_screening/tests/tests/test_forms.py +9 -2
  64. meta_screening/tests/tests/test_screening_part_three.py +11 -14
  65. meta_subject/action_items.py +1 -2
  66. meta_subject/choices.py +2 -1
  67. meta_subject/form_validators/glucose_form_validator.py +16 -1
  68. meta_subject/forms/blood_results/blood_results_rft_form.py +60 -3
  69. meta_subject/forms/study_medication_form.py +5 -3
  70. meta_subject/migrations/0221_auto_20250402_1913.py +42 -0
  71. meta_subject/migrations/0222_alter_historicalstudymedication_stock_codes_and_more.py +46 -0
  72. meta_subject/migrations/0223_bloodresultsfbc_errors_bloodresultsgludummy_errors_and_more.py +83 -0
  73. meta_subject/migrations/0224_bloodresultsfbc_abnormal_summary_and_more.py +153 -0
  74. meta_subject/tests/tests/test_egfr.py +5 -5
  75. meta_analytics/dataframes/enrolled/__init__.py +0 -1
  76. meta_analytics/dataframes/enrolled/get_glucose_df.py +0 -122
  77. /meta_edc-1.0.6.dist-info/AUTHORS → /meta_analytics/dataframes/glucose_endpoints/utils.py +0 -0
  78. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info/licenses}/LICENSE +0 -0
  79. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,329 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "0",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "%%capture\n",
11
+ "import os\n",
12
+ "from pathlib import Path\n",
13
+ "import pandas as pd\n",
14
+ "from dj_notebook import activate\n",
15
+ "import numpy as np\n",
16
+ "from django_pandas.io import read_frame\n",
17
+ "\n",
18
+ "env_file = os.environ[\"META_ENV\"]\n",
19
+ "reports_folder = Path(os.environ[\"META_REPORTS_FOLDER\"])\n",
20
+ "analysis_folder = Path(os.environ[\"META_ANALYSIS_FOLDER\"])\n",
21
+ "pharmacy_folder = Path(os.environ[\"META_PHARMACY_FOLDER\"])\n",
22
+ "plus = activate(dotenv_file=env_file)\n",
23
+ "pd.set_option('future.no_silent_downcasting', True)"
24
+ ]
25
+ },
26
+ {
27
+ "cell_type": "code",
28
+ "execution_count": null,
29
+ "id": "1",
30
+ "metadata": {},
31
+ "outputs": [],
32
+ "source": [
33
+ "import pdfkit\n",
34
+ "from datetime import date\n",
35
+ "from edc_pdutils.dataframes import get_subject_visit\n",
36
+ "from meta_analytics.dataframes import get_glucose_fbg_ogtt_df, get_glucose_fbg_df\n",
37
+ "from meta_visit_schedule.constants import MONTH15, MONTH18, MONTH21, MONTH27, MONTH30, MONTH33, MONTH39\n",
38
+ "from meta_analytics.dataframes import GlucoseEndpointsByDate\n",
39
+ "from scipy.stats import chi2\n",
40
+ "from great_tables import loc, style, md\n",
41
+ "from meta_analytics.dataframes import get_eos_df\n",
42
+ "from meta_analytics.utils import df_as_great_table, df_as_great_table2\n",
43
+ "from meta_prn.models import LossToFollowup\n",
44
+ "from edc_visit_schedule.models import SubjectScheduleHistory\n",
45
+ "from edc_appointment.analytics import get_appointment_df\n",
46
+ "from edc_appointment.constants import NEW_APPT, CANCELLED_APPT, ONTIME_APPT, MISSED_APPT, SCHEDULED_APPT, COMPLETE_APPT, INCOMPLETE_APPT, IN_PROGRESS_APPT, UNSCHEDULED_APPT\n",
47
+ "from edc_constants.constants import YES\n",
48
+ "from meta_consent.models import SubjectConsentV1Ext"
49
+ ]
50
+ },
51
+ {
52
+ "cell_type": "code",
53
+ "execution_count": null,
54
+ "id": "2",
55
+ "metadata": {},
56
+ "outputs": [],
57
+ "source": [
58
+ "html_data = []\n",
59
+ "cutoff_date = date(2025,3, 31)\n",
60
+ "end_of_trial_date= date(2026,3, 1)\n",
61
+ "document_title = f\"<h2>Monitoring Report: {cutoff_date.strftime('%B %Y')}</h2><h5>Data Download: {cutoff_date.strftime('%d %B %Y')}</h5>\"\n",
62
+ "study_title = 'META3 - Metformin treatment for diabetes prevention in Africa'\n",
63
+ "pdf_filename = f\"monitoring_report_{cutoff_date.strftime('%Y%m%d')}.pdf\"\n",
64
+ "\n",
65
+ "column_headers = {\"appt_datetime\": \"Appointment\", \"year\": \"Year\", \"month\": \"Month\", \"10\": \"Hindu Mandal\", \"20\": \"Amana\", \"30\": \"Temeke\", \"40\": \"Mwananyamala\", \"60\": \"Mnazi Moja\", \"total\": \"Total\"}\n",
66
+ "\n"
67
+ ]
68
+ },
69
+ {
70
+ "cell_type": "code",
71
+ "execution_count": null,
72
+ "id": "3",
73
+ "metadata": {},
74
+ "outputs": [],
75
+ "source": [
76
+ "df_visit = get_subject_visit(\"meta_subject.subjectvisit\")\n",
77
+ "df_visit = df_visit[df_visit.appt_datetime.dt.date<=cutoff_date]\n",
78
+ "df_appointments = get_appointment_df()\n",
79
+ "df_appointments[\"site_id\"] = df_appointments.site_id.astype(str)\n",
80
+ "cls = GlucoseEndpointsByDate()\n",
81
+ "cls.run()\n",
82
+ "df_endpoint = cls.endpoint_only_df.copy()\n",
83
+ "df_glucose = get_glucose_fbg_ogtt_df()\n",
84
+ "df_glucose_fbg = get_glucose_fbg_df()\n",
85
+ "df_glucose = pd.concat([df_glucose, df_glucose_fbg])\n",
86
+ "\n",
87
+ "enrolled = df_visit.copy()\n",
88
+ "enrolled[\"site_id\"] = enrolled[\"site_id\"].astype(str)\n",
89
+ "enrolled_pivot = (\n",
90
+ " enrolled\n",
91
+ " .query(\"visit_code==1000.0\").groupby([\"site_id\"])\n",
92
+ " .size()\n",
93
+ " .reset_index()\n",
94
+ " .pivot_table(columns=\"site_id\", values=0, observed=True)\n",
95
+ ")\n",
96
+ "enrolled_pivot.columns.name=\"\"\n",
97
+ "enrolled_pivot[\"total\"] = enrolled_pivot[[\"10\", \"20\",\"30\",\"40\",\"60\"]].sum(axis=1)\n",
98
+ "\n"
99
+ ]
100
+ },
101
+ {
102
+ "cell_type": "code",
103
+ "execution_count": null,
104
+ "id": "4",
105
+ "metadata": {},
106
+ "outputs": [],
107
+ "source": [
108
+ "# Table 1f Future scheduled appointments per month\n",
109
+ "df_appt_pivot = (\n",
110
+ " # df_appointments.query(\"appt_datetime<=@cutoff_date and appt_reason==@SCHEDULED_APPT and appt_timing==@ONTIME_APPT and ~appt_status.isin([@NEW_APPT])\")\n",
111
+ " df_appointments.query(\"@cutoff_date<=appt_datetime<=@end_of_trial_date and appt_reason==@SCHEDULED_APPT and appt_timing==@ONTIME_APPT and appt_status.isin([@NEW_APPT])\")\n",
112
+ " .set_index(\"appt_datetime\")\n",
113
+ " .groupby(by=[\"site_id\", pd.Grouper(freq=\"ME\")])\n",
114
+ " .size()\n",
115
+ " .to_frame()\n",
116
+ " .reset_index()\n",
117
+ " .rename(columns={0:\"patients\"})\n",
118
+ " .pivot(index=\"appt_datetime\", columns=\"site_id\", values=\"patients\")\n",
119
+ " .reset_index()\n",
120
+ " .fillna(0)\n",
121
+ ")\n",
122
+ "\n",
123
+ "df_appt_pivot.columns.name = None\n",
124
+ "df_appt_pivot[\"total\"] = df_appt_pivot.iloc[:,1:].sum(axis=1)\n",
125
+ "df_appt_pivot[\"appt_datetime\"] = df_appt_pivot.appt_datetime.dt.strftime(\"%Y-%m\")\n",
126
+ "sum_row = df_appt_pivot.select_dtypes(include='float64').sum()\n",
127
+ "sum_row['appt_datetime'] = 'Total-'\n",
128
+ "sum_row_df = pd.DataFrame(sum_row).T\n",
129
+ "df_appt_pivot = pd.concat([df_appt_pivot, sum_row_df], axis=0)\n",
130
+ "df_appt_pivot[[\"year\", \"month\"]] = df_appt_pivot[\"appt_datetime\"].str.split(\"-\", expand=True)\n",
131
+ "\n",
132
+ "df_appt_pivot2 = (\n",
133
+ " # df_appointments.query(\"appt_datetime<=@cutoff_date and appt_reason==@SCHEDULED_APPT and appt_timing==@ONTIME_APPT and ~appt_status.isin([@NEW_APPT])\")\n",
134
+ " df_appointments.query(\"@cutoff_date<=appt_datetime<=@end_of_trial_date and appt_reason==@SCHEDULED_APPT and appt_timing==@ONTIME_APPT and appt_status.isin([@NEW_APPT])\")\n",
135
+ " .set_index(\"visit_code\")\n",
136
+ " .groupby(by=[\"site_id\", \"visit_code\"])\n",
137
+ " .agg([\"last\"])\n",
138
+ " .size()\n",
139
+ " .to_frame()\n",
140
+ " .reset_index()\n",
141
+ " .rename(columns={0:\"patients\"})\n",
142
+ " .pivot(index=\"visit_code\", columns=\"site_id\", values=\"patients\")\n",
143
+ " .reset_index()\n",
144
+ " .fillna(0)\n",
145
+ ")\n",
146
+ "\n",
147
+ "df_appt_pivot2.columns.name = None\n",
148
+ "df_appt_pivot2[\"total\"] = df_appt_pivot2.iloc[:,1:].sum(axis=1)\n",
149
+ "df_appt_pivot2[\"visit_code\"] = df_appt_pivot2.visit_code.astype(str)\n",
150
+ "sum_row = df_appt_pivot2.select_dtypes(include='float64').sum()\n",
151
+ "sum_row['visit_code'] = 'Total-'\n",
152
+ "sum_row_df = pd.DataFrame(sum_row).T\n",
153
+ "df_appt_pivot2 = pd.concat([df_appt_pivot2, sum_row_df], axis=0)\n",
154
+ "\n",
155
+ "# df_appt_pivot2[[\"year\", \"month\"]] = df_appt_pivot2[\"appt_datetime\"].str.split(\"-\", expand=True)\n",
156
+ "\n",
157
+ "\n",
158
+ "df_appt_pivot2"
159
+ ]
160
+ },
161
+ {
162
+ "cell_type": "code",
163
+ "execution_count": null,
164
+ "id": "5",
165
+ "metadata": {},
166
+ "outputs": [],
167
+ "source": [
168
+ "def get_df_appt(criteria:str):\n",
169
+ " df_appt = (\n",
170
+ " df_appointments.query(\"@cutoff_date<=appt_datetime<=@end_of_trial_date and appt_reason==@SCHEDULED_APPT and appt_timing==@ONTIME_APPT and appt_status.isin([@NEW_APPT]) and visit_code<2000.0\")\n",
171
+ " .groupby([\"site_id\", \"appt_datetime\"])\n",
172
+ " .agg(\"last\")\n",
173
+ " .reset_index()\n",
174
+ " .query(criteria)\n",
175
+ " .set_index(\"appt_datetime\")\n",
176
+ " .groupby(by=[\"site_id\", pd.Grouper(freq=\"ME\")])\n",
177
+ " .size()\n",
178
+ " .to_frame()\n",
179
+ " .reset_index()\n",
180
+ " .rename(columns={0:\"patients\"})\n",
181
+ " .pivot(index=\"appt_datetime\", columns=\"site_id\", values=\"patients\")\n",
182
+ " .reset_index()\n",
183
+ " .fillna(0)\n",
184
+ " )\n",
185
+ " df_appt.columns.name = None\n",
186
+ " df_appt[\"total\"] = df_appt.iloc[:,1:].sum(axis=1)\n",
187
+ " sum_row = df_appt.select_dtypes(include='float64').sum()\n",
188
+ " sum_row_df = pd.DataFrame(sum_row).T\n",
189
+ " df_appt = pd.concat([df_appt, sum_row_df], axis=0)\n",
190
+ " df_appt[\"appt_datetime\"] = df_appt.appt_datetime.dt.strftime(\"%Y-%m\")\n",
191
+ " df_appt[[\"year\", \"month\"]] = df_appt[\"appt_datetime\"].str.split(\"-\", expand=True)\n",
192
+ " df_appt[\"year\"] = df_appt[\"year\"].fillna(\"Total\")\n",
193
+ " return df_appt\n",
194
+ "\n",
195
+ "\n",
196
+ "gt = df_as_great_table2(\n",
197
+ " get_df_appt(criteria=\"visit_code.isin([1360.0, 1480.0])\"),\n",
198
+ " title=\"Table 1f: Participants who will complete followup on 1360 or 1480 before 2026-03-01\",\n",
199
+ " # subtitle=\"Visit codes 1360 or 1480 only\",\n",
200
+ " rowname_col=\"month\",\n",
201
+ " groupname_col=\"year\",\n",
202
+ ")\n",
203
+ "gt = (\n",
204
+ " gt\n",
205
+ " .cols_label({k:v for k, v in column_headers.items() if k!=\"label\"})\n",
206
+ " .cols_align(align=\"center\", columns=[\"appt_datetime\", \"10\", \"20\", \"30\", \"40\", \"60\", \"total\"])\n",
207
+ " .cols_align(align=\"left\", columns=[\"month\", \"year\"])\n",
208
+ " .fmt_number(columns=[\"10\", \"20\", \"30\", \"40\", \"60\", \"total\"], decimals=0)\n",
209
+ " .tab_source_note(source_note=f\"Scheduled appointment date is on or after {cutoff_date.strftime('%d %B %Y')} and before {end_of_trial_date.strftime('%d %B %Y')}.\")\n",
210
+ " .tab_style(\n",
211
+ " style=[\n",
212
+ " style.text(color=\"black\", weight=\"bold\"),\n",
213
+ " style.fill(color=\"lightgray\")\n",
214
+ " ],\n",
215
+ " locations=loc.row_groups()\n",
216
+ " )\n",
217
+ ")\n",
218
+ "html_data.append(gt.as_raw_html())\n",
219
+ "gt.show()"
220
+ ]
221
+ },
222
+ {
223
+ "cell_type": "code",
224
+ "execution_count": null,
225
+ "id": "6",
226
+ "metadata": {},
227
+ "outputs": [],
228
+ "source": [
229
+ "\n",
230
+ "gt = df_as_great_table2(\n",
231
+ " get_df_appt(criteria=\"~visit_code.isin([1360.0, 1480.0])\"),\n",
232
+ " title=\"Table 1f: Participants who will NOT complete followup on 1360 or 1480 before 2026-03-01\",\n",
233
+ " rowname_col=\"month\",\n",
234
+ " groupname_col=\"year\",\n",
235
+ ")\n",
236
+ "gt = (\n",
237
+ " gt\n",
238
+ " .cols_label({k:v for k, v in column_headers.items() if k!=\"label\"})\n",
239
+ " .cols_align(align=\"center\", columns=[\"appt_datetime\", \"10\", \"20\", \"30\", \"40\", \"60\", \"total\"])\n",
240
+ " .cols_align(align=\"left\", columns=[\"month\", \"year\"])\n",
241
+ " .fmt_number(columns=[\"10\", \"20\", \"30\", \"40\", \"60\", \"total\"], decimals=0)\n",
242
+ " .tab_source_note(source_note=f\"Scheduled appointment date is on or after {cutoff_date.strftime('%d %B %Y')} and before {end_of_trial_date.strftime('%d %B %Y')}.\")\n",
243
+ " .tab_style(\n",
244
+ " style=[\n",
245
+ " style.text(color=\"black\", weight=\"bold\"),\n",
246
+ " style.fill(color=\"lightgray\")\n",
247
+ " ],\n",
248
+ " locations=loc.row_groups()\n",
249
+ " )\n",
250
+ ")\n",
251
+ "html_data.append(gt.as_raw_html())\n",
252
+ "gt.show()"
253
+ ]
254
+ },
255
+ {
256
+ "cell_type": "code",
257
+ "execution_count": null,
258
+ "id": "7",
259
+ "metadata": {},
260
+ "outputs": [],
261
+ "source": [
262
+ "# gather raw html\n",
263
+ "raw_html = [f'<div class=\"page-break\">{s}</div>' for s in html_data]\n",
264
+ "style_css = \"\"\"\n",
265
+ "<style>\n",
266
+ " .page-break {\n",
267
+ " page-break-inside: avoid; /* Always add page break before this element */\n",
268
+ " }\n",
269
+ " .table-header {\n",
270
+ " font-weight: bold;\n",
271
+ " font-size: 18px;\n",
272
+ " text-align: center;\n",
273
+ " border-bottom: None;\n",
274
+ " }\n",
275
+ "</style>\n",
276
+ "\"\"\"\n",
277
+ "raw_html = ''.join(raw_html)\n",
278
+ "raw_html = f'<!DOCTYPE html>\\n<html lang=\"en\">\\n{style_css}\\n<head>\\n<meta charset=\"utf-8\"/>\\n</head>\\n<body>\\n' + document_title + raw_html + '\\n</body>\\n</html>\\n'"
279
+ ]
280
+ },
281
+ {
282
+ "cell_type": "code",
283
+ "execution_count": null,
284
+ "id": "8",
285
+ "metadata": {},
286
+ "outputs": [],
287
+ "source": [
288
+ "pdfkit.from_string(raw_html, str(analysis_folder / pdf_filename),\n",
289
+ "options={\n",
290
+ " 'footer-center': 'Page [page] of [topage]',\n",
291
+ " 'footer-font-size': '8',\n",
292
+ " 'footer-spacing': '5',\n",
293
+ " 'encoding': \"UTF-8\",\n",
294
+ " 'margin-top':'10mm',\n",
295
+ " 'margin-right':'15mm',\n",
296
+ " 'margin-bottom':'15mm',\n",
297
+ " 'margin-left':'15mm',\n",
298
+ " 'header-center': study_title,\n",
299
+ " 'header-font-size': '6',\n",
300
+ " 'header-spacing': '0',\n",
301
+ " 'disable-javascript': None,\n",
302
+ " 'no-outline': None,\n",
303
+ "},\n",
304
+ "verbose=True)"
305
+ ]
306
+ }
307
+ ],
308
+ "metadata": {
309
+ "kernelspec": {
310
+ "display_name": "Python 3",
311
+ "language": "python",
312
+ "name": "python3"
313
+ },
314
+ "language_info": {
315
+ "codemirror_mode": {
316
+ "name": "ipython",
317
+ "version": 2
318
+ },
319
+ "file_extension": ".py",
320
+ "mimetype": "text/x-python",
321
+ "name": "python",
322
+ "nbconvert_exporter": "python",
323
+ "pygments_lexer": "ipython2",
324
+ "version": "2.7.6"
325
+ }
326
+ },
327
+ "nbformat": 4,
328
+ "nbformat_minor": 5
329
+ }
@@ -0,0 +1,103 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "0",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": []
10
+ },
11
+ {
12
+ "cell_type": "code",
13
+ "execution_count": null,
14
+ "id": "1",
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "%%capture\n",
19
+ "import os\n",
20
+ "import pandas as pd\n",
21
+ "import numpy as np\n",
22
+ "from dj_notebook import activate\n",
23
+ "from pathlib import Path\n",
24
+ "\n",
25
+ "env_file = os.environ[\"META_ENV\"]\n",
26
+ "analysis_folder = Path(os.environ[\"META_ANALYSIS_FOLDER\"])\n",
27
+ "reports_folder = Path(os.environ[\"META_ANALYSIS_FOLDER\"])\n",
28
+ "plus = activate(dotenv_file=env_file)"
29
+ ]
30
+ },
31
+ {
32
+ "cell_type": "code",
33
+ "execution_count": null,
34
+ "id": "2",
35
+ "metadata": {},
36
+ "outputs": [],
37
+ "source": [
38
+ "from edc_pdutils.dataframes import get_crf"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": null,
44
+ "id": "3",
45
+ "metadata": {},
46
+ "outputs": [],
47
+ "source": [
48
+ "df_patient_history = get_crf(\"meta_subject.patienthistory\", subject_visit_model=\"meta_subject.subjectvisit\")"
49
+ ]
50
+ },
51
+ {
52
+ "cell_type": "code",
53
+ "execution_count": null,
54
+ "id": "4",
55
+ "metadata": {},
56
+ "outputs": [],
57
+ "source": [
58
+ "df_patient_history[['subject_identifier', \"current_arv_regimen\"]].groupby(by=[\"current_arv_regimen\"])[\"current_arv_regimen\"].value_counts()"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "id": "5",
65
+ "metadata": {},
66
+ "outputs": [],
67
+ "source": [
68
+ "df_patient_history[['subject_identifier', \"current_arv_regimen\", \"other_current_arv_regimen\"]][[ \"other_current_arv_regimen\"]].value_counts()"
69
+ ]
70
+ },
71
+ {
72
+ "cell_type": "code",
73
+ "execution_count": null,
74
+ "id": "6",
75
+ "metadata": {},
76
+ "outputs": [],
77
+ "source": [
78
+ "df_patient_history[ \"other_current_arv_regimen\"] = df_patient_history[ \"other_current_arv_regimen\"].apply(lambda x : x.split(\"-\")[0])"
79
+ ]
80
+ }
81
+ ],
82
+ "metadata": {
83
+ "kernelspec": {
84
+ "display_name": "Python 3",
85
+ "language": "python",
86
+ "name": "python3"
87
+ },
88
+ "language_info": {
89
+ "codemirror_mode": {
90
+ "name": "ipython",
91
+ "version": 2
92
+ },
93
+ "file_extension": ".py",
94
+ "mimetype": "text/x-python",
95
+ "name": "python",
96
+ "nbconvert_exporter": "python",
97
+ "pygments_lexer": "ipython2",
98
+ "version": "2.7.6"
99
+ }
100
+ },
101
+ "nbformat": 4,
102
+ "nbformat_minor": 5
103
+ }
@@ -0,0 +1,227 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "0",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": []
10
+ },
11
+ {
12
+ "cell_type": "code",
13
+ "execution_count": null,
14
+ "id": "1",
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "%%capture\n",
19
+ "import pandas as pd\n",
20
+ "from django_pandas.io import read_frame\n",
21
+ "from pathlib import Path\n",
22
+ "from dj_notebook import activate\n",
23
+ "\n",
24
+ "plus = activate(dotenv_file=\"/Users/erikvw/source/edc_source/meta-edc/.env\")\n",
25
+ "report_folder = Path(\"/Users/erikvw/Documents/ucl/protocols/meta3/reports/\")\n",
26
+ "# output is suppressed -- normally would spew out all the edc loading messages\n"
27
+ ]
28
+ },
29
+ {
30
+ "cell_type": "code",
31
+ "execution_count": null,
32
+ "id": "2",
33
+ "metadata": {},
34
+ "outputs": [],
35
+ "source": [
36
+ "from edc_registration.models import RegisteredSubject\n",
37
+ "from edc_appointment.analytics import get_appointment_df\n",
38
+ "from meta_prn.models import OnSchedule, OffSchedule, OffSchedulePregnancy, OffSchedulePostnatal, OnScheduleDmReferral, \\\n",
39
+ " EndOfStudy\n",
40
+ "\n",
41
+ "df_onschedule = read_frame(OnSchedule.objects.all(), verbose=True)\n",
42
+ "df_offschedule = read_frame(OffSchedule.objects.all(), verbose=True)\n",
43
+ "df_onschedule_preg = read_frame(OffSchedulePregnancy.objects.all(), verbose=True)\n",
44
+ "df_onschedule_postnatal = read_frame(OffSchedulePostnatal.objects.all(), verbose=True)\n",
45
+ "df_onschedule_dm = read_frame(OnScheduleDmReferral.objects.all(), verbose=True)\n",
46
+ "df_eos = read_frame(EndOfStudy.objects.all(), verbose=True)\n",
47
+ "df_appt = get_appointment_df()\n",
48
+ "df_rs = read_frame(RegisteredSubject.objects.values(\"subject_identifier\", \"registration_datetime\").all(), verbose=True)\n"
49
+ ]
50
+ },
51
+ {
52
+ "cell_type": "code",
53
+ "execution_count": null,
54
+ "id": "3",
55
+ "metadata": {},
56
+ "outputs": [],
57
+ "source": [
58
+ "df_appt[df_appt.visit_code > 1360][[\"visit_code\", \"schedule_name\"]].schedule_name.value_counts()"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "id": "4",
65
+ "metadata": {},
66
+ "outputs": [],
67
+ "source": [
68
+ "df_appt[(df_appt.visit_code > 1360) & (df_appt.schedule_name == \"schedule\")][[\"visit_code\", \"schedule_name\"]].visit_code.value_counts()"
69
+ ]
70
+ },
71
+ {
72
+ "cell_type": "code",
73
+ "execution_count": null,
74
+ "id": "5",
75
+ "metadata": {},
76
+ "outputs": [],
77
+ "source": [
78
+ "df_appt[(df_appt.visit_code > 1360) & (df_appt.schedule_name == \"schedule\")][[\"subject_identifier\", \"appt_datetime\", \"visit_code\", \"appt_status\"]].sort_values(\"subject_identifier\")"
79
+ ]
80
+ },
81
+ {
82
+ "cell_type": "code",
83
+ "execution_count": null,
84
+ "id": "6",
85
+ "metadata": {},
86
+ "outputs": [],
87
+ "source": [
88
+ "df_appt = get_appointment_df()\n",
89
+ "\n",
90
+ "df_appt = df_appt[(df_appt.visit_code >= 1360) & (df_appt.schedule_name == \"schedule\")][[\"subject_identifier\", \"appt_datetime\", \"visit_code\", \"appt_status\"]]"
91
+ ]
92
+ },
93
+ {
94
+ "cell_type": "code",
95
+ "execution_count": null,
96
+ "id": "7",
97
+ "metadata": {},
98
+ "outputs": [],
99
+ "source": [
100
+ "df_magreth = pd.read_csv(Path(\"/Users/erikvw/Documents/ucl/protocols/meta3/reports/\") / \"consented_v1_ext_magreth.csv\")\n"
101
+ ]
102
+ },
103
+ {
104
+ "cell_type": "code",
105
+ "execution_count": null,
106
+ "id": "8",
107
+ "metadata": {},
108
+ "outputs": [],
109
+ "source": [
110
+ "df_magreth"
111
+ ]
112
+ },
113
+ {
114
+ "cell_type": "code",
115
+ "execution_count": null,
116
+ "id": "9",
117
+ "metadata": {},
118
+ "outputs": [],
119
+ "source": [
120
+ "df_main = pd.merge(df_appt[[\"subject_identifier\", \"appt_datetime\", \"visit_code\", \"appt_status\"]], df_magreth, on=\"subject_identifier\", how=\"right\").groupby([\"subject_identifier\", \"agreed\"]).agg({\"visit_code\": \"min\", \"date_reconsented\": \"max\"})"
121
+ ]
122
+ },
123
+ {
124
+ "cell_type": "code",
125
+ "execution_count": null,
126
+ "id": "10",
127
+ "metadata": {},
128
+ "outputs": [],
129
+ "source": [
130
+ "df_main = df_main.merge(df_appt[[\"subject_identifier\", \"visit_code\", \"appt_status\", \"appt_datetime\"]], on=[\"subject_identifier\", \"visit_code\"], how=\"left\")\n",
131
+ "df_main\n"
132
+ ]
133
+ },
134
+ {
135
+ "cell_type": "code",
136
+ "execution_count": null,
137
+ "id": "11",
138
+ "metadata": {},
139
+ "outputs": [],
140
+ "source": [
141
+ "df_rs"
142
+ ]
143
+ },
144
+ {
145
+ "cell_type": "code",
146
+ "execution_count": null,
147
+ "id": "12",
148
+ "metadata": {},
149
+ "outputs": [],
150
+ "source": [
151
+ "from meta_consent.models import SubjectConsentV1Ext\n",
152
+ "df_v1ext = read_frame(SubjectConsentV1Ext.objects.values(\"subject_identifier\", \"report_datetime\", \"agrees_to_extension\").all(), verbose=True)\n",
153
+ "df_v1ext"
154
+ ]
155
+ },
156
+ {
157
+ "cell_type": "code",
158
+ "execution_count": null,
159
+ "id": "13",
160
+ "metadata": {},
161
+ "outputs": [],
162
+ "source": [
163
+ "df_main = df_main.merge(df_rs, on=\"subject_identifier\", how=\"left\")"
164
+ ]
165
+ },
166
+ {
167
+ "cell_type": "code",
168
+ "execution_count": null,
169
+ "id": "14",
170
+ "metadata": {},
171
+ "outputs": [],
172
+ "source": [
173
+ "df_main = df_main.merge(df_v1ext, on=\"subject_identifier\", how=\"outer\")\n",
174
+ "df_main.rename(columns={\"report_datetime\": \"v1_ext_datetime\", \"agrees_to_extension\": \"agreed\", \"visit_code\": \"last_visit_code\"}, inplace=True)\n"
175
+ ]
176
+ },
177
+ {
178
+ "cell_type": "code",
179
+ "execution_count": null,
180
+ "id": "15",
181
+ "metadata": {},
182
+ "outputs": [],
183
+ "source": [
184
+ "df_main = df_main.merge(df_eos[[\"subject_identifier\", \"offstudy_datetime\"]], on=\"subject_identifier\", how=\"left\")\n"
185
+ ]
186
+ },
187
+ {
188
+ "cell_type": "code",
189
+ "execution_count": null,
190
+ "id": "16",
191
+ "metadata": {},
192
+ "outputs": [],
193
+ "source": [
194
+ "df_main[[\"subject_identifier\",\"registration_datetime\", \"last_visit_code\", \"appt_status\", \"appt_datetime\", \"date_reconsented\", \"v1_ext_datetime\", \"agreed\"]]"
195
+ ]
196
+ },
197
+ {
198
+ "cell_type": "code",
199
+ "execution_count": null,
200
+ "id": "17",
201
+ "metadata": {},
202
+ "outputs": [],
203
+ "source": []
204
+ }
205
+ ],
206
+ "metadata": {
207
+ "kernelspec": {
208
+ "display_name": "Python 3",
209
+ "language": "python",
210
+ "name": "python3"
211
+ },
212
+ "language_info": {
213
+ "codemirror_mode": {
214
+ "name": "ipython",
215
+ "version": 2
216
+ },
217
+ "file_extension": ".py",
218
+ "mimetype": "text/x-python",
219
+ "name": "python",
220
+ "nbconvert_exporter": "python",
221
+ "pygments_lexer": "ipython2",
222
+ "version": "2.7.6"
223
+ }
224
+ },
225
+ "nbformat": 4,
226
+ "nbformat_minor": 5
227
+ }