code: def log_to_tensorboard(self, metric_name: str) -> None:
      self.check_estimates_exist()
  
      def none_to_zero(x: Optional[float]) -> float:
          if x is None or math.isnan(x):
              return 0.0
          return x
  
      for name, value in [
          (
              "CPE/{}/Direct_Method_Reward".format(metric_name),
              # pyre-fixme[16]: `Optional` has no attribute `normalized`.
              self.direct_method.normalized,
          ),
          (
              "CPE/{}/IPS_Reward".format(metric_name),
              self.inverse_propensity.normalized,
          ),
          (
              "CPE/{}/Doubly_Robust_Reward".format(metric_name),
              self.doubly_robust.normalized,
          ),
          (
              "CPE/{}/Sequential_Doubly_Robust".format(metric_name),
              self.sequential_doubly_robust.normalized,
          ),
          (
              "CPE/{}/Weighted_Sequential_Doubly_Robust".format(
                  metric_name
              ),
              self.weighted_doubly_robust.normalized,
          ),
          ("CPE/{}/MAGIC".format(metric_name), self.magic.normalized),
      ]:
          SummaryWriterContext.add_scalar(name, none_to_zero(value))
  
file_path: ReAgent/reagent/evaluation/cpe.py
imports: import logging
  import math
  from typing import Dict, NamedTuple, Optional
  import numpy
  import torch
  from reagent.core.tensorboardX import SummaryWriterContext
label_desc: Use image node_id 3 for calling the CpeEstimateSet obj's underlying member method code with example usage: obj.log_to_tensorboard(metric_name) and returns: x, int