Exemplo n.º 1
0
def test_plotting():

    torun = [
        'hex2rgb',
        'arraycolors',
        'gridcolors',
        'surf3d',
        'bar3d',
    ]

    if 'hex2rgb' in torun:
        c1 = sc.hex2rgb('#fff')
        c2 = sc.hex2rgb('fabcd8')
        print(c1)
        print(c2)

    if 'arraycolors' in torun:
        n = 1000
        ncols = 5
        arr = pl.rand(n, ncols)
        for c in range(ncols):
            arr[:, c] += c
        x = pl.rand(n)
        y = pl.rand(n)
        colors = sc.arraycolors(arr)
        if doplot:
            pl.figure(figsize=(20, 16))
            for c in range(ncols):
                pl.scatter(x + c, y, s=50, c=colors[:, c])

    if 'gridcolors' in torun:
        colors_a = sc.gridcolors(ncolors=8, demo=doplot)
        colors_b = sc.gridcolors(ncolors=18, demo=doplot)
        colors_c = sc.gridcolors(ncolors=28, demo=doplot)
        print('\n8 colors:', colors_a)
        print('\n18 colors:', colors_b)
        print('\n28 colors:', colors_c)

    if 'surf3d' in torun:
        data = pl.randn(50, 50)
        smoothdata = sc.smooth(data, 20)
        if doplot:
            sc.surf3d(smoothdata)

    if 'bar3d' in torun:
        data = pl.rand(20, 20)
        smoothdata = sc.smooth(data)
        if doplot:
            sc.bar3d(smoothdata)

    return pl.gcf()
Exemplo n.º 2
0
def test_smooth():
    data = pl.randn(200, 100)
    smoothdata = sc.smooth(data, 10)
    if doplot:
        pl.subplot(1, 2, 1)
        pl.pcolor(data)
        pl.subplot(1, 2, 2)
        pl.pcolor(smoothdata)
    return smoothdata
