-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cervical cancer #1287
base: master
Are you sure you want to change the base?
Cervical cancer #1287
Changes from 1 commit
0393e17
bc1ac59
5a66e5d
b24c6bd
cc488bd
144644a
f1015b5
f2b44b0
0d06e44
c964058
1b0226b
fdcea86
7f13653
356973c
91efced
443401b
9e60e5c
8f5e8f0
5464169
86a503f
242de2c
77a2808
41b9743
0fe0ee1
b3d77af
b242de7
9ed44ac
41d1152
fdbd1ac
38e34e3
c665214
4470892
e6008cf
90bbbb9
7beb619
b42dea3
0a3f2d6
ee6e3c1
12f312f
a4cfcc8
e30fa14
28ffe64
416027c
cae6c2c
6007b2a
5b67b62
68f14cc
de34cc5
6a27f52
ca8a1f5
01398e9
3e4508b
e30044f
2c53eb2
9138a01
73682ea
445b6b3
d727856
8dcc0e6
6f25468
910a080
e81857e
890b245
eef200f
00b5944
381a307
23724e8
5373f3a
2d96458
7673ed0
1501739
680be51
0e60aa3
519ca33
5e648e9
b3a4202
e574a13
4ecf108
e8bcffe
ed8602d
91475a4
15e2df9
ffe10d8
c357295
66ad5f5
f3a9d24
5284d9e
3a58fa4
563cff7
ea1e540
7ba6797
f92de78
fa8ee61
4fad45a
8e605b8
1d1a19d
2743ade
402e5a1
2299c8f
f7971d6
7bfb2ba
7706c01
1d8e786
dcd9270
d35718f
0349109
e8821b9
a2dddc0
f244070
c814528
63c22e5
d19e617
c413fc6
9c5cf13
bb1ddd8
3b09512
bb2642c
843e184
0eb4871
ec94bbe
1b705f4
1ce601b
5d69604
8263482
5ee1ae4
9ef7c8d
a0b2b12
a520791
1b7016d
e77278f
9a57fcb
2a9e18c
1bd4268
130fee0
ce4fa2e
4329d8a
4985355
61e537d
5cf3315
bc3ec13
eeefe7d
2a49fcc
a81d5ec
201c2eb
13e0900
f181070
dc4d263
7cc3342
da0ca1d
02c6f53
b6e5a49
212bb6c
a12fe17
ade941b
9625665
63677bb
8ee9c70
5326af8
d419bd2
e7a9b9a
fea6310
8a7cf3e
81e1daf
12a308b
23b0240
758fa41
926633b
9ba2bb9
62def2b
0e3361b
714f230
1f3d2d8
185ecde
4802ab9
012bdcd
b1c6db3
81a0b09
c85db36
8648c8c
3971e47
998c0f8
cb15ecd
ed32c08
10c32e2
905735e
c7124d5
4d19b79
1d39d90
43a21c0
58f3b7c
d50753d
8a0d983
baf4ede
46be8d4
2c29fa9
abbf7a1
9be93d2
f78733e
16e5cc7
68e87b5
1164682
9ad9687
aea457f
52de860
bc598c1
f3aa9c1
248b468
eb59e52
e20be10
f5a4e4e
1d34917
e0c117c
89b48db
ac3b861
10afb02
0e9c35e
b33cec9
2e2c483
58c3922
bd3317e
e3a909e
6e24798
14a593b
7cd9e79
ead5cb7
32791bd
817d15d
339c06a
243d953
ec351f2
79d7d06
b18a74e
4ce6962
c4de745
26f5911
b41f0c2
2777ff7
07f47b0
9859bed
dab92b1
d21b9c8
4fe0280
2607b63
30e9cb1
249ffe7
4bdf8a8
1061c30
002547f
d073bb9
3512612
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,6 +46,7 @@ def __init__(self, name=None, resourcefilepath=None): | |
self.linear_models_for_progression_of_hpv_cc_status = dict() | ||
self.lm_onset_vaginal_bleeding = None | ||
self.daly_wts = dict() | ||
self.cervical_cancer_cons = dict() | ||
|
||
INIT_DEPENDENCIES = { | ||
'Demography', 'SimplifiedBirths', 'HealthSystem', 'Lifestyle', 'SymptomManager' | ||
|
@@ -339,6 +340,15 @@ def initialise_population(self, population): | |
# For simplicity we assume all these are null at baseline - we don't think this will influence population | ||
# status in the present to any significant degree | ||
|
||
# consumables | ||
|
||
def get_cervical_cancer_item_codes(self): | ||
get_items = self.sim.modules['HealthSystem'].get_item_code_from_item_name | ||
|
||
self.cervical_cancer_cons['cervical_cancer_screening_via'] = {get_items('Clean delivery kit'): 1} | ||
self.cervical_cancer_cons['cervical_cancer_screening_via_optional'] = {get_items('gloves'): 1} | ||
|
||
# todo: add others as above | ||
|
||
def initialise_simulation(self, sim): | ||
""" | ||
|
@@ -350,6 +360,8 @@ def initialise_simulation(self, sim): | |
* Schedule the palliative care appointments for those that are on palliative care at initiation | ||
""" | ||
|
||
self.get_cervical_cancer_item_codes() | ||
|
||
# ----- SCHEDULE LOGGING EVENTS ----- | ||
# Schedule logging event to happen immediately | ||
sim.schedule_event(CervicalCancerLoggingEvent(self), sim.date + DateOffset(months=0)) | ||
|
@@ -629,6 +641,11 @@ def report_daly_values(self): | |
) | ||
] = self.daly_wts['stage_1_3_treated'] | ||
|
||
# todo: check | ||
# I'm a bit surprised this works, because the masks being used are wrt to df, but the indexing | ||
# into a series with a difference index. Maybe it only works as long as everyone is alive!? | ||
|
||
|
||
# Assign daly_wt to those in stage4 cancer (who have not had palliative care) | ||
disability_series_for_alive_persons.loc[ | ||
(df.ce_hpv_cc_status == "stage4") & | ||
|
@@ -726,6 +743,14 @@ def apply(self, population): | |
|
||
# -------------------- ACQUISITION AND PROGRESSION OF CANCER (ce_hpv_cc_status) ----------------------------------- | ||
|
||
# todo: | ||
# this is being broadcast. it should be lmited to those with is_alive: ie. df.loc[df.is_alive, | ||
# 'cc_new_stage_this_month'] = False | ||
# As I expect this is going to be over-written (further down) it would be more efiicent to not | ||
# write it into the main sim.population.props df yet (reading/writing there is time-consuming), | ||
# and instead do one write to it at the end of the event, when everything is settled. | ||
|
||
|
||
df.ce_new_stage_this_month = False | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is being broadcast. it should be lmited to those with is_alive: ie. df.loc[df.is_alive, 'cc_new_stage_this_month'] = False As I expect this is going to be over-written (further down) it would be more efiicent to not write it into the main sim.population.props df yet (reading/writing there is time-consuming), and instead do one write to it at the end of the event, when everything is settled. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok will try to amend |
||
|
||
df['ce_hiv_unsuppressed'] = ((df['hv_art'] == 'on_not_vl_suppressed') | (df['hv_art'] == 'not')) & (df['hv_inf']) | ||
|
@@ -743,6 +768,18 @@ def apply(self, population): | |
df.loc[idx_gets_new_stage, 'ce_hpv_cc_status'] = stage | ||
df.loc[idx_gets_new_stage, 'ce_new_stage_this_month'] = True | ||
|
||
|
||
# todo: | ||
# this is also broadcasting to all dataframe (including dead peple and never alive people, | ||
# potentially). | ||
# | ||
# Also, it will over-write to False those people not in any of those categories. I can see | ||
# that this will not violate the logic, but the safest thing would be to also include in the | ||
# chanied union statement the current value, in order to absolute prevent reversions... i.e. | ||
# add in ce_cc_ever on the end of this line. | ||
|
||
|
||
|
||
df['ce_cc_ever'] = ((df.ce_hpv_cc_status == 'stage1') | (df.ce_hpv_cc_status == 'stage2a') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is also broadcasting to all dataframe (including dead peple and never alive people, potentially). Also, it will over-write to False those people not in any of those categories. I can see that this will not violate the logic, but the safest thing would be to also include in the chanied union statement the current value, in order to absolute prevent reversions... i.e. add in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK thanks |
||
| (df.ce_hpv_cc_status == 'stage2b') | (df.ce_hpv_cc_status == 'stage3') | ( | ||
df.ce_hpv_cc_status == 'stage4') | ||
|
@@ -753,6 +790,17 @@ def apply(self, population): | |
|
||
# in future this may be triggered by family planning visit | ||
|
||
# todo: | ||
# Instead, for the individuals that are chosen to be screened, create and schedule the HSI | ||
# event directly. | ||
# | ||
# e.g. for each individual to be screened... make an HSI_Event_CervicalCancer_Screening..... | ||
# and in that event, do whatever is required for the screening. (might be the same as happens | ||
# in the generic appointment, in which case point them both to the same function) | ||
|
||
|
||
|
||
|
||
df.ce_selected_for_via_this_month = False | ||
|
||
eligible_population = df.is_alive & (df.sex == 'F') & (df.age_years >= 30) & (df.age_years < 50) & \ | ||
|
@@ -802,10 +850,6 @@ def apply(self, population): | |
disease_module=self.module | ||
) | ||
|
||
# vaccinating 9 year old girls - this only uncommented for testing - vaccination is controlled by epi | ||
# age9_f_idx = df.index[(df.is_alive) & (df.age_exact_years > 9) & (df.age_exact_years < 90) & (df.sex == 'F')] | ||
# df.loc[age9_f_idx, 'va_hpv'] = 1 | ||
|
||
# -------------------- DEATH FROM cervical CANCER --------------------------------------- | ||
# There is a risk of death for those in stage4 only. Death is assumed to go instantly. | ||
stage4_idx = df.index[df.is_alive & (df.ce_hpv_cc_status == "stage4")] | ||
|
@@ -818,6 +862,8 @@ def apply(self, population): | |
) | ||
df.loc[selected_to_die, 'ce_date_death'] = self.sim.date | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is date of death not recorded already in demography? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah so I should use ''date_of_death' rather than 'ce_date_death' ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You don't need to store the date of death yourself, and it's stored in the demography log. That said, there's no harm to it, other than memory wastage. |
||
|
||
# todo: distribute death dates across next 30 days | ||
|
||
|
||
# --------------------------------------------------------------------------------------------------------- | ||
# HEALTH SYSTEM INTERACTION EVENTS | ||
|
@@ -853,14 +899,20 @@ def apply(self, person_id, squeeze_factor): | |
hsi_event=self | ||
) | ||
|
||
if dx_result: | ||
cons_availability = self.get_consumables(item_code=self.cervical_cancer_cons['cervical_cancer_screening_via'], | ||
optional_item_codes=self.cervical_cancer_cons['cervical_cancer_screening_via_optional']) | ||
|
||
self.add_equipment({'Drip stand', 'Infusion pump'}) | ||
self.add_equipment(self.healthcare_system.equipment.from_pkg_names('Major Surgery')) | ||
|
||
if dx_result and cons_availability: | ||
df.at[person_id, 'ce_via_cin_ever_detected'] = True | ||
|
||
if dx_result and (df.at[person_id, 'ce_hpv_cc_status'] == 'cin1' | ||
if (df.at[person_id, 'ce_hpv_cc_status'] == 'cin1' | ||
or df.at[person_id, 'ce_hpv_cc_status'] == 'cin2' | ||
or df.at[person_id, 'ce_hpv_cc_status'] == 'cin3' | ||
): | ||
hs.schedule_hsi_event( | ||
hs.schedule_hsi_event( | ||
hsi_event=HSI_CervicalCancer_Cryotherapy_CIN( | ||
module=self.module, | ||
person_id=person_id | ||
|
@@ -870,19 +922,19 @@ def apply(self, person_id, squeeze_factor): | |
tclose=None | ||
) | ||
|
||
if dx_result and (df.at[person_id, 'ce_hpv_cc_status'] == 'stage1' | ||
elif (df.at[person_id, 'ce_hpv_cc_status'] == 'stage1' | ||
or df.at[person_id, 'ce_hpv_cc_status'] == 'stage2a' | ||
or df.at[person_id, 'ce_hpv_cc_status'] == 'stage2b' | ||
or df.at[person_id, 'ce_hpv_cc_status'] == 'stage3' | ||
or df.at[person_id, 'ce_hpv_cc_status'] == 'stage4'): | ||
hs.schedule_hsi_event( | ||
hsi_event=HSI_CervicalCancer_Biopsy( | ||
module=self.module, | ||
person_id=person_id | ||
), | ||
priority=0, | ||
topen=self.sim.date, | ||
tclose=None | ||
hs.schedule_hsi_event( | ||
hsi_event=HSI_CervicalCancer_Biopsy( | ||
module=self.module, | ||
person_id=person_id | ||
), | ||
priority=0, | ||
topen=self.sim.date, | ||
tclose=None | ||
) | ||
|
||
# sy_chosen_via_screening_for_cin_cervical_cancer reset to 0 | ||
|
@@ -1199,6 +1251,10 @@ def apply(self, person_id, squeeze_factor): | |
assert not pd.isnull(df.at[person_id, "ce_date_diagnosis"]) | ||
assert not pd.isnull(df.at[person_id, "ce_date_treatment"]) | ||
|
||
# todo: | ||
# could use pd.Dateoffset(years =...) instead of the number of days for ease for | ||
# reading/comprehension | ||
|
||
days_threshold_365 = 365 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could use pd.Dateoffset(years =...) instead of the number of days for ease for reading/comprehension |
||
days_threshold_1095 = 1095 | ||
days_threshold_1825 = 1825 | ||
|
@@ -1279,6 +1335,15 @@ def apply(self, person_id, squeeze_factor): | |
if pd.isnull(df.at[person_id, "ce_date_palliative_care"]): | ||
df.at[person_id, "ce_date_palliative_care"] = self.sim.date | ||
|
||
|
||
|
||
# todo: | ||
# for scheduling the same class of HSI_Event to multiple people, more | ||
# efficient to use schedule_batch_of_individual_hsi_events | ||
|
||
|
||
|
||
|
||
# Schedule another instance of the event for one month | ||
hs.schedule_hsi_event( | ||
hsi_event=HSI_CervicalCancer_PalliativeCare( | ||
|
@@ -1300,7 +1365,6 @@ class CervicalCancerLoggingEvent(RegularEvent, PopulationScopeEventMixin): | |
|
||
# the use of groupby might be more efficient in computing the statistics below; | ||
|
||
|
||
def __init__(self, module): | ||
"""schedule logging to repeat every 1 month | ||
""" | ||
|
@@ -1435,6 +1499,10 @@ def apply(self, population): | |
out.update({"n_diagnosed_1_year_ago": n_diagnosed_1_year_ago}) | ||
out.update({"n_diagnosed_1_year_ago_died": n_diagnosed_1_year_ago_died}) | ||
|
||
# todo: | ||
# ? move to using the logger: | ||
# i.e. logger.info(key='cervical_cancer_stats_every_month', description='XX', data=out) | ||
mmsuarezcosta marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
print(self.sim.date, 'total_none:', out['total_none'], 'total_hpv:', out['total_hpv'], 'total_cin1:',out['total_cin1'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move to using the logger: |
||
'total_cin2:', out['total_cin2'], 'total_cin3:', out['total_cin3'], 'total_stage1:', out['total_stage1'], | ||
'total_stage2a:', out['total_stage2a'], 'total_stage2b:', out['total_stage2b'], | ||
|
@@ -1527,7 +1595,7 @@ def apply(self, population): | |
selected_rows = df[(df['sex'] == 'F') & (df['age_years'] > 15) & df['is_alive']] | ||
|
||
# pd.set_option('display.max_rows', None) | ||
# print(selected_rows[selected_columns]) | ||
print(selected_rows[selected_columns]) | ||
|
||
# selected_columns = ['sex', 'age_years', 'is_alive'] | ||
# pd.set_option('display.max_rows', None) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why schedule logging event immediately yet polling event is starting a month after? Are we interested in logging defaults also?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know. I think I copied this from another module. Shall I change both to immediate ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems most of the cancer modules are indeed coded like as you did @andrew-phillips-1 . Not sure what the rationale was. I don't think defaults would be a representation of the population at any point. However, other modules have been coded in such a way that logging starts later. Perhaps logging must start when polling starts or a month after polling judging by this parameter
r_vaginal_bleeding_cc_stage1
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andrew-phillips-1. I think logging should happen after a month. Please start with polling event then logging event i.e. see below
This will also agree to your comment here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. @thewati please remind me about incorporating these things when I am working this after you (or of course you could incorporate them if you wish, which would be very helpful)