|
| 1 | +"""Custom analyzers for hpvsim_tanzania.""" |
| 2 | +import numpy as np |
| 3 | +import sciris as sc |
| 4 | +import hpvsim as hpv |
| 5 | +import hpvsim.utils as hpu |
| 6 | + |
| 7 | + |
| 8 | +class cohort_cancers(hpv.Analyzer): |
| 9 | + """Track scaled cancer cases in an ageing cohort from a given start year.""" |
| 10 | + |
| 11 | + def __init__(self, cohort_age=None, start=None, **kwargs): |
| 12 | + super().__init__(**kwargs) |
| 13 | + self.start = start or 2024 |
| 14 | + self.cohort_age = cohort_age or [9, 16] |
| 15 | + self.years = None |
| 16 | + self.results = None |
| 17 | + return |
| 18 | + |
| 19 | + def initialize(self, sim): |
| 20 | + super().initialize() |
| 21 | + self.si = sc.findfirst(sim.res_yearvec, self.start) |
| 22 | + self.npts = len(sim.res_yearvec[self.si:]) |
| 23 | + self.years = sim.res_yearvec[self.si:] |
| 24 | + self.results = np.zeros(self.npts) |
| 25 | + return |
| 26 | + |
| 27 | + def apply(self, sim): |
| 28 | + if sim.yearvec[sim.t] >= self.start: |
| 29 | + li = np.floor(sim.yearvec[sim.t]) |
| 30 | + idx = sc.findfirst(self.years, li) |
| 31 | + ppl = sim.people |
| 32 | + time_elapsed = sim.yearvec[sim.t] - self.start |
| 33 | + current_age_range = [self.cohort_age[0] + time_elapsed, self.cohort_age[1] + time_elapsed] |
| 34 | + cic = (ppl.date_cancerous == sim.t) & (ppl.age >= current_age_range[0]) & (ppl.age <= current_age_range[1]) |
| 35 | + if cic.any(): |
| 36 | + self.results[idx] += sum(ppl.scale[hpu.true(cic)]) |
| 37 | + return |
| 38 | + |
| 39 | + @staticmethod |
| 40 | + def reduce(analyzers, use_mean=False, quantiles=None): |
| 41 | + if quantiles is None: |
| 42 | + quantiles = {'low': 0.1, 'high': 0.9} |
| 43 | + if not isinstance(quantiles, dict): |
| 44 | + try: |
| 45 | + quantiles = {'low': float(quantiles[0]), 'high': float(quantiles[1])} |
| 46 | + except Exception as E: |
| 47 | + errormsg = (f'Could not convert {quantiles} into a quantiles object: must be a dict ' |
| 48 | + f'with keys low, high or a 2-element array ({str(E)})') |
| 49 | + raise ValueError(errormsg) |
| 50 | + |
| 51 | + base_analyzer = analyzers[0] |
| 52 | + reduced_analyzer = sc.dcp(base_analyzer) |
| 53 | + ashape = base_analyzer.results.shape |
| 54 | + new_ashape = ashape + (len(analyzers),) |
| 55 | + raw = np.zeros(new_ashape) |
| 56 | + for a, analyzer in enumerate(analyzers): |
| 57 | + raw[:, a] = analyzer.results |
| 58 | + |
| 59 | + reduced_analyzer.raw = raw |
| 60 | + reduced_analyzer.results = np.quantile(raw, q=0.5, axis=-1) |
| 61 | + reduced_analyzer.low = np.quantile(raw, q=quantiles['low'], axis=-1) |
| 62 | + reduced_analyzer.high = np.quantile(raw, q=quantiles['high'], axis=-1) |
| 63 | + |
| 64 | + sums = raw.sum(axis=0) |
| 65 | + reduced_analyzer.cum_cancers_best = np.quantile(sums, q=0.5) |
| 66 | + reduced_analyzer.cum_cancers_low = np.quantile(sums, q=quantiles['low']) |
| 67 | + reduced_analyzer.cum_cancers_high = np.quantile(sums, q=quantiles['high']) |
| 68 | + |
| 69 | + return reduced_analyzer |
0 commit comments