[docs]classEnvToHuman:def__init__(self,model,verbose:bool=False)->None:self.model=modelself.verbose=verboseasserthasattr(model,"agents"),"EnvToHuman: model needs to have a 'agents' attribute."model.patches.add_vector_property("Psi",length=model.params.nticks+1,dtype=np.float32,default=np.float32(0.0))asserthasattr(model,"params"),"EnvToHuman: model needs to have a 'params' attribute."asserthasattr(model.params,"psi_jt"),("EnvToHuman: model params needs to have a 'psi_jt' (environmental contamination rate) parameter.")psi=model.params.psi_jt# convenience# TODO - use newer laser_core with add_array_property and psi.shapemodel.patches.add_vector_property("beta_env",length=psi.shape[0],dtype=np.float32,default=0.0)assertmodel.patches.beta_env.shape==model.params.psi_jt.shapeassertmodel.params.beta_j0_env.shape[0]==model.patches.beta_env.shape[1]psi_bar=psi.mean(axis=0,keepdims=True)model.patches.beta_env[:,:]=model.params.beta_j0_env.T*(1.0+(psi-psi_bar)/psi_bar)return
[docs]defcheck(self):asserthasattr(self.model.agents,"S"),"EnvToHuman: model agents needs to have a 'S' (susceptible) attribute."asserthasattr(self.model.agents,"E"),"EnvToHuman: model agents needs to have a 'E' (exposed) attribute."asserthasattr(self.model,"patches"),"EnvToHuman: model needs to have a 'patches' attribute."asserthasattr(self.model.patches,"W"),"EnvToHuman: model patches needs to have a 'W' (environmental) attribute."assert"tau_i"inself.model.params,"EnvToHuman: model params needs to have a 'tau_i' (emmigration probability) parameter."assert"theta_j"inself.model.params,("EnvToHuman: model params needs to have a 'theta_j' (fraction of population with WASH) attribute.")assert"kappa"inself.model.params,"EnvToHuman: model params needs to have a 'kappa' (environmental transmission rate) parameter."return
def__call__(self,model,tick:int)->None:Psi=model.patches.Psi[tick+1]W=model.patches.W[tick]tau_i=model.params.tau_ilocal_frac=1-tau_inon_wash=(1-model.params.theta_j)*Wseasonal=model.patches.beta_env[tick]*non_washdenominator=model.params.kappa+Wnormalized=seasonal/denominatorPsi[:]=normalized# PsiSS=model.agents.S[tick]S_next=model.agents.S[tick+1]E_next=model.agents.E[tick+1]# Use S_next here since some S will have been removed by natural mortality and by human-to-human transmissionlocal_s=np.round(S_next*local_frac).astype(S.dtype)infections_s=model.prng.binomial(local_s,-np.expm1(-Psi)).astype(S_next.dtype)S_next-=infections_sE_next+=infections_sassertnp.all(S_next>=0),f"Negative susceptible populations at tick {tick+1}.\n\t{S_next=}"return
[docs]defplot(self,fig:Figure=None):# pragma: no cover_fig=plt.figure(figsize=(12,9),dpi=128,num="Environmental Transmission Rate")iffigisNoneelsefigforipatchinnp.argsort(self.model.params.S_j_initial)[-10:]:plt.plot(self.model.patches.Psi[:,ipatch],label=f"{self.model.params.location_name[ipatch]}")plt.xlabel("Tick")plt.ylabel("Environmental Transmission Rate")plt.legend()yield"Environmental Transmission Rate"return