def run_scoring(
  args,
  notes: pd.DataFrame,
  ratings: pd.DataFrame,
  noteStatusHistory: pd.DataFrame,
  userEnrollment: pd.DataFrame,
  seed: Optional[int] = None,
  pseudoraters: Optional[bool] = True,
  enabledScorers: Optional[Set[Scorers]] = None,
  strictColumns: bool = True,
  runParallel: bool = True,
  dataLoader: Optional[CommunityNotesDataLoader] = None,
  useStableInitialization: bool = True,
  writePrescoringScoringOutputCallback: Optional[
    Callable[
      [
        pd.DataFrame,
        pd.DataFrame,
        sklearn.pipeline.Pipeline,
        sklearn.pipeline.Pipeline,
        c.PrescoringMetaOutput,
        Optional[pd.DataFrame],
      ],
      None,
    ]
  ] = None,
  cutoffTimestampMillis: Optional[int] = None,
  excludeRatingsAfterANoteGotFirstStatusPlusNHours: Optional[int] = None,
  daysInPastToApplyPostFirstStatusFiltering: Optional[int] = 14,
  filterPrescoringInputToSimulateDelayInHours: Optional[int] = None,
  checkFlips: bool = True,
  previousScoredNotes: Optional[pd.DataFrame] = None,
  previousAuxiliaryNoteInfo: Optional[pd.DataFrame] = None,
  previousRatingCutoffTimestampMillis: Optional[int] = 0,
):
  """Runs both phases of scoring consecutively. Only for adhoc/testing use.
  In prod, we run each phase as a separate binary.

  Wrapper around run_prescoring, run_final_note_scoring, and run_contributor_scoring.

  Invokes note scoring algorithms, merges results and computes user stats.

  Args:
    ratings (pd.DataFrame): preprocessed ratings
    noteStatusHistory (pd.DataFrame): one row per note; history of when note had each status
    userEnrollment (pd.DataFrame): The enrollment state for each contributor
    seed (int, optional): if not None, base distinct seeds for the first and second MF rounds on this value
    pseudoraters (bool, optional): if True, compute optional pseudorater confidence intervals
    enabledScorers (Set[Scorers], optional): Scorers which should be instantiated
    strictColumns (bool, optional): if True, validate which columns are present
    runParallel (bool, optional): if True, run algorithms in parallel
    dataLoader (CommunityNotesDataLoader, optional): dataLoader provided to parallel execution
    useStableInitialization
    writePrescoringScoringOutputCallback
    filterPrescoringInputToSimulateDelayInHours

  Returns:
    Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame]:
      scoredNotes pd.DataFrame: one row per note contained note scores and parameters.
      helpfulnessScores pd.DataFrame: one row per user containing a column for each helpfulness score.
      noteStatusHistory pd.DataFrame: one row per note containing when they got their most recent statuses.
      auxiliaryNoteInfo: one row per note containing adjusted and ratio tag values
  """
  # Filter input data for testing if optional args present. Else, do nothing.
  (
    notes,
    ratings,
    prescoringNotesInput,
    prescoringRatingsInput,
  ) = filter_input_data_for_testing(
    notes,
    ratings,
    noteStatusHistory,
    cutoffTimestampMillis,
    excludeRatingsAfterANoteGotFirstStatusPlusNHours,
    daysInPastToApplyPostFirstStatusFiltering,
    filterPrescoringInputToSimulateDelayInHours,
  )

  postSelectionSimilarityValues = run_post_selection_similarity(notes=notes, ratings=ratings)

  (
    prescoringNoteModelOutput,
    prescoringRaterModelOutput,
    prescoringNoteTopicClassifier,
    prescoringPflipClassifier,
    prescoringMetaOutput,
    prescoringScoredNotes,
  ) = run_prescoring(
    args,
    notes=prescoringNotesInput,
    ratings=prescoringRatingsInput,
    noteStatusHistory=noteStatusHistory,
    userEnrollment=userEnrollment,
    postSelectionSimilarityValues=postSelectionSimilarityValues,
    seed=seed,
    enabledScorers=enabledScorers,
    runParallel=runParallel,
    dataLoader=dataLoader,
    useStableInitialization=useStableInitialization,
    checkFlips=False,
    previousRatingCutoffTimestampMillis=previousRatingCutoffTimestampMillis,
  )

  logger.info("We invoked run_scoring and are now in between prescoring and scoring.")
  if writePrescoringScoringOutputCallback is not None:
    with c.time_block("Writing prescoring output."):
      writePrescoringScoringOutputCallback(
        prescoringNoteModelOutput,
        prescoringRaterModelOutput,
        prescoringNoteTopicClassifier,
        prescoringPflipClassifier,
        prescoringMetaOutput,
        prescoringScoredNotes,
      )
  logger.info("Starting final scoring")

  scoredNotes, newNoteStatusHistory, auxiliaryNoteInfo, _ = run_final_note_scoring(
    args,
    notes=notes,
    ratings=ratings,
    noteStatusHistory=noteStatusHistory,
    userEnrollment=userEnrollment,
    seed=seed,
    pseudoraters=pseudoraters,
    enabledScorers=enabledScorers,
    strictColumns=strictColumns,
    runParallel=runParallel,
    dataLoader=dataLoader,
    useStableInitialization=useStableInitialization,
    prescoringNoteModelOutput=prescoringNoteModelOutput,
    prescoringRaterModelOutput=prescoringRaterModelOutput,
    noteTopicClassifier=prescoringNoteTopicClassifier,
    pflipClassifier=prescoringPflipClassifier,
    prescoringMetaOutput=prescoringMetaOutput,
    checkFlips=checkFlips,
    previousScoredNotes=previousScoredNotes,
    previousAuxiliaryNoteInfo=previousAuxiliaryNoteInfo,
    previousRatingCutoffTimestampMillis=previousRatingCutoffTimestampMillis,
  )

  logger.info("Starting contributor scoring")

  helpfulnessScores = run_contributor_scoring(
    ratings=ratings,
    scoredNotes=scoredNotes,
    auxiliaryNoteInfo=auxiliaryNoteInfo,
    prescoringRaterModelOutput=prescoringRaterModelOutput,
    noteStatusHistory=newNoteStatusHistory,
    userEnrollment=userEnrollment,
    strictColumns=strictColumns,
  )

  return scoredNotes, helpfulnessScores, newNoteStatusHistory, auxiliaryNoteInfo
