def test_add_demographic_characteristics_RaceEthnicity(self): characteristics = {} person = StatePerson.new_with_defaults( person_id=12345, birthdate=date(1984, 8, 31), gender=Gender.FEMALE, races=[StatePersonRace.new_with_defaults(race=Race.ASIAN)], ethnicities=[ StatePersonEthnicity.new_with_defaults( ethnicity=Ethnicity.HISPANIC) ]) event_date = date(2010, 9, 1) updated_characteristics = add_demographic_characteristics( characteristics, person, event_date) expected_output = { 'age_bucket': '25-29', 'race': [Race.ASIAN], 'gender': Gender.FEMALE, 'ethnicity': [Ethnicity.HISPANIC] } self.assertEqual(updated_characteristics, expected_output)
def characteristics_dict(person: StatePerson, program_event: ProgramEvent) -> Dict[str, Any]: """Builds a dictionary that describes the characteristics of the person and event. Args: person: the StatePerson we are picking characteristics from program_event: the ProgramEvent we are picking characteristics from Returns: A dictionary populated with all relevant characteristics. """ characteristics: Dict[str, Any] = {} event_date = program_event.event_date if isinstance(program_event, ProgramReferralEvent): if program_event.supervision_type: characteristics['supervision_type'] = program_event.supervision_type if program_event.assessment_score and program_event.assessment_type: assessment_bucket = assessment_score_bucket( assessment_score=program_event.assessment_score, assessment_level=None, assessment_type=program_event.assessment_type) if assessment_bucket and include_assessment_in_metric( 'program', program_event.state_code, program_event.assessment_type): characteristics['assessment_score_bucket'] = assessment_bucket characteristics['assessment_type'] = program_event.assessment_type if program_event.participation_status: characteristics['participation_status'] = program_event.participation_status if program_event.supervising_officer_external_id: characteristics['supervising_officer_external_id'] = program_event.supervising_officer_external_id if program_event.supervising_district_external_id: characteristics['supervising_district_external_id'] = program_event.supervising_district_external_id elif isinstance(program_event, ProgramParticipationEvent): characteristics['date_of_participation'] = event_date if program_event.supervision_type: characteristics['supervision_type'] = program_event.supervision_type if program_event.program_location_id: characteristics['program_location_id'] = program_event.program_location_id if program_event.program_id: characteristics['program_id'] = program_event.program_id characteristics = add_demographic_characteristics(characteristics, person, event_date) characteristics_with_person_details = characteristics_with_person_id_fields( characteristics, program_event.state_code, person, 'program') return characteristics_with_person_details
def test_add_demographic_characteristics_NoAttributes(self): characteristics = {} person = StatePerson.new_with_defaults(person_id=12345) event_date = date(2010, 9, 1) updated_characteristics = add_demographic_characteristics( characteristics, person, event_date) expected_output = {} self.assertEqual(updated_characteristics, expected_output)
def characteristics_dict( person: StatePerson, event: ReleaseEvent, metric_type: ReincarcerationRecidivismMetricType) -> Dict[str, Any]: """Builds a dictionary that describes the characteristics of the person and the release event. Release cohort, follow-up period, and methodology are not included in the output here. They are added into augmented versions of these combinations later. Args: person: the StatePerson we are picking characteristics from event: the ReleaseEvent we are picking characteristics from metric_type: The ReincarcerationRecidivismMetricType provided determines which fields should be added to the characteristics dictionary Returns: A dictionary populated with all relevant characteristics. """ characteristics: Dict[str, Any] = {} if event.county_of_residence: characteristics['county_of_residence'] = event.county_of_residence if event.release_facility is not None: characteristics['release_facility'] = event.release_facility event_stay_length = stay_length_from_event(event) event_stay_length_bucket = stay_length_bucket(event_stay_length) characteristics['stay_length_bucket'] = event_stay_length_bucket characteristics = add_demographic_characteristics( characteristics, person, event.original_admission_date) if isinstance( event, RecidivismReleaseEvent ) and metric_type == ReincarcerationRecidivismMetricType.COUNT: time_at_liberty = days_at_liberty(event) characteristics['days_at_liberty'] = time_at_liberty characteristics = characteristics_with_person_id_fields( characteristics, event.state_code, person, 'recidivism') return characteristics
def test_add_demographic_characteristics_MultipleRaces(self): characteristics = {} person = StatePerson.new_with_defaults( person_id=12345, birthdate=date(1984, 8, 31), gender=Gender.FEMALE, races=[ StatePersonRace.new_with_defaults(race=Race.ASIAN), StatePersonRace.new_with_defaults(race=Race.BLACK) ]) event_date = date(2010, 9, 1) updated_characteristics = add_demographic_characteristics( characteristics, person, event_date) expected_output = { 'age_bucket': '25-29', 'race': [Race.ASIAN, Race.BLACK], 'gender': Gender.FEMALE } self.assertEqual(updated_characteristics, expected_output)
def characteristics_dict(person: StatePerson, supervision_time_bucket: SupervisionTimeBucket, metric_type: SupervisionMetricType) -> Dict[str, Any]: """Builds a dictionary that describes the characteristics of the person and supervision_time_bucket. Args: person: the StatePerson we are picking characteristics from supervision_time_bucket: the SupervisionTimeBucket we are picking characteristics from metric_type: The SupervisionMetricType provided determines which fields should be added to the characteristics dictionary Returns: A dictionary populated with all relevant characteristics. """ characteristics: Dict[str, Any] = {} include_revocation_dimensions = _include_revocation_dimensions_for_metric( metric_type) include_assessment_dimensions = _include_assessment_dimensions_for_metric( metric_type) include_demographic_dimensions = _include_demographic_dimensions_for_metric( metric_type) include_person_level_dimensions = _include_person_level_dimensions_for_metric( metric_type) if (metric_type == SupervisionMetricType.POPULATION and isinstance(supervision_time_bucket, (RevocationReturnSupervisionTimeBucket, NonRevocationReturnSupervisionTimeBucket))): if supervision_time_bucket.most_severe_violation_type: characteristics[ 'most_severe_violation_type'] = supervision_time_bucket.most_severe_violation_type if supervision_time_bucket.most_severe_violation_type_subtype: characteristics['most_severe_violation_type_subtype'] = \ supervision_time_bucket.most_severe_violation_type_subtype if supervision_time_bucket.response_count is not None: characteristics[ 'response_count'] = supervision_time_bucket.response_count if include_revocation_dimensions and \ isinstance(supervision_time_bucket, RevocationReturnSupervisionTimeBucket): if supervision_time_bucket.revocation_type: characteristics[ 'revocation_type'] = supervision_time_bucket.revocation_type if supervision_time_bucket.source_violation_type: characteristics[ 'source_violation_type'] = supervision_time_bucket.source_violation_type if metric_type in [ SupervisionMetricType.REVOCATION_ANALYSIS, SupervisionMetricType.REVOCATION_VIOLATION_TYPE_ANALYSIS ]: if supervision_time_bucket.most_severe_violation_type: characteristics[ 'most_severe_violation_type'] = supervision_time_bucket.most_severe_violation_type if supervision_time_bucket.most_severe_violation_type_subtype: characteristics['most_severe_violation_type_subtype'] = \ supervision_time_bucket.most_severe_violation_type_subtype if metric_type in [SupervisionMetricType.REVOCATION_ANALYSIS]: if supervision_time_bucket.most_severe_response_decision: characteristics['most_severe_response_decision'] = \ supervision_time_bucket.most_severe_response_decision if supervision_time_bucket.response_count is not None: characteristics[ 'response_count'] = supervision_time_bucket.response_count if isinstance(supervision_time_bucket, SupervisionTerminationBucket): if supervision_time_bucket.termination_reason: characteristics[ 'termination_reason'] = supervision_time_bucket.termination_reason if supervision_time_bucket.supervision_type: characteristics[ 'supervision_type'] = supervision_time_bucket.supervision_type if supervision_time_bucket.case_type: characteristics['case_type'] = supervision_time_bucket.case_type if not include_revocation_dimensions and supervision_time_bucket.supervision_level: characteristics[ 'supervision_level'] = supervision_time_bucket.supervision_level if include_assessment_dimensions: # TODO(2853): Figure out more robust solution for not assessed people. Here we don't set assessment_type when # someone is not assessed. This only works as desired because BQ doesn't rely on assessment_type at all. characteristics['assessment_score_bucket'] = 'NOT_ASSESSED' if supervision_time_bucket.assessment_score and supervision_time_bucket.assessment_type: assessment_bucket = assessment_score_bucket( supervision_time_bucket.assessment_score, supervision_time_bucket.assessment_level, supervision_time_bucket.assessment_type) if assessment_bucket and include_assessment_in_metric( 'supervision', supervision_time_bucket.state_code, supervision_time_bucket.assessment_type): characteristics['assessment_score_bucket'] = assessment_bucket characteristics[ 'assessment_type'] = supervision_time_bucket.assessment_type if supervision_time_bucket.supervising_officer_external_id: characteristics[ 'supervising_officer_external_id'] = supervision_time_bucket.supervising_officer_external_id if supervision_time_bucket.supervising_district_external_id: characteristics[ 'supervising_district_external_id'] = supervision_time_bucket.supervising_district_external_id if isinstance(supervision_time_bucket, RevocationReturnSupervisionTimeBucket): event_date = supervision_time_bucket.revocation_admission_date elif isinstance(supervision_time_bucket, SupervisionTerminationBucket): event_date = supervision_time_bucket.termination_date else: year = supervision_time_bucket.year month = supervision_time_bucket.month event_date = date(year, month, 1) if include_demographic_dimensions: characteristics = add_demographic_characteristics( characteristics, person, event_date) if include_person_level_dimensions: characteristics = characteristics_with_person_id_fields( characteristics, person, 'supervision') if not include_revocation_dimensions and supervision_time_bucket.supervision_level_raw_text: characteristics['supervision_level_raw_text'] = \ supervision_time_bucket.supervision_level_raw_text if metric_type == SupervisionMetricType.POPULATION: if isinstance(supervision_time_bucket, (RevocationReturnSupervisionTimeBucket, NonRevocationReturnSupervisionTimeBucket)): characteristics['is_on_supervision_last_day_of_month'] = \ supervision_time_bucket.is_on_supervision_last_day_of_month if metric_type == SupervisionMetricType.REVOCATION_ANALYSIS: if isinstance(supervision_time_bucket, RevocationReturnSupervisionTimeBucket) \ and supervision_time_bucket.violation_history_description: characteristics['violation_history_description'] = \ supervision_time_bucket.violation_history_description if include_revocation_dimensions and isinstance( supervision_time_bucket, RevocationReturnSupervisionTimeBucket): characteristics['revocation_admission_date'] = \ supervision_time_bucket.revocation_admission_date if metric_type == SupervisionMetricType.ASSESSMENT_CHANGE: if isinstance(supervision_time_bucket, SupervisionTerminationBucket) \ and supervision_time_bucket.termination_date: characteristics[ 'termination_date'] = supervision_time_bucket.termination_date return characteristics
def characteristics_dict( person: StatePerson, incarceration_event: IncarcerationEvent) -> Dict[str, Any]: """Builds a dictionary that describes the characteristics of the person and event. Args: person: the StatePerson we are picking characteristics from incarceration_event: the IncarcerationEvent we are picking characteristics from Returns: A dictionary populated with all relevant characteristics. """ characteristics: Dict[str, Any] = {} # Add characteristics that will be used to generate dictionaries with unique combinations. if isinstance(incarceration_event, IncarcerationAdmissionEvent): characteristics['admission_date'] = incarceration_event.event_date 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 # TODO(3275): Rename to purpose_for_incarceration if incarceration_event.specialized_purpose_for_incarceration: characteristics['specialized_purpose_for_incarceration'] = \ incarceration_event.specialized_purpose_for_incarceration if isinstance(incarceration_event, IncarcerationReleaseEvent): characteristics['release_date'] = incarceration_event.event_date if incarceration_event.release_reason: characteristics[ 'release_reason'] = incarceration_event.release_reason if incarceration_event.release_reason_raw_text: characteristics[ 'release_reason_raw_text'] = incarceration_event.release_reason_raw_text if incarceration_event.purpose_for_incarceration: characteristics[ 'purpose_for_incarceration'] = incarceration_event.purpose_for_incarceration if incarceration_event.supervision_type_at_release: characteristics[ 'supervision_type_at_release'] = incarceration_event.supervision_type_at_release if incarceration_event.admission_reason: characteristics[ 'admission_reason'] = incarceration_event.admission_reason # Have to explicitly check if this is not None because 0 is a valid value and evaluates to False if incarceration_event.total_days_incarcerated is not None: characteristics[ 'total_days_incarcerated'] = incarceration_event.total_days_incarcerated if isinstance(incarceration_event, IncarcerationStayEvent): characteristics['date_of_stay'] = incarceration_event.event_date 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.judicial_district_code: characteristics[ 'judicial_district_code'] = incarceration_event.judicial_district_code # 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 event_date = incarceration_event.event_date characteristics = add_demographic_characteristics(characteristics, person, event_date) characteristics_with_person_details = add_person_level_characteristics( person, incarceration_event, characteristics) return characteristics_with_person_details