-
Notifications
You must be signed in to change notification settings - Fork 4
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
Conversation
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.
CervicalCancer.docx
Here is the draft write-up
# this was not assigned here at outset because baseline value of hv_inf was not accessible - it is assigned | ||
# st start of main polling event below |
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 think maybe Tara has changed this in the HIV module as I remember discussing with her.
src/tlo/methods/cervical_cancer.py
Outdated
|
||
# ----- SCHEDULE LOGGING EVENTS ----- | ||
# Schedule logging event to happen immediately | ||
sim.schedule_event(CervicalCancerLoggingEvent(self), sim.date + DateOffset(months=0)) |
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 ?
sim.schedule_event(CervicalCancerLoggingEvent(self), sim.date + DateOffset(months=0)) | ||
|
||
# ----- SCHEDULE MAIN POLLING EVENTS ----- | ||
# Schedule main polling event to happen immediately |
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.
or shall I schedule it immediately ?
src/tlo/methods/tb.py
Outdated
@@ -20,7 +20,7 @@ | |||
from tlo.util import random_date | |||
|
|||
logger = logging.getLogger(__name__) | |||
logger.setLevel(logging.INFO) | |||
logger.setLevel(logging.CRITICAL) |
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.
yes thanks
src/tlo/simulation.py
Outdated
@@ -16,7 +16,7 @@ | |||
from tlo.progressbar import ProgressBar | |||
|
|||
logger = logging.getLogger(__name__) | |||
logger.setLevel(logging.INFO) | |||
logger.setLevel(logging.CRITICAL) |
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
src/tlo/simulation.py
Outdated
@@ -82,7 +82,7 @@ def __init__(self, *, start_date: Date, seed: int = None, log_config: dict = Non | |||
self.rng = np.random.RandomState(np.random.MT19937(self._seed_seq)) | |||
|
|||
def configure_logging(self, filename: str = None, directory: Union[Path, str] = "./outputs", | |||
custom_levels: Dict[str, int] = None, suppress_stdout: bool = False): | |||
custom_levels: Dict[str, int] = None, suppress_stdout: bool = True): |
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.
OK
src/tlo/simulation.py
Outdated
# print(stats_dict) | ||
|
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.
yes I will keep in while I am still thinking of using it.
# todo: not sure what is wrong with this assert as I am fairly certain the intended assert is true | ||
|
||
# assert set(sim.modules['SymptomManager'].who_has('vaginal_bleeding')).issubset( | ||
# df.index[df.ce_cc_ever]) |
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.
So how do I change that ?
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.
Perhaps logging must start when polling starts or a month after polling judging by this parameter r_vaginal_bleeding_cc_stage1
.
# Conflicts: # resources/ResourceFile_Bladder_Cancer.xlsx # src/tlo/methods/enhanced_lifestyle.py # src/tlo/methods/hsi_generic_first_appts.py # src/tlo/simulation.py
I'm merging in and refactored to include the logic intended when presenting at first appointment (non-emergency), namely. (@andrew-phillips-1 - this is because since you started work on this, we've refactored this so that the actions to do in that appointment and coded into the module itself.) # If the symptoms include vaginal bleeding:
if 'vaginal_bleeding' in symptoms:
schedule_hsi(
HSI_CervicalCancerPresentationVaginalBleeding(
person_id=person_id,
module=sim.modules['CervicalCancer']
),
priority=0,
topen=sim.date,
tclose=None)
if 'chosen_via_screening_for_cin_cervical_cancer' in symptoms:
schedule_hsi(
HSI_CervicalCancer_AceticAcidScreening(
person_id=person_id,
module=sim.modules['CervicalCancer']
),
priority=0,
topen=sim.date,
tclose=None)
if 'chosen_xpert_screening_for_hpv_cervical_cancer' in symptoms:
schedule_hsi(
HSI_CervicalCancer_XpertHPVScreening(
person_id=person_id,
module=sim.modules['CervicalCancer']
),
priority=0,
topen=sim.date,
tclose=None) |
odds_ratio_health_seeking_in_adults=1.00) | ||
) | ||
|
||
# in order to implement screening for cervical cancer creating a dummy symptom - likely there is a better way |
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.
The comment is right here -- this is having the desired effect, but we would rather not use the 'symptoms' in this way.
Instead, for the individuals that are chosen to be screened, create and schedule the HSI event directly.
e.g. for each indivisual to be screened... make an HSI_Event_CervicalCancer_Screening..... and in that event, do whatever is required for the sceening. (might be the same as happens in the generic appointment, in which case point them both to the same function)
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 - I will see if I can make that work.
|
||
# ----- HSI FOR PALLIATIVE CARE ----- | ||
on_palliative_care_at_initiation = df.index[df.is_alive & ~pd.isnull(df.ce_date_palliative_care)] | ||
for person_id in on_palliative_care_at_initiation: |
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.
for scheduling the same class of HSI_Event to multiple people, more efficient to use schedule_batch_of_individual_hsi_events
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.
OK I will look into how to do that
p = self.sim.modules['CervicalCancer'].parameters | ||
|
||
# ------------------- SET INITIAL CE_HPV_CC_STATUS ------------------------------------------------------------------- | ||
# this was done here and not at outset because baseline value of hv_inf was not accessible |
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.
this is interesting. As HIV is declared a dependency, it should be registered first, and so these properties be available by the time of running initialise_simulation and initialise_population. Could Wati/Emmanuel have a look at this, please?
If a one-off job is essential (though not sure it should be )... I think neater to put this into its own non-recurring event, and schedule it to occur on first day of simulation only. (That way it doesnt clutter up the main polling event)
|
||
# -------------------- ACQUISITION AND PROGRESSION OF CANCER (ce_hpv_cc_status) ----------------------------------- | ||
|
||
df.ce_new_stage_this_month = False |
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.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
ok will try to amend
|
||
idx_gets_new_stage = gets_new_stage[gets_new_stage].index | ||
|
||
# print(stage, lm, gets_new_stage, idx_gets_new_stage) |
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.
# print(stage, lm, gets_new_stage, idx_gets_new_stage) |
df.loc[idx_gets_new_stage, 'ce_hpv_cc_status'] = stage | ||
df.loc[idx_gets_new_stage, 'ce_new_stage_this_month'] = True | ||
|
||
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 comment
The 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 ce_cc_ever
on the end of this line.
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.
OK thanks
src/tlo/methods/cervical_cancer.py
Outdated
disease_module=self.module | ||
) | ||
|
||
self.sim.modules['SymptomManager'].change_symptom( |
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.
see comment above about symptoms
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.
yes
.when(2, p['rr_hpv_vaccinated']), | ||
Predictor('age_years', conditions_are_mutually_exclusive=True) | ||
.when('.between(0,15)', 0.0) | ||
.when('.between(50,110)', p['rr_hpv_age50plus']), |
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.
.when('.between(50,110)', p['rr_hpv_age50plus']), | |
.when('>50'),p['rr_hpv_age50plus'])``` |
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.
done thanks
LinearModelType.MULTIPLICATIVE, | ||
p['r_cin1_hpv'], | ||
Predictor('ce_hpv_cc_status').when('hpv', 1.0).otherwise(0.0), | ||
Predictor('hv_inf', conditions_are_mutually_exclusive=True) |
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.
lots of these are also 'conditions_are_exhaustive=True' too
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.
changed
|
||
# Assign daly_wt to those with cancer stages before stage4 and have either never been treated or are no longer | ||
# in the stage in which they were treated | ||
disability_series_for_alive_persons.loc[ |
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'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!?
src/tlo/methods/cervical_cancer.py
Outdated
disease_module=self.module | ||
) | ||
|
||
# vaccinating 9 year old girls - this only uncommented for testing - vaccination is controlled by epi |
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.
uncomment?
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 think we don't need that code as vaccination is controlled elsewhere
|
||
for person_id in selected_to_die: | ||
self.sim.schedule_event( | ||
InstantaneousDeath(self.module, person_id, "CervicalCancer"), self.sim.date |
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.
ideally, we'd distribute in time these deaths so that they don;t clump on first of the month (but this is a not a big deal).
The utilility function random_date
(in utils) can be used
def __init__(self, module, person_id): | ||
super().__init__(module, person_id=person_id) | ||
|
||
self.TREATMENT_ID = "CervicalCancer_XpertHPVScreening" |
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 think some equipment declaration needed for this (and others?) HSI_Events?
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.
yes I will be talking to Joe about that
assert not pd.isnull(df.at[person_id, "ce_date_diagnosis"]) | ||
assert not pd.isnull(df.at[person_id, "ce_date_treatment"]) | ||
|
||
days_threshold_365 = 365 |
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.
could use pd.Dateoffset(years =...) instead of the number of days for ease for reading/comprehension
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}) | ||
|
||
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 comment
The reason will be displayed to describe this comment to others. Learn more.
move to using the logger:
i.e. logger.info(key='cervical_cancer_stats_every_month', description='XX', data=out)
…to cervical_cancer_
Here's a first draft of this module. I need to do another search to try to find additional data for calibration.
I couldn't upload the draft write as it was asking me to use the command line and Git LFS.