def METHOD_NAME(
    es,
    aggregations,
    transforms,
    feature_substrings,
    target_dataframe_name="log",
    multi_output=False,
    max_depth=3,
    max_features=-1,
    instance_ids=[0, 1, 2, 3],
):
    if not isinstance(feature_substrings, list):
        feature_substrings = [feature_substrings]
    if any([issubclass(x, PrimitiveBase) for x in feature_substrings]):
        feature_substrings = [x.name.upper() for x in feature_substrings]
    features = dfs(
        entityset=es,
        target_dataframe_name=target_dataframe_name,
        agg_primitives=aggregations,
        trans_primitives=transforms,
        max_features=max_features,
        max_depth=max_depth,
        features_only=True,
    )
    applicable_features = []
    for feat in features:
        applicable_features += [
            feat for x in feature_substrings if x in feat.get_name()
        ]
    if len(applicable_features) == 0:
        raise ValueError(
            "No feature names with %s, verify the name attribute \
                          is defined and/or generate_name() is defined to \
                          return %s "
            % (feature_substrings, feature_substrings),
        )
    df = calculate_feature_matrix(
        entityset=es,
        features=applicable_features,
        instance_ids=instance_ids,
        n_jobs=1,
    )
    encode_features(df, applicable_features)
    # TODO: check the multi_output shape by checking
    # feature.number_output_features for each feature
    # and comparing it with the matrix shape
    if not multi_output:
        assert len(applicable_features) == df.shape[1]
    return