Example #1
0
def us_mo_get_month_supervision_type(
    any_date_in_month: datetime.date,
    supervision_sentences: List[StateSupervisionSentence],
    incarceration_sentences: List[StateIncarcerationSentence],
    supervision_period: StateSupervisionPeriod
) -> StateSupervisionPeriodSupervisionType:
    """Calculates the supervision period supervision type that should be attributed to a US_MO supervision period
    on a given month.

    The date used to calculate the supervision period supervision type is either the last day of the month, or
    the last day of supervision, whichever comes first.
    """
    start_of_month = first_day_of_month(any_date_in_month)
    end_of_month = last_day_of_month(any_date_in_month)
    first_of_next_month = end_of_month + datetime.timedelta(days=1)

    if supervision_period.termination_date is None:
        upper_bound_exclusive_date = first_of_next_month
    else:
        upper_bound_exclusive_date = min(first_of_next_month,
                                         supervision_period.termination_date)

    lower_bound_inclusive = max(start_of_month, supervision_period.start_date)

    supervision_type = \
        us_mo_get_most_recent_supervision_period_supervision_type_before_upper_bound_day(
            upper_bound_exclusive_date=upper_bound_exclusive_date,
            lower_bound_inclusive_date=lower_bound_inclusive,
            supervision_sentences=supervision_sentences,
            incarceration_sentences=incarceration_sentences)

    if not supervision_type:
        return StateSupervisionPeriodSupervisionType.INTERNAL_UNKNOWN

    return supervision_type
Example #2
0
def _identify_months_fully_incarcerated(
        incarceration_periods: List[StateIncarcerationPeriod]) -> \
        Set[Tuple[int, int]]:
    """For each StateIncarcerationPeriod, identifies months where the person was incarcerated for every day during that
    month. Returns a set of months in the format (year, month) for which the person spent the entire month in a
    prison."""
    months_incarcerated: Set[Tuple[int, int]] = set()

    for incarceration_period in incarceration_periods:
        admission_date = incarceration_period.admission_date
        release_date = incarceration_period.release_date

        if admission_date is None:
            return months_incarcerated

        if release_date is None:
            release_date = last_day_of_month(date.today())

        if admission_date.day == 1:
            month_date = admission_date
        else:
            month_date = first_day_of_month(admission_date) + relativedelta(
                months=1)

        while month_date + relativedelta(
                months=1) <= release_date + relativedelta(days=1):
            months_incarcerated.add((month_date.year, month_date.month))
            month_date = month_date + relativedelta(months=1)

    return months_incarcerated
Example #3
0
def get_month_supervision_type(
    any_date_in_month: datetime.date,
    supervision_sentences: List[StateSupervisionSentence],
    incarceration_sentences: List[StateIncarcerationSentence],
    supervision_period: StateSupervisionPeriod
) -> StateSupervisionPeriodSupervisionType:
    """Supervision type can change over time even if the period does not change. This function calculates the
    supervision type that a given supervision period represents during the month that |any_date_in_month| falls in. We
    do this by looking at all sentences attached to this supervision period, then determining which ones overlap with
    any day in the month, and using the sentence supervision types to determine the period supervision type at this
    point in time.

    Args:
    any_date_in_month: (date) Any day in the month to consider
    supervision_period: (StateSupervisionPeriod) The supervision period we want to associate a supervision type with
    supervision_sentences: (List[StateSupervisionSentence]) All supervision sentences for a given person.
    """
    if not supervision_period.supervision_period_id:
        raise ValueError('All objects should have database ids.')

    if is_placeholder(supervision_period):
        raise ValueError('Do not expect placeholder periods!')

    start_of_month = first_day_of_month(any_date_in_month)
    end_of_month = last_day_of_month(any_date_in_month)

    # Find sentences that are attached to the period and overlap with the month
    incarceration_sentences = _get_valid_attached_sentences(
        incarceration_sentences, supervision_period)
    incarceration_sentences = _get_sentences_overlapping_with_dates(
        start_of_month, end_of_month, incarceration_sentences)

    supervision_sentences = _get_valid_attached_sentences(
        supervision_sentences, supervision_period)
    supervision_sentences = _get_sentences_overlapping_with_dates(
        start_of_month, end_of_month, supervision_sentences)

    return _get_supervision_type_from_sentences(incarceration_sentences,
                                                supervision_sentences)
