예제 #1
0
def combination_referral_monthly_metrics(
        combo: Dict[str, Any],
        program_event: ProgramReferralEvent,
        all_referral_events:
        List[ProgramReferralEvent]) \
        -> List[Tuple[Dict[str, Any], int]]:
    """Returns all unique referral metrics for the given event and combination.

    First, includes an event-based count for the month the event occurred with a metric period of 1 month. Then, if
    this event should be included in the person-based count for the month when the event occurred, adds those person-
    based metrics.

    Args:
        combo: A characteristic combination to convert into metrics
        program_event: The program event from which the combination was derived
        all_referral_events: All of this person's ProgramReferralEvents

    Returns:
        A list of key-value tuples representing specific metric combination dictionaries and the number 1 representing
            a positive contribution to that count metric.
    """
    metrics = []

    event_date = program_event.event_date
    event_year = event_date.year
    event_month = event_date.month

    # Add event-based combo for the 1-month period the month of the event
    event_based_same_month_combo = augmented_combo_for_calculations(
        combo, program_event.state_code,
        event_year, event_month,
        MetricMethodologyType.EVENT, 1)

    metrics.append((event_based_same_month_combo, 1))

    # Create the person-based combo for the 1-month period of the month of the event
    person_based_same_month_combo = augmented_combo_for_calculations(
        combo, program_event.state_code,
        event_year, event_month,
        MetricMethodologyType.PERSON, 1
    )

    # Get all other referral events that happened the same month as this one
    all_referral_events_in_event_month = [
        event for event in all_referral_events
        if event.event_date.year == event_date.year and
        event.event_date.month == event_date.month
    ]

    if include_referral_in_count(
            combo,
            program_event,
            last_day_of_month(event_date),
            all_referral_events_in_event_month):
        # Include this event in the person-based count
        metrics.append((person_based_same_month_combo, 1))

    return metrics
예제 #2
0
def combination_incarceration_metric_period_metrics(
        combo: Dict[str, Any],
        incarceration_event: IncarcerationEvent,
        metric_period_end_date: date,
        periods_and_events: Dict[int, List[IncarcerationEvent]]) \
        -> List[Tuple[Dict[str, Any], int]]:
    """Returns all unique incarceration metrics for the given event, combination, and relevant metric_period_months.

    Returns metrics for each of the metric period length that this event falls into if this event should be included in
    the person-based count for that metric period.

    Args:
        combo: A characteristic combination to convert into metrics
        incarceration_event: The IncarcerationEvent from which the combination was derived
        metric_period_end_date: The day the metric periods end
        periods_and_events: Dictionary mapping metric period month lengths to the IncarcerationEvents that fall in that
            period

    Returns:
        A list of key-value tuples representing specific metric combination dictionaries and the number 1 representing
            a positive contribution to that count metric.
    """
    metrics = []

    period_end_year = metric_period_end_date.year
    period_end_month = metric_period_end_date.month

    for period_length, events_in_period in periods_and_events.items():
        if incarceration_event in events_in_period:
            # This event falls within this metric period
            person_based_period_combo = augmented_combo_for_calculations(
                combo, incarceration_event.state_code, period_end_year,
                period_end_month, MetricMethodologyType.PERSON, period_length)

            related_events_in_period: List[IncarcerationEvent] = []

            if isinstance(incarceration_event, IncarcerationAdmissionEvent):
                related_events_in_period = [
                    event for event in events_in_period
                    if isinstance(event, IncarcerationAdmissionEvent)
                ]
            elif isinstance(incarceration_event, IncarcerationReleaseEvent):
                related_events_in_period = [
                    event for event in events_in_period
                    if isinstance(event, IncarcerationReleaseEvent)
                ]

            if related_events_in_period and include_event_in_count(
                    incarceration_event, metric_period_end_date,
                    related_events_in_period):
                # Include this event in the person-based count for this time period
                metrics.append((person_based_period_combo, 1))

    return metrics