Exemplo n.º 3
0
    def compute_r_eff(self, method='daily', smoothing=2, window=7):
        '''
        Effective reproductive number based on number of people each person infected.

        Args:
            method (str): 'instant' uses daily infections, 'infectious' counts from the date infectious, 'outcome' counts from the date recovered/dead
            smoothing (int): the number of steps to smooth over for the 'daily' method
            window (int): the size of the window used for 'infectious' and 'outcome' calculations (larger values are more accurate but less precise)

        Returns:
            r_eff (array): the r_eff results array
        '''

        # Initialize arrays to hold sources and targets infected each day
        sources = np.zeros(self.npts)
        targets = np.zeros(self.npts)
        window = int(window)

        # Default method -- calculate the daily infections
        if method == 'daily':

            # Find the dates that everyone became infectious and recovered, and hence calculate infectious duration
            recov_inds = self.people.defined('date_recovered')
            dead_inds = self.people.defined('date_dead')
            date_recov = self.people.date_recovered[recov_inds]
            date_dead = self.people.date_dead[dead_inds]
            date_outcome = np.concatenate((date_recov, date_dead))
            inds = np.concatenate((recov_inds, dead_inds))
            date_inf = self.people.date_infectious[inds]
            mean_inf = date_outcome.mean() - date_inf.mean()

            # Calculate R_eff as the mean infectious duration times the number of new infectious divided by the number of infectious people on a given day
            raw_values = mean_inf * self.results['new_infections'].values / (
                self.results['n_infectious'].values + 1e-6)
            len_raw = len(raw_values)  # Calculate the number of raw values
            if len_raw >= 3:  # Can't smooth arrays shorter than this since the default smoothing kernel has length 3
                initial_period = self['dur']['exp2inf']['par1'] + self['dur'][
                    'asym2rec'][
                        'par1']  # Approximate the duration of the seed infections for averaging
                initial_period = int(min(
                    len_raw,
                    initial_period))  # Ensure we don't have too many points
                for ind in range(
                        initial_period):  # Loop over each of the initial inds
                    raw_values[ind] = raw_values[ind:initial_period].mean(
                    )  # Replace these values with their average
                values = sc.smooth(raw_values, smoothing)
                values[:
                       smoothing] = raw_values[:
                                               smoothing]  # To avoid numerical effects, replace the beginning and end with the original
                values[-smoothing:] = raw_values[-smoothing:]
            else:
                values = raw_values

        # Alternate (traditional) method -- count from the date of infection or outcome
        elif method in ['infectious', 'outcome']:

            # Store a mapping from each source to their date
            source_dates = {}

            for t in self.tvec:

                # Sources are easy -- count up the arrays for all the people who became infections on that day
                if method == 'infectious':
                    inds = cvu.true(
                        t == self.people.date_infectious
                    )  # Find people who became infectious on this timestep
                elif method == 'outcome':
                    recov_inds = cvu.true(
                        t == self.people.date_recovered
                    )  # Find people who recovered on this timestep
                    dead_inds = cvu.true(
                        t == self.people.date_dead
                    )  # Find people who died on this timestep
                    inds = np.concatenate((recov_inds, dead_inds))
                sources[t] = len(inds)

                # Create the mapping from sources to dates
                for ind in inds:
                    source_dates[ind] = t

            # Targets are hard -- loop over the transmission tree
            for transdict in self.people.infection_log:
                source = transdict['source']
                if source is not None and source in source_dates:  # Skip seed infections and people with e.g. recovery after the end of the sim
                    source_date = source_dates[source]
                    targets[source_date] += 1

                # for ind in inds:
                #     targets[t] += len(self.people.transtree.targets[ind])

            # Populate the array -- to avoid divide-by-zero, skip indices that are 0
            r_eff = np.divide(targets,
                              sources,
                              out=np.full(self.npts, np.nan),
                              where=sources > 0)

            # Use stored weights calculate the moving average over the window of timesteps, n
            num = np.nancumsum(r_eff * sources)
            num[window:] = num[window:] - num[:-window]
            den = np.cumsum(sources)
            den[window:] = den[window:] - den[:-window]
            values = np.divide(num,
                               den,
                               out=np.full(self.npts, np.nan),
                               where=den > 0)

        # Method not recognized
        else:
            errormsg = f'Method must be "daily", "infected", or "outcome", not "{method}"'
            raise ValueError(errormsg)

        # Set the values and return
        self.results['r_eff'].values[:] = values

        return self.results['r_eff'].values
Exemplo n.º 4
0
"""
Version: 2019jan10
"""

import pylab as pl
import sciris as sc

torun = [
    'smooth',
]

if 'doplot' not in locals(): doplot = True

if 'smooth' in torun:
    data = pl.randn(200, 100)
    smoothdata = sc.smooth(data, 10)
    if doplot:
        pl.subplot(1, 2, 1)
        pl.pcolor(data)
        pl.subplot(1, 2, 2)
        pl.pcolor(smoothdata)
