gazoo-research-utils 2.0.1__tar.gz

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.
@@ -0,0 +1,7 @@
1
+ Copyright 2026 Andrew Lim
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,176 @@
1
+ Metadata-Version: 2.4
2
+ Name: gazoo-research-utils
3
+ Version: 2.0.1
4
+ Summary: Utilities for the Analysis of Gazoo Research Data
5
+ Author: Andrew Lim MD, Megan Lim MD, Christopher Lim MD, Robert Lim MD
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Dist: lifelines>=0.28.0
11
+ Requires-Dist: pandas>=3.0.0
12
+ Requires-Dist: pydantic>=2.12.5
13
+ Requires-Dist: pytest>=7.4.0 ; extra == 'dev'
14
+ Requires-Dist: pytest-cov>=4.1.0 ; extra == 'dev'
15
+ Requires-Python: >=3.11
16
+ Project-URL: Homepage, https://gazooresearch.com/
17
+ Provides-Extra: dev
18
+ Description-Content-Type: text/markdown
19
+
20
+ # GazooResearchUtils
21
+ GazooResearchUtils is a python library whose purpose is to analyze medical data from GazooResearch.
22
+
23
+
24
+ ## Example output from GazooResearch prostate-data.csv
25
+ The data is denormalized on fields, but ultimately has this hierarchy.
26
+ id -> collection -> tag -> (field, data_type, value, phi)
27
+
28
+
29
+ ### Column descriptions are as follows
30
+ id: patient identification
31
+ collection: A collection of related tags
32
+ tag: name of tag (eg. dob, psa)
33
+ tag_id: Unique identifier
34
+ field: tag name (date, value, date)
35
+ data_type: data type held in the value column. Options are: text, categorical, number, date). dates will be of this form YYYY-MM-DD
36
+ value: value of field
37
+ phi: 0 or 1, depending on if the data element is protected health information
38
+
39
+ ### Issues
40
+ The value field may be empty, or will contain data conforming to the data_type structure.
41
+
42
+ ```csv
43
+ id,collection,tag,tag_id,field,data_type,value,phi
44
+ 111111,0,id,#6bed55ed-f844-4c88-ab74-af0e74aa2547,mrn,text,111111,1
45
+ 111111,0,last-name,bd7e898c-9732-4320-8227-a1b90cc8c80e,value,text,Bing,1
46
+ 111111,0,first-name,#4ff0ace3-e804-4d55-97a0-22cc6f927327,value,text,Chandler,1
47
+ 111111,0,dob,#5578f001-b34b-4465-b699-8c8ff6c11d89,date,date,1952-12-17,0
48
+ 111111,0,document,#ce5ab218-8e98-417b-b843-965ea637ca57,date,date,2023-12-06,0
49
+ 111111,0,document,#ce5ab218-8e98-417b-b843-965ea637ca57,type,categorical,clinical,0
50
+ 111111,c61,surgery,#6082ea75-06c3-4082-9c69-918d0df8c619,date,date,2010-01-01,0
51
+ 111111,c61,surgery,#6082ea75-06c3-4082-9c69-918d0df8c619,type,categorical,prostatectomy-lymphadenectomy,0
52
+ 111111,c61,surgery,#6082ea75-06c3-4082-9c69-918d0df8c619,target-id,text,prostate,0
53
+ 111111,c61,R,#358ebce7-9e7d-441c-a976-38d02d3da58e,date,date,2010-01-01,0
54
+ 111111,c61,R,#358ebce7-9e7d-441c-a976-38d02d3da58e,R,categorical,0,0
55
+ 111111,c61,pT,#2485755d-aa2a-4fa9-a263-4d11c9370145,date,date,2010-01-01,0
56
+ 111111,c61,pT,#2485755d-aa2a-4fa9-a263-4d11c9370145,T,categorical,2c,0
57
+ 111111,c61,pN,#8d04921a-cee6-4c7c-9eb2-d954c1b33008,date,date,2010-01-01,0
58
+ 111111,c61,pN,#8d04921a-cee6-4c7c-9eb2-d954c1b33008,N,categorical,0,0
59
+ 111111,c61,pN,#8d04921a-cee6-4c7c-9eb2-d954c1b33008,involved-lymph-nodes,number,,0
60
+ 111111,c61,pN,#8d04921a-cee6-4c7c-9eb2-d954c1b33008,total-lymph-nodes,number,,0
61
+ 111111,c61,gleason-grade-group,#55109b94-41fe-4b11-a47a-824970ab9dfb,date,date,2010-01-01,0
62
+ 111111,c61,gleason-grade-group,#55109b94-41fe-4b11-a47a-824970ab9dfb,value,categorical,2,0
63
+ 111111,c61,gleason-grade-group,#55109b94-41fe-4b11-a47a-824970ab9dfb,target-id,text,prostate,0
64
+ 111111,c61,psa,64987467-bcc2-4c23-a943-899467d93981,date,date,2019-02-22,0
65
+ 111111,c61,psa,64987467-bcc2-4c23-a943-899467d93981,value,number,0.28,0
66
+ 111111,c61,psa,64987467-bcc2-4c23-a943-899467d93981,units,categorical,ng/ml,0
67
+ 111111,c61,psa,91a5221d-de16-4af9-acb6-82b7d37ed118,date,date,2019-06-12,0
68
+ 111111,c61,psa,91a5221d-de16-4af9-acb6-82b7d37ed118,value,number,0.31,0
69
+ 111111,c61,psa,91a5221d-de16-4af9-acb6-82b7d37ed118,units,categorical,ng/ml,0
70
+ 111111,c61,psa,6ed2dc02-af27-4395-a73e-36af30b7fed6,date,date,2023-12-06,0
71
+ 111111,c61,psa,6ed2dc02-af27-4395-a73e-36af30b7fed6,value,number,0.01,0
72
+ 111111,c61,psa,6ed2dc02-af27-4395-a73e-36af30b7fed6,units,categorical,ng/ml,0
73
+ 111111,c61,androgen-deprivation-therapy,#ed2d15d6-2650-41fe-af7d-e9b6ac1140d6,start-date,date,2019-07-15,0
74
+ 111111,c61,androgen-deprivation-therapy,#ed2d15d6-2650-41fe-af7d-e9b6ac1140d6,end-date,date,2019-12-06,0
75
+ 111111,c61,androgen-deprivation-therapy,#ed2d15d6-2650-41fe-af7d-e9b6ac1140d6,medication,categorical,leuprolide,0
76
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,start-date,date,2019-08-15,0
77
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,end-date,date,2019-10-03,0
78
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,field,categorical,prostate-bed-pelvic-lymph-nodes,0
79
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,dose,number,,0
80
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,unit,categorical,Gy,0
81
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,fractions,number,,0
82
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,technique,categorical,unknown,0
83
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,target-id,text,prostate,0
84
+ 111111,c61,biochemical-progression,#e6458863-ceba-4194-a361-df96407d5c3a,date,date,,0
85
+ 111111,c61,biochemical-progression,#e6458863-ceba-4194-a361-df96407d5c3a,type,categorical,aua,0
86
+ 111111,0,last-name,#3dd60c0d-d51d-4c4a-8250-715a8f415207,value,text,Bing,1
87
+ 111111,0,id,#1c9d95e8-7d8b-4102-990b-02ebea1e9a14,mrn,text,111111,1
88
+ 111111,0,dob,#47a681ae-23a8-41e8-b569-32039d3f47b4,date,date,1952-12-17,0
89
+ 111111,c61,psa,#b482b981-cf18-420f-b518-d3f6279f03c5,date,date,2019-02-22,0
90
+ 111111,c61,psa,#b482b981-cf18-420f-b518-d3f6279f03c5,value,number,0.28,0
91
+ 111111,c61,psa,#b482b981-cf18-420f-b518-d3f6279f03c5,units,categorical,ng/ml,0
92
+ 333333,0,id,c918371b-01f7-49ee-acd8-b00dee6e49e9,mrn,text,333333,1
93
+ 333333,0,first-name,dc110270-d5c1-431c-8f90-86459bed3a36,value,text,Joey,1
94
+ 333333,0,last-name,2d9ae449-8d3f-4493-82a8-75321f4df6cd,value,text,Tribbiani,1
95
+ 333333,0,dob,d1044870-b049-4465-b306-e0eb1a20b8c2,date,date,1948-01-22,0
96
+ 333333,c61,surgery,#a5b2b0b0-1752-401f-a4d6-63f41dec128b,date,date,2019-08-31,0
97
+ 333333,c61,surgery,#a5b2b0b0-1752-401f-a4d6-63f41dec128b,type,categorical,prostatectomy,0
98
+ 333333,c61,surgery,#a5b2b0b0-1752-401f-a4d6-63f41dec128b,target-id,text,prostate,0
99
+ 333333,c61,pT,#3d0cf1cf-3608-4f98-95f9-7569d0f57a63,date,date,2019-08-31,0
100
+ 333333,c61,pT,#3d0cf1cf-3608-4f98-95f9-7569d0f57a63,T,categorical,3a,0
101
+ ```
102
+
103
+
104
+ ## Anchors
105
+ Often when calculating time based analysis, we need a starting point. An anchor is used to define that starting point. An anchor json follow the same structure as a filter json. **Anchors should have a date field**.
106
+ ```json
107
+ anchor = {'collection':str, 'tag': str, 'field': str, 'exact': [str, str,...], 'between': [float, float]}
108
+ ```
109
+
110
+ ### Tag Sequence
111
+ Sometimes you want to find an ordered scenario, for example you may want to find patients that first have surgery and then adjuvant radiation. Your anchor may have this structure:
112
+ ```json
113
+ anchor = [{'tag': 'surgery'},{'tag':'radiation'}]
114
+ ```
115
+ Note that you are not interested in the type of surgery, or type of radiation.
116
+
117
+ ### Time Delta
118
+ time_delta represents the maximum number of **days** between anchor tags. This is only relavant if there is >1 anchor tag.
119
+
120
+ # Instance
121
+ There may be multiple instances of an anchor sequence. 'instance' defines which one matters.
122
+ instance = 0 - Means that the 1st instance of this anchor sequence will be used.
123
+
124
+ # Time Delta
125
+ Represents the maximum allowable days between anchors.
126
+ ```json
127
+ anchor = [{'tag': 'surgery'},{'tag':'radiation'}]
128
+ time_delta = 60
129
+ # the maximum time between surgery and radaition is 60 days. Useful if you don't want to indentify patients with salvage radiotherapy that typically occurs many months to years later.
130
+ ```
131
+
132
+ ## Data Filtering
133
+ A filter json will be used to find patients that have matching tags. The filter does not need to include all fields. When you want to find patients matching multiple critera specify 'filters' which is an array of filter json.
134
+ ```json
135
+ filter = {'collection':str, 'tag': str, 'field': str, 'exact': [str, str,...], 'between': [float, float]}
136
+ ```
137
+ It may include:
138
+ * collection alone
139
+ ```json
140
+ filter = {'collection':'c61'}
141
+ ```
142
+ * tag alone
143
+ ```json
144
+ filter = {'tag':'psa'}
145
+ ```
146
+ * field alone
147
+ ```json
148
+ filter = {'tag':'psa'}
149
+ ```
150
+ * field with a value that exactly matches
151
+ ```json
152
+ filter = {'field':'histology', 'exact': ['melanoma', 'squamous-cell-carcinoma']}
153
+ ```
154
+ * field with a value that is a number and is between two values
155
+ ```json
156
+ filter = {'field':'psa', 'between': [0.2, 0.5]}
157
+ ```
158
+ * or a combination of the above
159
+ ```json
160
+ filter = {'tag':'psa', 'field':'psa', 'between': [0.2, 0.5]}
161
+ ```
162
+ When you want to find patients matching multiple critera specify 'filters' which is an array of filter json.<br>The below filters finds patients who have both gleason grade group 4 OR 5, AND psa between 0.2-0.5.
163
+ ```json
164
+ filters = [{'field':'gleason-grade-group', 'exact': [4,5]}, {'tag':'psa', 'field':'psa', 'between': [0.2, 0.5]}]
165
+ ```
166
+
167
+ ### Search Range
168
+ The represents the time period before and after the anchor should be examined for the filters criteria (units: days).
169
+ <br>
170
+ For example, imagine you are researching prostate cancer patients getting radiation. You are interested in looking at patients with a pre-RT psa >=20 ng/mL.
171
+ ```json
172
+ anchors = [{'tag':'radiation'}]
173
+ filters = [{'tag':'psa', 'field':'psa', 'between': [20, 10000]}]
174
+ search_range = [-90, 1] # Include patients who had a PSA >20 ng/mL 90 days before starting radiation, or 1 day after radiotherapy.
175
+
176
+ ```
@@ -0,0 +1,157 @@
1
+ # GazooResearchUtils
2
+ GazooResearchUtils is a python library whose purpose is to analyze medical data from GazooResearch.
3
+
4
+
5
+ ## Example output from GazooResearch prostate-data.csv
6
+ The data is denormalized on fields, but ultimately has this hierarchy.
7
+ id -> collection -> tag -> (field, data_type, value, phi)
8
+
9
+
10
+ ### Column descriptions are as follows
11
+ id: patient identification
12
+ collection: A collection of related tags
13
+ tag: name of tag (eg. dob, psa)
14
+ tag_id: Unique identifier
15
+ field: tag name (date, value, date)
16
+ data_type: data type held in the value column. Options are: text, categorical, number, date). dates will be of this form YYYY-MM-DD
17
+ value: value of field
18
+ phi: 0 or 1, depending on if the data element is protected health information
19
+
20
+ ### Issues
21
+ The value field may be empty, or will contain data conforming to the data_type structure.
22
+
23
+ ```csv
24
+ id,collection,tag,tag_id,field,data_type,value,phi
25
+ 111111,0,id,#6bed55ed-f844-4c88-ab74-af0e74aa2547,mrn,text,111111,1
26
+ 111111,0,last-name,bd7e898c-9732-4320-8227-a1b90cc8c80e,value,text,Bing,1
27
+ 111111,0,first-name,#4ff0ace3-e804-4d55-97a0-22cc6f927327,value,text,Chandler,1
28
+ 111111,0,dob,#5578f001-b34b-4465-b699-8c8ff6c11d89,date,date,1952-12-17,0
29
+ 111111,0,document,#ce5ab218-8e98-417b-b843-965ea637ca57,date,date,2023-12-06,0
30
+ 111111,0,document,#ce5ab218-8e98-417b-b843-965ea637ca57,type,categorical,clinical,0
31
+ 111111,c61,surgery,#6082ea75-06c3-4082-9c69-918d0df8c619,date,date,2010-01-01,0
32
+ 111111,c61,surgery,#6082ea75-06c3-4082-9c69-918d0df8c619,type,categorical,prostatectomy-lymphadenectomy,0
33
+ 111111,c61,surgery,#6082ea75-06c3-4082-9c69-918d0df8c619,target-id,text,prostate,0
34
+ 111111,c61,R,#358ebce7-9e7d-441c-a976-38d02d3da58e,date,date,2010-01-01,0
35
+ 111111,c61,R,#358ebce7-9e7d-441c-a976-38d02d3da58e,R,categorical,0,0
36
+ 111111,c61,pT,#2485755d-aa2a-4fa9-a263-4d11c9370145,date,date,2010-01-01,0
37
+ 111111,c61,pT,#2485755d-aa2a-4fa9-a263-4d11c9370145,T,categorical,2c,0
38
+ 111111,c61,pN,#8d04921a-cee6-4c7c-9eb2-d954c1b33008,date,date,2010-01-01,0
39
+ 111111,c61,pN,#8d04921a-cee6-4c7c-9eb2-d954c1b33008,N,categorical,0,0
40
+ 111111,c61,pN,#8d04921a-cee6-4c7c-9eb2-d954c1b33008,involved-lymph-nodes,number,,0
41
+ 111111,c61,pN,#8d04921a-cee6-4c7c-9eb2-d954c1b33008,total-lymph-nodes,number,,0
42
+ 111111,c61,gleason-grade-group,#55109b94-41fe-4b11-a47a-824970ab9dfb,date,date,2010-01-01,0
43
+ 111111,c61,gleason-grade-group,#55109b94-41fe-4b11-a47a-824970ab9dfb,value,categorical,2,0
44
+ 111111,c61,gleason-grade-group,#55109b94-41fe-4b11-a47a-824970ab9dfb,target-id,text,prostate,0
45
+ 111111,c61,psa,64987467-bcc2-4c23-a943-899467d93981,date,date,2019-02-22,0
46
+ 111111,c61,psa,64987467-bcc2-4c23-a943-899467d93981,value,number,0.28,0
47
+ 111111,c61,psa,64987467-bcc2-4c23-a943-899467d93981,units,categorical,ng/ml,0
48
+ 111111,c61,psa,91a5221d-de16-4af9-acb6-82b7d37ed118,date,date,2019-06-12,0
49
+ 111111,c61,psa,91a5221d-de16-4af9-acb6-82b7d37ed118,value,number,0.31,0
50
+ 111111,c61,psa,91a5221d-de16-4af9-acb6-82b7d37ed118,units,categorical,ng/ml,0
51
+ 111111,c61,psa,6ed2dc02-af27-4395-a73e-36af30b7fed6,date,date,2023-12-06,0
52
+ 111111,c61,psa,6ed2dc02-af27-4395-a73e-36af30b7fed6,value,number,0.01,0
53
+ 111111,c61,psa,6ed2dc02-af27-4395-a73e-36af30b7fed6,units,categorical,ng/ml,0
54
+ 111111,c61,androgen-deprivation-therapy,#ed2d15d6-2650-41fe-af7d-e9b6ac1140d6,start-date,date,2019-07-15,0
55
+ 111111,c61,androgen-deprivation-therapy,#ed2d15d6-2650-41fe-af7d-e9b6ac1140d6,end-date,date,2019-12-06,0
56
+ 111111,c61,androgen-deprivation-therapy,#ed2d15d6-2650-41fe-af7d-e9b6ac1140d6,medication,categorical,leuprolide,0
57
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,start-date,date,2019-08-15,0
58
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,end-date,date,2019-10-03,0
59
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,field,categorical,prostate-bed-pelvic-lymph-nodes,0
60
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,dose,number,,0
61
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,unit,categorical,Gy,0
62
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,fractions,number,,0
63
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,technique,categorical,unknown,0
64
+ 111111,c61,external-radiation,#407ad0f8-a8ef-4e21-a41c-6ba11a85d777,target-id,text,prostate,0
65
+ 111111,c61,biochemical-progression,#e6458863-ceba-4194-a361-df96407d5c3a,date,date,,0
66
+ 111111,c61,biochemical-progression,#e6458863-ceba-4194-a361-df96407d5c3a,type,categorical,aua,0
67
+ 111111,0,last-name,#3dd60c0d-d51d-4c4a-8250-715a8f415207,value,text,Bing,1
68
+ 111111,0,id,#1c9d95e8-7d8b-4102-990b-02ebea1e9a14,mrn,text,111111,1
69
+ 111111,0,dob,#47a681ae-23a8-41e8-b569-32039d3f47b4,date,date,1952-12-17,0
70
+ 111111,c61,psa,#b482b981-cf18-420f-b518-d3f6279f03c5,date,date,2019-02-22,0
71
+ 111111,c61,psa,#b482b981-cf18-420f-b518-d3f6279f03c5,value,number,0.28,0
72
+ 111111,c61,psa,#b482b981-cf18-420f-b518-d3f6279f03c5,units,categorical,ng/ml,0
73
+ 333333,0,id,c918371b-01f7-49ee-acd8-b00dee6e49e9,mrn,text,333333,1
74
+ 333333,0,first-name,dc110270-d5c1-431c-8f90-86459bed3a36,value,text,Joey,1
75
+ 333333,0,last-name,2d9ae449-8d3f-4493-82a8-75321f4df6cd,value,text,Tribbiani,1
76
+ 333333,0,dob,d1044870-b049-4465-b306-e0eb1a20b8c2,date,date,1948-01-22,0
77
+ 333333,c61,surgery,#a5b2b0b0-1752-401f-a4d6-63f41dec128b,date,date,2019-08-31,0
78
+ 333333,c61,surgery,#a5b2b0b0-1752-401f-a4d6-63f41dec128b,type,categorical,prostatectomy,0
79
+ 333333,c61,surgery,#a5b2b0b0-1752-401f-a4d6-63f41dec128b,target-id,text,prostate,0
80
+ 333333,c61,pT,#3d0cf1cf-3608-4f98-95f9-7569d0f57a63,date,date,2019-08-31,0
81
+ 333333,c61,pT,#3d0cf1cf-3608-4f98-95f9-7569d0f57a63,T,categorical,3a,0
82
+ ```
83
+
84
+
85
+ ## Anchors
86
+ Often when calculating time based analysis, we need a starting point. An anchor is used to define that starting point. An anchor json follow the same structure as a filter json. **Anchors should have a date field**.
87
+ ```json
88
+ anchor = {'collection':str, 'tag': str, 'field': str, 'exact': [str, str,...], 'between': [float, float]}
89
+ ```
90
+
91
+ ### Tag Sequence
92
+ Sometimes you want to find an ordered scenario, for example you may want to find patients that first have surgery and then adjuvant radiation. Your anchor may have this structure:
93
+ ```json
94
+ anchor = [{'tag': 'surgery'},{'tag':'radiation'}]
95
+ ```
96
+ Note that you are not interested in the type of surgery, or type of radiation.
97
+
98
+ ### Time Delta
99
+ time_delta represents the maximum number of **days** between anchor tags. This is only relavant if there is >1 anchor tag.
100
+
101
+ # Instance
102
+ There may be multiple instances of an anchor sequence. 'instance' defines which one matters.
103
+ instance = 0 - Means that the 1st instance of this anchor sequence will be used.
104
+
105
+ # Time Delta
106
+ Represents the maximum allowable days between anchors.
107
+ ```json
108
+ anchor = [{'tag': 'surgery'},{'tag':'radiation'}]
109
+ time_delta = 60
110
+ # the maximum time between surgery and radaition is 60 days. Useful if you don't want to indentify patients with salvage radiotherapy that typically occurs many months to years later.
111
+ ```
112
+
113
+ ## Data Filtering
114
+ A filter json will be used to find patients that have matching tags. The filter does not need to include all fields. When you want to find patients matching multiple critera specify 'filters' which is an array of filter json.
115
+ ```json
116
+ filter = {'collection':str, 'tag': str, 'field': str, 'exact': [str, str,...], 'between': [float, float]}
117
+ ```
118
+ It may include:
119
+ * collection alone
120
+ ```json
121
+ filter = {'collection':'c61'}
122
+ ```
123
+ * tag alone
124
+ ```json
125
+ filter = {'tag':'psa'}
126
+ ```
127
+ * field alone
128
+ ```json
129
+ filter = {'tag':'psa'}
130
+ ```
131
+ * field with a value that exactly matches
132
+ ```json
133
+ filter = {'field':'histology', 'exact': ['melanoma', 'squamous-cell-carcinoma']}
134
+ ```
135
+ * field with a value that is a number and is between two values
136
+ ```json
137
+ filter = {'field':'psa', 'between': [0.2, 0.5]}
138
+ ```
139
+ * or a combination of the above
140
+ ```json
141
+ filter = {'tag':'psa', 'field':'psa', 'between': [0.2, 0.5]}
142
+ ```
143
+ When you want to find patients matching multiple critera specify 'filters' which is an array of filter json.<br>The below filters finds patients who have both gleason grade group 4 OR 5, AND psa between 0.2-0.5.
144
+ ```json
145
+ filters = [{'field':'gleason-grade-group', 'exact': [4,5]}, {'tag':'psa', 'field':'psa', 'between': [0.2, 0.5]}]
146
+ ```
147
+
148
+ ### Search Range
149
+ The represents the time period before and after the anchor should be examined for the filters criteria (units: days).
150
+ <br>
151
+ For example, imagine you are researching prostate cancer patients getting radiation. You are interested in looking at patients with a pre-RT psa >=20 ng/mL.
152
+ ```json
153
+ anchors = [{'tag':'radiation'}]
154
+ filters = [{'tag':'psa', 'field':'psa', 'between': [20, 10000]}]
155
+ search_range = [-90, 1] # Include patients who had a PSA >20 ng/mL 90 days before starting radiation, or 1 day after radiotherapy.
156
+
157
+ ```
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["uv_build >= 0.9.28, <0.10.0", "twine==6.1.0"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "gazoo-research-utils"
7
+ version = "2.0.1"
8
+ authors = [
9
+ { name="Andrew Lim MD"},
10
+ { name="Megan Lim MD" },
11
+ { name="Christopher Lim MD" },
12
+ { name="Robert Lim MD" },
13
+ ]
14
+ description = "Utilities for the Analysis of Gazoo Research Data"
15
+ readme = "README.md"
16
+ requires-python = ">=3.11"
17
+ classifiers = [
18
+ "Programming Language :: Python :: 3",
19
+ "Operating System :: OS Independent",
20
+ ]
21
+ license = "MIT"
22
+ license-files = ["LICEN[CS]E*"]
23
+ dependencies = [
24
+ "lifelines >= 0.28.0", "pandas>=3.0.0", "pydantic>=2.12.5"
25
+ ]
26
+
27
+ [project.urls]
28
+ Homepage = "https://gazooresearch.com/"
29
+
30
+ [project.optional-dependencies]
31
+ dev = [
32
+ "pytest>=7.4.0",
33
+ "pytest-cov>=4.1.0",
34
+ ]