예제 #3
0
def combination_rate_metrics(
    combo: Dict[str, Any],
    event: ReleaseEvent,
    reincarcerations_by_follow_up_period: Dict[int,
                                               List[RecidivismReleaseEvent]],
) -> List[Tuple[Dict[str, Any], int]]:
    """Returns all recidivism rate metrics for the combo given the relevant follow-up periods.

    Args:
        combo: a characteristic combination to convert into metrics
        event: the release event from which the combination was derived
        reincarcerations_by_follow_up_period: dictionary where the keys are all relevant periods for measurement, and
            the values are lists of dictionaries representing the reincarceration admissions during that period

    Returns:
        A list of key-value tuples representing specific metric combination dictionaries and the recidivism value
            corresponding to that metric.
    """
    metrics = []

    for (
            period,
            reincarceration_admissions,
    ) in reincarcerations_by_follow_up_period.items():
        augmented_combo = augmented_combo_for_calculations(
            combo,
            event.state_code,
            metric_type=ReincarcerationRecidivismMetricType.
            REINCARCERATION_RATE,
        )
        augmented_combo["follow_up_period"] = period

        # If they didn't recidivate at all or not yet for this period (or they didn't recidivate until 10 years had
        # passed), assign a value of 0.
        if (isinstance(event, NonRecidivismReleaseEvent)
                or not reincarceration_admissions):
            metrics.append((augmented_combo, 0))

        # If they recidivated, each unique release of a given person within a follow-up period after the year of release
        # may be counted as an instance of recidivism for event-based measurement.
        elif isinstance(event, RecidivismReleaseEvent):
            for reincarceration in reincarceration_admissions:
                event_combo_copy = augmented_combo.copy()
                event_combo_copy["return_type"] = reincarceration.return_type
                event_combo_copy[
                    "from_supervision_type"] = reincarceration.from_supervision_type
                event_combo_copy[
                    "source_violation_type"] = reincarceration.source_violation_type

                metrics.append((event_combo_copy, 1))

    return metrics
예제 #4
0
def combination_supervision_metric_period_metrics(
        combo: Dict[str, Any],
        supervision_time_bucket: SupervisionTimeBucket,
        metric_period_end_date: date,
        periods_and_buckets: Dict[int, List[SupervisionTimeBucket]],
        metric_type: SupervisionMetricType) \
        -> List[Tuple[Dict[str, Any], int]]:
    """Returns all unique supervision metrics for the given time bucket and combination for each of the relevant
    metric_period_months.

    Returns metrics for each of the metric period lengths that this event falls into if this event should be included in
    the person-based count for that metric period length.

    Args:
        combo: A characteristic combination to convert into metrics
        supervision_time_bucket: The SupervisionTimeBucket from which the
            combination was derived
        metric_period_end_date: The day the metric periods end
        periods_and_buckets: Dictionary mapping metric period month lengths to
            the SupervisionTimeBuckets that fall in that period
        metric_type: The type of metric being tracked by this combo

    Returns:
        A list of key-value tuples representing specific metric combination dictionaries and the the metric value
            corresponding to that metric.
    """
    metrics: List[Tuple[Dict[str, Any], int]] = []

    period_end_year = metric_period_end_date.year
    period_end_month = metric_period_end_date.month

    for period_length, buckets_in_period in periods_and_buckets.items():
        if supervision_time_bucket in buckets_in_period:
            # This event falls within this metric period
            person_based_period_combo = augmented_combo_for_calculations(
                combo, supervision_time_bucket.state_code, period_end_year,
                period_end_month, MetricMethodologyType.PERSON, period_length)

            relevant_buckets_in_period: List[SupervisionTimeBucket] = []

            if metric_type == SupervisionMetricType.ASSESSMENT_CHANGE:
                # Get all other supervision time buckets for this period that should contribute to an assessment change
                # metric
                relevant_buckets_in_period = [
                    bucket for bucket in buckets_in_period
                    if (isinstance(bucket, SupervisionTerminationBucket))
                ]
            elif metric_type == SupervisionMetricType.POPULATION:
                # Get all other supervision time buckets for this period that should contribute to a population metric
                relevant_buckets_in_period = [
                    bucket for bucket in buckets_in_period
                    if (isinstance(bucket, (
                        RevocationReturnSupervisionTimeBucket,
                        NonRevocationReturnSupervisionTimeBucket)))
                ]
            elif metric_type in (
                    SupervisionMetricType.REVOCATION,
                    SupervisionMetricType.REVOCATION_ANALYSIS,
                    SupervisionMetricType.REVOCATION_VIOLATION_TYPE_ANALYSIS):
                # Get all other revocation return time buckets for this period
                relevant_buckets_in_period = [
                    bucket for bucket in buckets_in_period if isinstance(
                        bucket, RevocationReturnSupervisionTimeBucket)
                ]
            elif metric_type in (
                    SupervisionMetricType.SUCCESS,
                    SupervisionMetricType.SUCCESSFUL_SENTENCE_DAYS_SERVED):
                # Get all other projected completion buckets in this period
                relevant_buckets_in_period = [
                    bucket for bucket in buckets_in_period if (isinstance(
                        bucket, ProjectedSupervisionCompletionBucket))
                ]

            if relevant_buckets_in_period and include_supervision_in_count(
                    combo, supervision_time_bucket, relevant_buckets_in_period,
                    metric_type):

                person_combo_value = _person_combo_value(
                    combo, supervision_time_bucket, relevant_buckets_in_period,
                    metric_type)

                # Include this event in the person-based count
                metrics.append((person_based_period_combo, person_combo_value))

    return metrics