Exemplo n.º 5
0
    def compute_r_eff(self, method='daily', smoothing=2, window=7):
        '''
        Effective reproductive number based on number of people each person infected.

        Args:
            method (str): 'instant' uses daily infections, 'infectious' counts from the date infectious, 'outcome' counts from the date recovered/dead
            smoothing (int): the number of steps to smooth over for the 'daily' method
            window (int): the size of the window used for 'infectious' and 'outcome' calculations (larger values are more accurate but less precise)

        Returns:
            r_eff (array): the r_eff results array
        '''

        # Initialize arrays to hold sources and targets infected each day
        sources = np.zeros(self.npts)
        targets = np.zeros(self.npts)
        window = int(window)

        # Default method -- calculate the daily infections
        if method == 'daily':

            # Find the dates that everyone became infectious and recovered, and hence calculate infectious duration
            recov_inds = self.people.defined('date_recovered')
            dead_inds = self.people.defined('date_dead')
            date_recov = self.people.date_recovered[recov_inds]
            date_dead = self.people.date_dead[dead_inds]
            date_outcome = np.concatenate((date_recov, date_dead))
            inds = np.concatenate((recov_inds, dead_inds))
            date_inf = self.people.date_infectious[inds]
            mean_inf = date_outcome.mean() - date_inf.mean()

            # Calculate R_eff as the mean infectious duration times the number of new infectious divided by the number of infectious people on a given day
            values = mean_inf * self.results['new_infections'].values / (
                self.results['n_infectious'].values + 1e-6)
            if len(values) >= 3:  # Can't smooth arrays shorter than this
                values = sc.smooth(values, smoothing)

        # Alternate (traditional) method -- count from the date of infection or outcome
        elif method in ['infectious', 'outcome']:

            for t in self.tvec:

                # Sources are easy -- count up the arrays
                if method == 'infectious':
                    inds = cvu.true(
                        t == self.people.date_infectious
                    )  # Find people who became infectious on this timestep
                elif method == 'outcome':
                    recov_inds = cvu.true(
                        t == self.people.date_recovered
                    )  # Find people who recovered on this timestep
                    dead_inds = cvu.true(
                        t == self.people.date_dead
                    )  # Find people who died on this timestep
                    inds = np.concatenate((recov_inds, dead_inds))
                sources[t] = len(inds)

                # Targets are hard -- loop over the transmission tree
                for ind in inds:
                    targets[t] += len(self.people.transtree.targets[ind])

            # Populate the array -- to avoid divide-by-zero, skip indices that are 0
            inds = sc.findinds(sources > 0)
            r_eff = np.zeros(self.npts) * np.nan
            r_eff[inds] = targets[inds] / sources[inds]

            # Use stored weights calculate the moving average over the window of timesteps, n
            num = np.nancumsum(r_eff * sources)
            num[window:] = num[window:] - num[:-window]
            den = np.cumsum(sources)
            den[window:] = den[window:] - den[:-window]

            # Avoid dividing by zero
            values = np.zeros(num.shape) * np.nan
            ind = den > 0
            values[ind] = num[ind] / den[ind]

        # Method not recognized
        else:
            errormsg = f'Method must be "daily", "infected", or "outcome", not "{method}"'
            raise ValueError(errormsg)

        # Set the values and return
        self.results['r_eff'].values[:] = values

        return self.results['r_eff'].values
Exemplo n.º 6
0
                                   pars={})
                    for key, val in row.items():
                        rowdict['pars'][key] = val
                    json.append(rowdict)
                sc.savejson(f'{dbname}.json', json, indent=2)
                saveobj = False
                if saveobj:  # Smaller file, but less portable
                    sc.saveobj(f'{dbname}.obj', json)

            # Plot the trend in best mismatch over time
            if plot_trend:
                mismatch = sc.dcp(df['mismatch'].values)
                best_mismatch = np.zeros(len(mismatch))
                for i in range(len(mismatch)):
                    best_mismatch[i] = mismatch[:i + 1].min()
                smoothed_mismatch = sc.smooth(mismatch)
                pl.figure(figsize=(16, 12), dpi=120)

                ax1 = pl.subplot(2, 1, 1)
                pl.plot(mismatch, alpha=0.2, label='Original')
                pl.plot(smoothed_mismatch, lw=3, label='Smoothed')
                pl.plot(best_mismatch, lw=3, label='Best')

                ax2 = pl.subplot(2, 1, 2)
                max_mismatch = mismatch.min() * best_thresh
                inds = cv.true(mismatch <= max_mismatch)
                pl.plot(best_mismatch, lw=3, label='Best')
                pl.scatter(inds,
                           mismatch[inds],
                           c=mismatch[inds],
                           label='Usable indices')