def calculate_lfcs(lognorm_df, ref_col=None, target_cols=None, ref_map=None):
    """
    Calculate log-fold changes between reference column and target columns

    lognorm_df: dataframe |
    ref_col: str or None, if str then target_col must also be present |
    target_col: list or None |
    ref_map: dict or None, key-value pairs correspond to target-reference conditions |
    returns: dataframe with log-fold changes
    """
    lfc_df = lognorm_df.copy()
    if (ref_col is not None) & (target_cols is not None):
        lfc_df[target_cols] = lfc_df[target_cols].sub(lfc_df[ref_col], axis=0)
        lfc_df = lfc_df.drop(ref_col, axis=1)
    elif ref_map is not None:
        for target_col, ref_col in ref_map.items():
            # use lognorms in case columns double as target and ref
            lfc_df[target_col] = lognorm_df[target_col] - lognorm_df[ref_col]
        for ref_col in set(ref_map.values()):
            if ref_col not in ref_map.keys(): # not a target condition as well
                lfc_df = lfc_df.drop(ref_col, axis=1)
    else:
        raise ValueError('Either ref_col and target_cols or ref_map must be present')
    return lfc_df