Runs both phases of scoring consecutively. Only for adhoc/testing use.
  In prod, we run each phase as a separate binary.

  Wrapper around run_prescoring, run_final_note_scoring, and run_contributor_scoring.

  Invokes note scoring algorithms, merges results and computes user stats.

  Args:
    ratings (pd.DataFrame): preprocessed ratings
    noteStatusHistory (pd.DataFrame): one row per note; history of when note had each status
    userEnrollment (pd.DataFrame): The enrollment state for each contributor
    seed (int, optional): if not None, base distinct seeds for the first and second MF rounds on this value
    pseudoraters (bool, optional): if True, compute optional pseudorater confidence intervals
    enabledScorers (Set[Scorers], optional): Scorers which should be instantiated
    strictColumns (bool, optional): if True, validate which columns are present
    runParallel (bool, optional): if True, run algorithms in parallel
    dataLoader (CommunityNotesDataLoader, optional): dataLoader provided to parallel execution
    useStableInitialization
    writePrescoringScoringOutputCallback
    filterPrescoringInputToSimulateDelayInHours

  Returns:
    Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame]:
      scoredNotes pd.DataFrame: one row per note contained note scores and parameters.
      helpfulnessScores pd.DataFrame: one row per user containing a column for each helpfulness score.
      noteStatusHistory pd.DataFrame: one row per note containing when they got their most recent statuses.
      auxiliaryNoteInfo: one row per note containing adjusted and ratio tag values
  
sourcecode/scoring/run_scoring.py