docstr: Do everything necessary after the fitting is done:
  
  * predicting
  * saving the files for the ensembles_statistics
  * generate output for SMAC
  We use it as the signal handler so we can recycle the code for the
  normal usecase and when the runsolver kills us here :)
docstr_tok: ["Do","everything","necessary","after","the","fitting","is","done",":","*","predicting","*","saving","the","files","for","the","ensembles_statistics","*","generate","output","for","SMAC","We","use","it","as","the","signal","handler","so","we","can","recycle","the","code","for","the","normal","usecase","and","when","the","runsolver","kills","us","here",":",")"]
code: def finish_up(
      self,
      loss: Union[Dict[str, float], float],
      train_loss: Optional[Dict[str, float]],
      opt_pred: np.ndarray,
      test_pred: np.ndarray,
      additional_run_info: Optional[TYPE_ADDITIONAL_INFO],
      file_output: bool,
      final_call: bool,
      status: StatusType,
  ) -> Tuple[
      float,
      Union[float, Dict[str, float]],
      int,
      Dict[str, Union[str, int, float, Dict, List, Tuple]],
  ]:
      """Do everything necessary after the fitting is done:
  
      * predicting
      * saving the files for the ensembles_statistics
      * generate output for SMAC
      We use it as the signal handler so we can recycle the code for the
      normal usecase and when the runsolver kills us here :)
      """
      self.duration = time.time() - self.starttime
  
      if file_output:
          file_out_loss, additional_run_info_ = self.file_output(
              opt_pred, test_pred
          )
      else:
          file_out_loss = None
          additional_run_info_ = {}
  
      test_loss = self.calculate_auxiliary_losses(test_pred)
  
      if file_out_loss is not None:
          return (
              self.duration,
              file_out_loss,
              self.seed,
              additional_run_info_,
          )
  
      loss_ = loss
      for metric in self.metrics:
          if metric.name not in loss_:
              raise ValueError(
                  f"Unable to compute optimization metric {metric.name}. Are you "
                  f"sure {metric.name} is applicable for the given task type?"
              )
      if len(self.metrics) == 1:
          loss = loss_[self.metrics[0].name]
      else:
          loss = {
              metric.name: loss_[metric.name] for metric in self.metrics
          }
  
      additional_run_info = (
          {} if additional_run_info is None else additional_run_info
      )
      for metric in self.scoring_functions:
          if metric.name in loss_:
              additional_run_info[metric.name] = loss_[metric.name]
      additional_run_info["duration"] = self.duration
      additional_run_info["num_run"] = self.num_run
      if train_loss is not None:
          if len(self.metrics) == 1:
              additional_run_info["train_loss"] = train_loss[
                  self.metrics[0].name
              ]
          else:
              additional_run_info["train_loss"] = [
                  train_loss[metric.name] for metric in self.metrics
              ]
      if test_loss is not None:
          additional_run_info["test_loss"] = test_loss
  
      return_value_dict = {
          "loss": loss,
          "additional_run_info": additional_run_info,
          "status": status,
      }
      if final_call:
          return_value_dict["final_queue_element"] = True
  
      self.queue.put(return_value_dict)
      return self.duration, loss_, self.seed, additional_run_info_
  
imports: from __future__ import annotations
  from typing import Any, Dict, List, Optional, Sequence, TextIO, Tuple, Type, Union, cast
  import logging
  import multiprocessing
  import time
  import warnings
  import numpy
  from ConfigSpace import Configuration
  from sklearn.base import BaseEstimator
  from sklearn.dummy import DummyClassifier, DummyRegressor
  from sklearn.ensemble import VotingClassifier, VotingRegressor
  from smac.tae import StatusType
  from threadpoolctl import threadpool_limits
  import autosklearn.pipeline.classification
  import autosklearn.pipeline.regression
  from autosklearn.askl_typing import FEAT_TYPE_TYPE
  from autosklearn.automl_common.common.utils.backend import Backend
  from autosklearn.constants import CLASSIFICATION_TASKS, MULTICLASS_CLASSIFICATION, MULTILABEL_CLASSIFICATION, MULTIOUTPUT_REGRESSION, REGRESSION_TASKS
  from autosklearn.data.target_validator import SUPPORTED_TARGET_TYPES, SUPPORTED_XDATA_TYPES
  from autosklearn.metrics import Scorer, calculate_losses
  from autosklearn.pipeline.components.base import ThirdPartyComponents, _addons
  from autosklearn.pipeline.implementations.util import convert_multioutput_multiclass_to_multilabel
  from autosklearn.util.logging_ import PicklableClientLogger, get_named_client_logger
label_desc: Use image node_id 4 for calling the AbstractEvaluator obj's underlying member method code with example usage: obj.finish_up(loss, train_loss, opt_pred, test_pred, additional_run_info, file_output, final_call, status) and returns: self,  loss_,  self,  additional_run_info_, self,  file_out_loss,  self,  additional_run_info_