def score_notes(
    self, noteStats: pd.DataFrame, currentLabels: pd.DataFrame, statusColumn: str
  ) -> Tuple[pd.DataFrame, Optional[pd.DataFrame]]:
    """Propagates any status set in sourceColumn when it is non-NaN."""
    # If necessary, prune noteStats according to prior firm rejects
    if self._checkFirmReject:
      coreRejects = noteStats[c.coreRatingStatusKey].isin(
        {c.firmReject, c.currentlyRatedNotHelpful}
      )
      expansionRejects = noteStats[c.expansionRatingStatusKey].isin(
        {c.firmReject, c.currentlyRatedNotHelpful}
      )
      crhBlocked = coreRejects | (noteStats[c.coreRatingStatusKey].isna() & expansionRejects)
      # FIRM_REJECT from upstream models should block both CRH and NYH status
      crhNotes = noteStats[self._sourceColumn].isin({c.currentlyRatedHelpful, c.needsYourHelp})
      noteStats = noteStats[~(crhBlocked & crhNotes)]
    # If necessary, prune noteStatus based on filter column pairs
    if self._filterColumnPairs:
      for col, value in self._filterColumnPairs:
        noteStats = noteStats[noteStats[col] == value]
    # Generate the set of note status updates
    statusUpdateRows = ~noteStats[self._sourceColumn].isna()
    noteStatusUpdates = noteStats[statusUpdateRows][[c.noteIdKey, self._sourceColumn]].rename(
      columns={self._sourceColumn: statusColumn}
    )
    # Rename FIRM_REJECT to NEEDS_MORE_RATINGS since the status will be exported as the final status
    noteStatusUpdates.loc[
      noteStatusUpdates[statusColumn] == c.firmReject, statusColumn
    ] = c.needsMoreRatings
    assert (
      noteStatusUpdates[statusColumn]
      .isin(
        {c.currentlyRatedHelpful, c.currentlyRatedNotHelpful, c.needsMoreRatings, c.needsYourHelp}
      )
      .all()
    ), "status must be set to CRH, CRNH, NMR or NYH"
    return (noteStatusUpdates, None)
Propagates any status set in sourceColumn when it is non-NaN.
sourcecode/scoring/scoring_rules.py