Example #4
0
def map_recidivism_liberty_combinations(
        characteristic_combos: List[Dict[str, Any]],
        event: ReleaseEvent,
        all_reincarcerations: Dict[date, Dict[str, Any]]) -> \
        List[Tuple[Dict[str, Any], Any]]:
    """Maps the given event and characteristic combinations to a variety of metrics that track metrics for time at
    liberty.
    """
    metrics = []

    if isinstance(event, RecidivismReleaseEvent):
        reincarceration_date = event.reincarceration_date

        year = reincarceration_date.year
        year_start_day = date(year, 1, 1)
        year_end_day = date(year, 12, 31)
        month_start_day = first_day_of_month(reincarceration_date)
        month_end_day = last_day_of_month(reincarceration_date)

        for combo in characteristic_combos:
            combo['metric_type'] = ReincarcerationRecidivismMetricType.LIBERTY

            # Year bucket
            combo['start_date'] = year_start_day
            combo['end_date'] = year_end_day

            metrics.extend(
                combination_liberty_metrics(combo, event,
                                            all_reincarcerations))

            # Month bucket
            combo['start_date'] = month_start_day
            combo['end_date'] = month_end_day

            metrics.extend(
                combination_liberty_metrics(combo, event,
                                            all_reincarcerations))

    return metrics
def characteristic_combinations(person: StatePerson,
                                incarceration_event: IncarcerationEvent,
                                inclusions: Dict[str, bool],
                                metric_type: IncarcerationMetricType) -> \
        List[Dict[str, Any]]:
    """Calculates all incarceration metric combinations.

    Returns the list of all combinations of the metric characteristics, of all sizes, given the StatePerson and
    IncarcerationEvent. That is, this returns a list of dictionaries where each dictionary is a combination of 0
    to n unique elements of characteristics, where n is the number of keys in the given inclusions dictionary that are
    set to True + the dimensions for the given type of event.

    Args:
        person: the StatePerson we are picking characteristics from
        incarceration_event: the IncarcerationEvent we are picking characteristics from
        inclusions: A dictionary containing the following keys that correspond to characteristic dimensions:
                - age_bucket
                - ethnicity
                - gender
                - race
            Where the values are boolean flags indicating whether to include the dimension in the calculations.
        metric_type: The IncarcerationMetricType that determines which fields should be added to the characteristics
            dictionary

    Returns:
        A list of dictionaries containing all unique combinations of characteristics.
    """

    characteristics: Dict[str, Any] = {}

    # Add characteristics that will be used to generate dictionaries with unique combinations.
    if isinstance(incarceration_event, IncarcerationAdmissionEvent):
        if incarceration_event.admission_reason:
            characteristics['admission_reason'] = incarceration_event.admission_reason
        if incarceration_event.supervision_type_at_admission:
            characteristics['supervision_type_at_admission'] = incarceration_event.supervision_type_at_admission
        if incarceration_event.specialized_purpose_for_incarceration:
            characteristics['specialized_purpose_for_incarceration'] = \
                incarceration_event.specialized_purpose_for_incarceration

    if isinstance(incarceration_event, IncarcerationReleaseEvent):
        if incarceration_event.release_reason:
            characteristics['release_reason'] = incarceration_event.release_reason

    if isinstance(incarceration_event, IncarcerationStayEvent):
        if incarceration_event.admission_reason:
            characteristics['admission_reason'] = incarceration_event.admission_reason
        if incarceration_event.supervision_type_at_admission:
            characteristics['supervision_type_at_admission'] = incarceration_event.supervision_type_at_admission

    # Always include facility as a dimension
    if incarceration_event.facility:
        characteristics['facility'] = incarceration_event.facility

    # Always include county_of_residence as a dimension
    if incarceration_event.county_of_residence:
        characteristics['county_of_residence'] = incarceration_event.county_of_residence

    if inclusions.get('age_bucket'):
        start_of_bucket = first_day_of_month(incarceration_event.event_date)
        entry_age = age_at_date(person, start_of_bucket)
        entry_age_bucket = age_bucket(entry_age)
        if entry_age_bucket is not None:
            characteristics['age_bucket'] = entry_age_bucket
    if inclusions.get('gender'):
        if person.gender is not None:
            characteristics['gender'] = person.gender
    if person.races or person.ethnicities:
        if inclusions.get('race'):
            races = person.races
        else:
            races = []

        if inclusions.get('ethnicity'):
            ethnicities = person.ethnicities
        else:
            ethnicities = []

        all_combinations = for_characteristics_races_ethnicities(races, ethnicities, characteristics)
    else:
        all_combinations = for_characteristics(characteristics)

    characteristics_with_person_details = add_person_level_characteristics(
        person, incarceration_event, characteristics)

    if metric_type == IncarcerationMetricType.ADMISSION:
        characteristics_with_person_details['admission_date'] = incarceration_event.event_date

    all_combinations.append(characteristics_with_person_details)

    return all_combinations
