Ejemplo n.º 1
0
def convert_df_to_json_array(df, cols, int_cols=None):
    """
    Convert desired data from a pandas dataframe into a json array.

    Args:
        df (pandas dataframe)  : the dataframe with data
        cols (list)            : list of the columns to convert to the json array format
        int_cols (str or list) : a str or list of columns to convert to integer values

    Returns:
        array: An array version of the pandas dataframe to be added to synthpops
        json data objects.
    """
    df = df[cols]

    # make into a list to iterate over
    int_cols = sc.tolist(int_cols)

    # some columns as ints
    df = df.astype({k: int for k in int_cols})

    # make an array of arrays --- dtype=object to preserve each columns type
    arr = df.to_numpy(dtype=object).tolist()

    return arr
Ejemplo n.º 2
0
def handle_to_plot(kind, to_plot, n_cols, sim, check_ready=True):
    ''' Handle which quantities to plot '''

    # Allow default kind to be overwritten by to_plot -- used by msim.plot()
    if isinstance(to_plot, tuple):
        kind, to_plot = to_plot  # Split the tuple

    # Check that results are ready
    if check_ready and not sim.results_ready:
        errormsg = 'Cannot plot since results are not ready yet -- did you run the sim?'
        raise RuntimeError(errormsg)

    # If it matches a result key, convert to a list
    reskeys = sim.result_keys('main')
    varkeys = sim.result_keys('variant')
    allkeys = reskeys + varkeys
    if to_plot in allkeys:
        to_plot = sc.tolist(to_plot)

    # If not specified or specified as another string, load defaults
    if to_plot is None or isinstance(to_plot, str):
        to_plot = cvd.get_default_plots(to_plot, kind=kind, sim=sim)

    # If a list of keys has been supplied or constructed
    if isinstance(to_plot, list):
        to_plot_list = to_plot  # Store separately
        to_plot = sc.odict()  # Create the dict
        invalid = sc.autolist()
        for reskey in to_plot_list:
            if reskey in allkeys:
                name = sim.results[
                    reskey].name if reskey in reskeys else sim.results[
                        'variant'][reskey].name
                to_plot[name] = [
                    reskey
                ]  # Use the result name as the key and the reskey as the value
            else:
                invalid += reskey
        if len(invalid):
            errormsg = f'The following key(s) are invalid:\n{sc.strjoin(invalid)}\n\nValid main keys are:\n{sc.strjoin(reskeys)}\n\nValid variant keys are:\n{sc.strjoin(varkeys)}'
            raise sc.KeyNotFoundError(errormsg)

    to_plot = sc.odict(sc.dcp(to_plot))  # In case it's supplied as a dict

    # Handle rows and columns -- assume 5 is the most rows we would want
    n_plots = len(to_plot)
    if n_cols is None:
        max_rows = 5  # Assumption -- if desired, the user can override this by setting n_cols manually
        n_cols = int((n_plots - 1) // max_rows +
                     1)  # This gives 1 column for 1-4, 2 for 5-8, etc.
    n_rows, n_cols = sc.get_rows_cols(
        n_plots, ncols=n_cols
    )  # Inconsistent naming due to Covasim/Matplotlib conventions

    return to_plot, n_cols, n_rows
Ejemplo n.º 3
0
    def member_ages(self, age_by_uid, subgroup_member_uids=None):
        """Return the ages of members in the layer group given the pop object."""
        if len(age_by_uid) == 0:
            print(
                "age_by_uid is empty. Returning an empty array for member_ages."
            )
            return np.array([])

        if subgroup_member_uids is None:
            return np.array(age_by_uid[self['member_uids']])
        else:
            subgroup_member_uids = sc.tolist(subgroup_member_uids)
            return np.array(age_by_uid[subgroup_member_uids])
Ejemplo n.º 4
0
 def pop_keywords(sourcekeys, rckey):
     ''' Helper function to handle input arguments '''
     sourcekeys = sc.tolist(sourcekeys)
     key = sourcekeys[0]  # Main key
     value = None
     changed = self.changed(key)
     if changed:
         value = self[key]
     for k in sourcekeys:
         kwvalue = kwargs.pop(k, None)
         if kwvalue is not None:
             value = kwvalue
     if value is not None:
         rc[rckey] = value
     return