예제 #5
0
def combination_supervision_monthly_metrics(
        combo: Dict[str, Any], supervision_time_bucket: SupervisionTimeBucket,
        all_supervision_time_buckets: List[SupervisionTimeBucket],
        metric_type: SupervisionMetricType
) -> List[Tuple[Dict[str, Any], int]]:
    """Returns all unique supervision metrics for the given time bucket and combination for the month of the bucket.

    First, includes an event-based count for the month the SupervisionTimeBucket represents. If this bucket of
    supervision should be included in the person-based count for the month when the supervision occurred, adds those
    person-based metrics.

    Args:
        combo: A characteristic combination to convert into metrics
        supervision_time_bucket: The SupervisionTimeBucket from which the combination was derived
        all_supervision_time_buckets: All of this person's SupervisionTimeBuckets
        metric_type: The type of metric being tracked by this combo

    Returns:
        A list of key-value tuples representing specific metric combination dictionaries and the the metric value
            corresponding to that metric.
    """
    metrics: List[Tuple[Dict[str, Any], int]] = []

    bucket_year = supervision_time_bucket.year
    bucket_month = supervision_time_bucket.month

    base_metric_period = 1

    # Add event-based combo for the base metric period of the month and year of the bucket
    event_based_same_bucket_combo = augmented_combo_for_calculations(
        combo, supervision_time_bucket.state_code, bucket_year, bucket_month,
        MetricMethodologyType.EVENT, base_metric_period)

    event_combo_value = None

    if isinstance(supervision_time_bucket,
                  ProjectedSupervisionCompletionBucket):
        if metric_type == SupervisionMetricType.SUCCESS:
            # Set 1 for successful completion, 0 for unsuccessful completion
            event_combo_value = 1 if supervision_time_bucket.successful_completion else 0
        elif metric_type == SupervisionMetricType.SUCCESSFUL_SENTENCE_DAYS_SERVED:
            if supervision_time_bucket.sentence_days_served is not None:
                # Only include this combo if there is a recorded number of days served. Set the value as the number of
                # days served.
                event_combo_value = supervision_time_bucket.sentence_days_served
            else:
                # If there's no recorded days served on this completion bucket, don't include it in any of the
                # successful sentence days served metrics.
                pass
        else:
            raise ValueError(
                f"Unsupported metric type {metric_type} for ProjectedSupervisionCompletionBucket."
            )

    elif metric_type == SupervisionMetricType.ASSESSMENT_CHANGE and \
            isinstance(supervision_time_bucket, SupervisionTerminationBucket):
        if supervision_time_bucket.assessment_score_change is not None:
            # Only include this combo if there is an assessment score change associated with this termination. Set the
            # value as the assessment score change
            event_combo_value = supervision_time_bucket.assessment_score_change
        else:
            # The only metric relying on the SupervisionTerminationBuckets is the
            # TerminatedSupervisionAssessmentScoreChangeMetric. So, if there's no recorded assessment score change on
            # this termination, don't include it in any of the metrics.
            pass
    else:
        # The default value for all combos is 1
        event_combo_value = 1

    if event_combo_value is None:
        # If the event_combo_value is not set, then exclude this bucket from all metrics
        return metrics

    # TODO(2913): Exclude combos with a supervision_type of DUAL from event-based counts
    metrics.append((event_based_same_bucket_combo, event_combo_value))

    # Create the person-based combo for the base metric period of the month of the bucket
    person_based_same_bucket_combo = augmented_combo_for_calculations(
        combo, supervision_time_bucket.state_code, bucket_year, bucket_month,
        MetricMethodologyType.PERSON, base_metric_period)

    buckets_in_period: List[SupervisionTimeBucket] = []

    if metric_type == SupervisionMetricType.POPULATION:
        # Get all other supervision time buckets for the same month as this one
        buckets_in_period = [
            bucket for bucket in all_supervision_time_buckets
            if (isinstance(bucket, (RevocationReturnSupervisionTimeBucket,
                                    NonRevocationReturnSupervisionTimeBucket)))
            and bucket.year == bucket_year and bucket.month == bucket_month
        ]
    elif metric_type == SupervisionMetricType.REVOCATION:
        # Get all other revocation supervision buckets for the same month as this one
        buckets_in_period = [
            bucket for bucket in all_supervision_time_buckets
            if isinstance(bucket, RevocationReturnSupervisionTimeBucket)
            and bucket.year == bucket_year and bucket.month == bucket_month
        ]
    elif metric_type in (
            SupervisionMetricType.SUCCESS,
            SupervisionMetricType.SUCCESSFUL_SENTENCE_DAYS_SERVED):
        # Get all other projected completion buckets for the same month as this one
        buckets_in_period = [
            bucket for bucket in all_supervision_time_buckets
            if isinstance(bucket, ProjectedSupervisionCompletionBucket)
            and bucket.year == bucket_year and bucket.month == bucket_month
        ]
    elif metric_type == SupervisionMetricType.ASSESSMENT_CHANGE:
        # Get all other termination buckets for the same month as this one
        buckets_in_period = [
            bucket for bucket in all_supervision_time_buckets
            if isinstance(bucket, SupervisionTerminationBucket)
            and bucket.year == bucket_year and bucket.month == bucket_month
        ]
    elif metric_type in (
            SupervisionMetricType.REVOCATION_ANALYSIS,
            SupervisionMetricType.REVOCATION_VIOLATION_TYPE_ANALYSIS):
        # Get all other revocation supervision buckets for the same month as this one
        buckets_in_period = [
            bucket for bucket in all_supervision_time_buckets
            if isinstance(bucket, RevocationReturnSupervisionTimeBucket)
            and bucket.year == bucket_year and bucket.month == bucket_month
        ]

    if buckets_in_period and include_supervision_in_count(
            combo, supervision_time_bucket, buckets_in_period, metric_type):
        person_combo_value = _person_combo_value(combo,
                                                 supervision_time_bucket,
                                                 buckets_in_period,
                                                 metric_type)

        # Include this event in the person-based count
        metrics.append((person_based_same_bucket_combo, person_combo_value))

    return metrics
