code: def edp_to_contextual_bandit_log(
      edp: EvaluationDataPage, device=None
  ) -> BanditsEstimatorInput:
      log = []
      n = edp.model_rewards.shape[0]
      for idx in range(n):
          # Action is only 1 if tgt policy and log policy took same action?
          action = torch.argmax(edp.action_mask[idx]).item()
          # pyre-fixme[6]: For 1st param expected `Union[None, List[typing.Any],
          #  int, slice, Tensor, typing.Tuple[typing.Any, ...]]` but got `Union[bool,
          #  float, int]`.
          if edp.action_mask[idx][action] == 0.0:
              action = None
          logged_propensities = torch.zeros(
              edp.model_propensities[idx].shape, device=device
          )
          if action is not None:
              # pyre-fixme[6]: For 1st param expected `Union[None,
              #  List[typing.Any], int, slice, Tensor, typing.Tuple[typing.Any,
              #  ...]]` but got `Union[bool, float, int]`.
              logged_propensities[action] = edp.logged_propensities[idx]
          log.append(
              LogSample(
                  context=None
                  if edp.contexts is None
                  else edp.contexts[idx],
                  # pyre-fixme[6]: For 1st param expected `Union[Tuple[float],
                  #  Tuple[int], float, int, ndarray, Tensor]` but got `Union[None,
                  #  bool, float, int]`.
                  log_action=Action(action),
                  # pyre-fixme[6]: For 3rd param expected `float` but got `Tensor`.
                  log_reward=edp.logged_rewards[idx],
                  log_action_probabilities=ActionDistribution(
                      logged_propensities
                  ),
                  tgt_action_probabilities=ActionDistribution(
                      edp.model_propensities[idx]
                  ),
                  # pyre-fixme[6]: For 1st param expected `Union[Tuple[float],
                  #  Tuple[int], float, int, ndarray, Tensor]` but got `Union[None,
                  #  bool, float, int]`.
                  tgt_action=Action(action),
                  model_outputs=ModelOutputs(
                      # pyre-fixme[6]: For 1st param expected `float` but got
                      #  `Tensor`.
                      tgt_reward_from_log_action=edp.model_rewards_for_logged_action[
                          idx
                      ],
                      # pyre-fixme[6]: For 2nd param expected `Sequence[float]`
                      #  but got `Tensor`.
                      tgt_rewards=edp.model_rewards[idx],
                  )
                  # item features not specified as edp came from trained reward model
              )
          )
      return BanditsEstimatorInput(
          ActionSpace(edp.action_mask.shape[1]), log, True
      )
  
imports: import logging
  import torch
  from reagent.evaluation.cpe import bootstrapped_std_error_of_mean, CpeEstimate, CpeEstimateSet
  from reagent.evaluation.evaluation_data_page import EvaluationDataPage
  from reagent.evaluation.evaluator import Evaluator
  from reagent.evaluation.weighted_sequential_doubly_robust_estimator import WeightedSequentialDoublyRobustEstimator
  from reagent.ope.estimators.contextual_bandits_estimators import BanditsEstimatorInput, DMEstimator, DoublyRobustEstimator, IPSEstimator, LogSample, ModelOutputs
  from reagent.ope.estimators.estimator import Estimator, EstimatorResult, EstimatorResults
  from reagent.ope.estimators.sequential_estimators import Action, ActionDistribution, DoublyRobustEstimator, MAGICEstimator, RLEstimator, RLEstimatorInput, RLPolicy, State, Transition, ValueFunction
  from reagent.ope.estimators.types import ActionSpace
label_desc: Use image node_id 2 for calling the OPEstimatorAdapter obj's underlying member method code with example usage: obj.edp_to_contextual_bandit_log(edp, device) and returns: BanditsEstimatorInput