def should_include_in_release_cohort( status: StateIncarcerationPeriodStatus, release_date: Optional[date], release_reason: Optional[ReleaseReason], next_incarceration_period: Optional[StateIncarcerationPeriod]) -> bool: """Identifies whether a period of incarceration with the given features should be included in the release cohort.""" # If the person is still in custody, there is no release to include in a cohort. if status == StateIncarcerationPeriodStatus.IN_CUSTODY: return False if not release_date: # If the person is not in custody, there should be a release_date. # This should not happen after validation. Throw error. raise ValueError("release_date is not set where it should be.") if not release_reason: # If there is no recorded release reason, then we cannot classify this as a valid release for the cohort return False if next_incarceration_period: time_range_release = DateRange.for_day(release_date) if DateRangeDiff(time_range_release, next_incarceration_period.duration).overlapping_range: # If the release overlaps with the following incarceration period, this is not an actual release from # incarceration return False if next_incarceration_period.release_date and release_date == next_incarceration_period.release_date: # This release shares a release_date with the next incarceration period. Do not include this release. return False if release_reason in [ReleaseReason.DEATH, ReleaseReason.EXECUTION]: # If the person was released from this incarceration period because they died or were executed, do not include # them in the release cohort. return False if release_reason == ReleaseReason.ESCAPE: # If the person was released from this incarceration period because they escaped, do not include them in the # release cohort. return False if release_reason == ReleaseReason.RELEASED_FROM_TEMPORARY_CUSTODY: # If the person was released from a period of temporary custody, do not include them in the release_cohort. return False if release_reason == ReleaseReason.RELEASED_IN_ERROR: # If the person was released from this incarceration period due to an error, do not include them in the # release cohort. return False if release_reason == ReleaseReason.TRANSFER: # If the person was released from this incarceration period because they were transferred elsewhere, do not # include them in the release cohort. return False if release_reason == ReleaseReason.TRANSFERRED_OUT_OF_STATE: # Releases where the person has been transferred out of state don't really count as true releases. return False if release_reason == ReleaseReason.COURT_ORDER: # If the person was released from this incarceration period due to a court order, do not include them in the # release cohort. return False if release_reason in (ReleaseReason.EXTERNAL_UNKNOWN, ReleaseReason.INTERNAL_UNKNOWN): # We do not have enough information to determine whether this release qualifies for inclusion in the release # cohort. return False if release_reason in (ReleaseReason.COMMUTED, ReleaseReason.COMPASSIONATE, ReleaseReason.CONDITIONAL_RELEASE, ReleaseReason.PARDONED, ReleaseReason.RELEASED_FROM_ERRONEOUS_ADMISSION, ReleaseReason.SENTENCE_SERVED, ReleaseReason.VACATED): return True raise ValueError("Enum case not handled for " "StateIncarcerationPeriodReleaseReason of type:" f" {release_reason}.")
@classmethod def get_or_default(cls, text: Optional[str]) -> 'SnapshotType': if text is None: return SnapshotType.DAY return cls(text) DAY = 'DAY' FIRST_DAY_OF_MONTH = 'FIRST_DAY_OF_MONTH' LAST_DAY_OF_MONTH = 'LAST_DAY_OF_MONTH' SNAPSHOT_CONVERTERS: Dict[SnapshotType, DateRangeConverterType] = { SnapshotType.DAY: DateRange.for_day, SnapshotType.FIRST_DAY_OF_MONTH: lambda date: DateRange.for_day(first_day_of_month(date)), SnapshotType.LAST_DAY_OF_MONTH: lambda date: DateRange.for_day(last_day_of_month(date)), } class Metric: @property @abstractmethod def filters(self) -> List[Dimension]: """Any dimensions where the data only represents a subset of values for that dimension. For instance, a table for the population metric may only cover data for the prison population, not those on parole or probation. In that case filters would contain PopulationType.PRISON. """