예제 #6
0
def combination_program_monthly_metrics(
        combo: Dict[str, Any], program_event: ProgramEvent,
        metric_type: ProgramMetricType, all_program_events: List[ProgramEvent],
        is_daily_metric: bool) -> List[Tuple[Dict[str, Any], int]]:
    """Returns all unique referral metrics for the given event and combination.

    First, includes an event-based count for the month the event occurred with a metric period of 1 month. Then, if
    this event should be included in the person-based count for the month when the event occurred, adds those person-
    based metrics.

    Args:
        combo: A characteristic combination to convert into metrics
        program_event: The program event from which the combination was derived
        metric_type: The type of metric being tracked by this combo
        all_program_events: All of this person's ProgramEvents
        is_daily_metric:  If True, limits person-based counts to the date of the event. If False, limits person-based
            counts to the month of the event.

    Returns:
        A list of key-value tuples representing specific metric combination dictionaries and the number 1 representing
            a positive contribution to that count metric.
    """
    metrics = []

    event_date = program_event.event_date
    event_year = event_date.year
    event_month = event_date.month

    base_metric_period = 0 if is_daily_metric else 1

    # Add event-based combo for the base metric period the month of the event
    event_based_same_month_combo = augmented_combo_for_calculations(
        combo, program_event.state_code, event_year, event_month,
        MetricMethodologyType.EVENT, base_metric_period)

    metrics.append((event_based_same_month_combo, 1))

    # Create the person-based combo for the base metric period of the month of the event
    person_based_same_month_combo = augmented_combo_for_calculations(
        combo, program_event.state_code, event_year, event_month,
        MetricMethodologyType.PERSON, base_metric_period)

    events_in_period: List[ProgramEvent] = []

    if metric_type == ProgramMetricType.PARTICIPATION:
        # Get all other participation events that happened on the same day as this one
        events_in_period = [
            event for event in all_program_events
            if (isinstance(event, ProgramParticipationEvent))
            and event.event_date == program_event.event_date
        ]
    elif metric_type == ProgramMetricType.REFERRAL:
        # Get all other referral events that happened in the same month as this one
        events_in_period = [
            event for event in all_program_events
            if isinstance(event, ProgramReferralEvent) and event.event_date.
            year == event_year and event.event_date.month == event_month
        ]

    if include_event_in_count(combo, program_event,
                              last_day_of_month(event_date), events_in_period):
        # Include this event in the person-based count
        metrics.append((person_based_same_month_combo, 1))

    return metrics