Ejemplo n.º 5
0
    def member_ages(self, age_by_uid, subgroup_member_uids=None):
        """
        Return the ages of members in the layer group given the pop object.

        Args:
            age_by_uid (np.ndarray) : mapping of age to uid
            subgroup_member_uids (np.ndarray, list) : subgroup of uids to return ages for

        Returns:
            nd.ndarray : ages of members in group or subgroup
        """
        if len(age_by_uid) == 0:
            print(
                "age_by_uid is empty. Returning an empty array for member_ages."
            )
            return np.array([])

        if subgroup_member_uids is None:
            return np.array(age_by_uid[self['member_uids']])
        else:
            subgroup_member_uids = sc.tolist(subgroup_member_uids)
            return np.array(age_by_uid[subgroup_member_uids])
Ejemplo n.º 6
0
def check_valid_probability_distributions(property_name,
                                          valid_properties=None):
    """
    Check that the property_name is a valid probability distribution.

    Args:
        property_name (str)            : the property name
        valid_properties (str or list) : a list of the valid probability distributions

    Returns:
        None.
    """
    # check the property_name is in the list of valid_probability_distributions()
    if valid_properties is None:
        valid_properties = defaults.valid_probability_distributions

    # if a single str, make into a list so next check will work
    valid_properties = sc.tolist(valid_properties)

    if property_name not in valid_properties:  # pragma: no cover
        raise NotImplementedError(
            f"{property_name} is not one of the expected probability distributions. The list of expected probability distributions is {valid_properties}. If you wish to use this method on the attribute {property_name}, you can supply it as the parameter valid_properties={property_name}."
        )
Ejemplo n.º 7
0
def savefig(filename=None, comments=None, fig=None, **kwargs):
    '''
    Wrapper for Matplotlib's ``pl.savefig()`` function which automatically stores
    Covasim metadata in the figure.

    By default, saves (git) information from both the Covasim version and the calling
    function. Additional comments can be added to the saved file as well. These can
    be retrieved via ``cv.get_png_metadata()`` (or ``sc.loadmetadata``). Metadata can
    also be stored for PDF, but cannot be automatically retrieved.

    Args:
        filename (str/list): name of the file to save to (default, timestamp); can also be a list of names
        comments (str/dict): additional metadata to save to the figure
        fig      (fig/list): figure to save (by default, current one); can also be a list of figures
        kwargs   (dict):     passed to ``fig.savefig()``

    **Example**::

        cv.Sim().run().plot()
        cv.savefig()
    '''

    # Handle inputs
    dpi = kwargs.pop('dpi', 150)
    metadata = kwargs.pop('metadata', {})

    if fig is None:
        fig = pl.gcf()
    figlist = sc.tolist(fig)

    if filename is None: # pragma: no cover
        now = sc.getdate(dateformat='%Y-%b-%d_%H.%M.%S')
        filename = f'covasim_{now}.png'
    filenamelist = sc.tolist(filename)

    if len(figlist) != len(filenamelist):
        errormsg = f'You have supplied {len(figlist)} figures and {len(filenamelist)} filenames: these must be the same length'
        raise ValueError(errormsg)

    metadata = {}
    metadata['Covasim version'] = cvv.__version__
    gitinfo = git_info()
    for key,value in gitinfo['covasim'].items():
        metadata[f'Covasim {key}'] = value
    for key,value in gitinfo['called_by'].items():
        metadata[f'Covasim caller {key}'] = value
    metadata['Covasim current time'] = sc.getdate()
    metadata['Covasim calling file'] = sc.getcaller()
    if comments:
        metadata['Covasim comments'] = comments

    # Loop over the figures (usually just one)
    for thisfig, thisfilename in zip(figlist, filenamelist):

        # Handle different formats
        lcfn = thisfilename.lower() # Lowercase filename
        if lcfn.endswith('pdf') or lcfn.endswith('svg'):
            metadata = {'Keywords':str(metadata)} # PDF and SVG doesn't support storing a dict

        # Save the figure
        thisfig.savefig(thisfilename, dpi=dpi, metadata=metadata, **kwargs)

    return filename