Example #6
0
def find_time_buckets_for_supervision_period(
    supervision_sentences: List[StateSupervisionSentence],
    incarceration_sentences: List[StateIncarcerationSentence],
    supervision_period: StateSupervisionPeriod,
    incarceration_periods_by_admission_month: Dict[int, Dict[
        int, List[StateIncarcerationPeriod]]],
    months_fully_incarcerated: Set[Tuple[int, int]],
    assessments: List[StateAssessment],
    violation_responses: List[StateSupervisionViolationResponse],
    supervision_period_to_agent_associations: Dict[int, Dict[Any, Any]]
) -> List[SupervisionTimeBucket]:
    """Finds months that this person was on supervision for the given StateSupervisionPeriod, where the person was not
    incarcerated for the full month and did not have a revocation admission that month.

    Args:
        - supervision_period: The supervision period the person was on
        - incarceration_periods_by_admission_month: A dictionary mapping years and months of admissions to prison to the
            StateIncarcerationPeriods that started in that month.
        - months_fully_incarcerated: A set of tuples in the format (year, month) for each month of which this person has
            been incarcerated for the full month.
        - ssvr_agent_associations: dictionary associating StateSupervisionViolationResponse ids to information about the
            corresponding StateAgent on the response
    Returns
        - A set of unique SupervisionTimeBuckets for the person for the given StateSupervisionPeriod.
    """
    supervision_month_buckets: List[SupervisionTimeBucket] = []

    start_date = supervision_period.start_date
    termination_date = supervision_period.termination_date

    if termination_date is None:
        termination_date = date.today()

    if start_date is None:
        return supervision_month_buckets

    start_of_month = first_day_of_month(start_date)

    while start_of_month <= termination_date:
        if month_is_non_revocation_supervision_bucket(
                start_of_month, termination_date, months_fully_incarcerated,
                incarceration_periods_by_admission_month):

            supervision_type = get_month_supervision_type(
                start_of_month, supervision_sentences, incarceration_sentences,
                supervision_period)
            end_of_month = last_day_of_month(start_of_month)

            assessment_score, assessment_level, assessment_type = find_most_recent_assessment(
                end_of_month, assessments)

            supervising_officer_external_id, supervising_district_external_id = \
                _get_supervising_officer_and_district(supervision_period, supervision_period_to_agent_associations)

            case_type = _identify_most_severe_case_type(supervision_period)

            end_of_violation_window = end_of_month if end_of_month < termination_date else termination_date
            violation_history = get_violation_and_response_history(
                end_of_violation_window, violation_responses)

            supervision_month_buckets.append(
                NonRevocationReturnSupervisionTimeBucket(
                    state_code=supervision_period.state_code,
                    year=start_of_month.year,
                    month=start_of_month.month,
                    supervision_type=supervision_type,
                    case_type=case_type,
                    assessment_score=assessment_score,
                    assessment_level=assessment_level,
                    assessment_type=assessment_type,
                    most_severe_violation_type=violation_history.
                    most_severe_violation_type,
                    most_severe_violation_type_subtype=violation_history.
                    most_severe_violation_type_subtype,
                    response_count=violation_history.response_count,
                    supervising_officer_external_id=
                    supervising_officer_external_id,
                    supervising_district_external_id=
                    supervising_district_external_id,
                    supervision_level=supervision_period.supervision_level,
                    supervision_level_raw_text=supervision_period.
                    supervision_level_raw_text))

        start_of_month = start_of_month + relativedelta(months=1)

    return supervision_month_buckets