예제 #7
0
def combination_incarceration_metrics(
        combo: Dict[str, Any],
        incarceration_event: IncarcerationEvent,
        all_incarceration_events: List[IncarcerationEvent],
        is_daily_metric: bool) \
        -> List[Tuple[Dict[str, Any], int]]:
    """Returns all unique incarceration metrics for the given event and combination.

    First, includes an event-based count for the event. Then, if this is a daily metric, includes a count of the event
    if it should be included in the person-based count for the day when the event occurred. If this is not a daily
    metric, includes a count of the event if it should be included in the person-based count for the month of the event.

    Args:
        combo: A characteristic combination to convert into metrics
        incarceration_event: The IncarcerationEvent from which the combination was derived
        all_incarceration_events: All of this person's IncarcerationEvents
        is_daily_metric: If True, limits person-based counts to the date of the event. If False, limits person-based
            counts to the month of the event.

    Returns:
        A list of key-value tuples representing specific metric combination dictionaries and the number 1 representing
            a positive contribution to that count metric.
    """
    metrics = []

    event_date = incarceration_event.event_date
    event_year = event_date.year
    event_month = event_date.month

    metric_period_months = 0 if is_daily_metric else 1

    # Add event-based combo for the 1-month period the month of the event
    event_based_same_month_combo = augmented_combo_for_calculations(
        combo,
        incarceration_event.state_code,
        event_year,
        event_month,
        MetricMethodologyType.EVENT,
        metric_period_months=metric_period_months)

    metrics.append((event_based_same_month_combo, 1))

    # Create the person-based combo for the 1-month period of the month of the event
    person_based_same_month_combo = augmented_combo_for_calculations(
        combo,
        incarceration_event.state_code,
        event_year,
        event_month,
        MetricMethodologyType.PERSON,
        metric_period_months=metric_period_months)

    day_match_value = event_date.day if is_daily_metric else None

    # Get the events of the same type that happened in the same month
    events_in_period = matching_events_for_person_based_count(
        year=event_year,
        month=event_month,
        day=day_match_value,
        event_type=type(incarceration_event),
        all_incarceration_events=all_incarceration_events)

    if events_in_period and include_event_in_count(
            incarceration_event, last_day_of_month(event_date),
            events_in_period):
        # Include this event in the person-based count
        metrics.append((person_based_same_month_combo, 1))

    return metrics
예제 #8
0
def map_supervision_combinations(
    person: StatePerson,
    supervision_time_buckets: List[SupervisionTimeBucket],
    metric_inclusions: Dict[SupervisionMetricType, bool],
    calculation_end_month: Optional[str],
    calculation_month_count: int,
    person_metadata: PersonMetadata,
) -> List[Tuple[Dict[str, Any], Any]]:
    """Transforms SupervisionTimeBuckets and a StatePerson into metric combinations.

    Takes in a StatePerson and all of her SupervisionTimeBuckets and returns an array of "supervision combinations".
    These are key-value pairs where the key represents a specific metric and the value represents whether or not
    the person should be counted as a positive instance of that metric.

    This translates a particular time on supervision into many different supervision population metrics.

    Args:
        person: the StatePerson
        supervision_time_buckets: A list of SupervisionTimeBuckets for the given StatePerson.
        metric_inclusions: A dictionary where the keys are each SupervisionMetricType, and the values are boolean
                flags for whether or not to include that metric type in the calculations
        calculation_end_month: The year and month in YYYY-MM format of the last month for which metrics should be
            calculated. If unset, ends with the current month.
        calculation_month_count: The number of months (including the month of the calculation_end_month) to
            limit the monthly calculation output to. If set to -1, does not limit the calculations.
        person_metadata: Contains information about the StatePerson that is necessary for the metrics.
    Returns:
        A list of key-value tuples representing specific metric combinations and the value corresponding to that metric.
    """
    metrics: List[Tuple[Dict[str, Any], Any]] = []

    supervision_time_buckets.sort(key=attrgetter("year", "month"))

    calculation_month_upper_bound = get_calculation_month_upper_bound_date(
        calculation_end_month)
    calculation_month_lower_bound = get_calculation_month_lower_bound_date(
        calculation_month_upper_bound, calculation_month_count)

    for supervision_time_bucket in supervision_time_buckets:
        event_date = supervision_time_bucket.event_date

        if (isinstance(supervision_time_bucket,
                       NonRevocationReturnSupervisionTimeBucket)
                and supervision_time_bucket.case_compliance):
            event_date = supervision_time_bucket.case_compliance.date_of_evaluation

        event_year = event_date.year
        event_month = event_date.month

        if not include_in_output(
                event_year,
                event_month,
                calculation_month_upper_bound,
                calculation_month_lower_bound,
        ):
            continue

        applicable_metric_types = BUCKET_TO_METRIC_TYPES.get(
            type(supervision_time_bucket))

        if not applicable_metric_types:
            raise ValueError(
                "No metric types mapped to supervision_time_bucket of type {}".
                format(type(supervision_time_bucket)))

        for metric_type in applicable_metric_types:
            if not metric_inclusions[metric_type]:
                continue

            metric_class = METRIC_TYPE_TO_CLASS.get(metric_type)

            if not metric_class:
                raise ValueError(
                    "No metric class for metric type {}".format(metric_type))

            if include_event_in_metric(supervision_time_bucket, metric_type):
                characteristic_combo = characteristics_dict_builder(
                    pipeline="supervision",
                    event=supervision_time_bucket,
                    metric_class=metric_class,
                    person=person,
                    event_date=event_date,
                    person_metadata=person_metadata,
                )

                metric_combo = augmented_combo_for_calculations(
                    characteristic_combo,
                    supervision_time_bucket.state_code,
                    metric_type,
                    event_year,
                    event_month,
                )

                value = value_for_metric_combo(supervision_time_bucket,
                                               metric_type)

                metrics.append((metric_combo, value))

    return metrics
예제 #9
0
def map_recidivism_combinations(
    person: StatePerson,
    release_events: Dict[int, List[ReleaseEvent]],
    metric_inclusions: Dict[ReincarcerationRecidivismMetricType, bool],
    person_metadata: PersonMetadata,
) -> List[Tuple[Dict[str, Any], Any]]:
    """Transforms ReleaseEvents and a StatePerson into metric combinations.

    Takes in a StatePerson and all of her ReleaseEvents and returns an array
    of "recidivism combinations". These are key-value pairs where the key
    represents a specific metric and the value represents whether or not
    recidivism occurred.

    This translates a particular recidivism event into many different recidivism
    metrics. Both count-based and rate-based metrics are generated. Each metric
    represents one of many possible combinations of characteristics being
    tracked for that event. For example, if an asian male is reincarcerated,
    there is a metric that corresponds to asian people, one to males,
    one to asian males, one to all people, and more depending on other
    dimensions in the data.

    If a release does not count towards recidivism, then the value is 0 for
    the rate-based metrics in either methodology.

    For both count and rate-based metrics, the value is 0 if the dimensions
    of the metric do not fully match the attributes of the person and their type
    of return to incarceration. For example, for a RecidivismReleaseEvent where
    the return_type is 'REVOCATION', there will be metrics produced where the
    return_type is 'NEW INCARCERATION_ADMISSION' and the value is 0.

    Args:
        person: the StatePerson
        release_events: A dictionary mapping release cohorts to a list of
            ReleaseEvents for the given StatePerson.
        metric_inclusions: A dictionary where the keys are each ReincarcerationRecidivismMetricType, and the values
            are boolean flags for whether or not to include that metric type in the calculations
        person_metadata: Contains information about the StatePerson that is necessary for the metrics.

    Returns:
        A list of key-value tuples representing specific metric combinations and
        the recidivism value corresponding to that metric.
    """
    metrics = []
    all_reincarcerations = reincarcerations(release_events)

    if metric_inclusions.get(
            ReincarcerationRecidivismMetricType.REINCARCERATION_RATE):
        for events in release_events.values():
            for event in events:
                event_date = event.release_date

                characteristic_combo = characteristics_dict_builder(
                    pipeline="recidivism",
                    event=event,
                    metric_class=ReincarcerationRecidivismRateMetric,
                    person=person,
                    event_date=event_date,
                    person_metadata=person_metadata,
                )

                reincarcerations_by_follow_up_period = reincarcerations_by_period(
                    event_date, all_reincarcerations)

                metrics.extend(
                    combination_rate_metrics(
                        characteristic_combo,
                        event,
                        reincarcerations_by_follow_up_period,
                    ))

    if metric_inclusions.get(
            ReincarcerationRecidivismMetricType.REINCARCERATION_COUNT):
        for reincarceration_event in all_reincarcerations.values():
            event_date = reincarceration_event.reincarceration_date

            characteristic_combo = characteristics_dict_builder(
                pipeline="recidivism",
                event=reincarceration_event,
                metric_class=ReincarcerationRecidivismCountMetric,
                person=person,
                event_date=event_date,
                person_metadata=person_metadata,
            )

            augmented_combo = augmented_combo_for_calculations(
                characteristic_combo,
                state_code=reincarceration_event.state_code,
                year=event_date.year,
                month=event_date.month,
                metric_type=ReincarcerationRecidivismMetricType.
                REINCARCERATION_COUNT,
            )

            metrics.append((augmented_combo, 1))

    return metrics