code: def sensitivity_simulation(
      data: pd.DataFrame,
      target_estimand: IdentifiedEstimand,
      estimate: CausalEstimate,
      treatment_name: str,
      outcome_name: str,
      kappa_t: Optional[Union[float, np.ndarray]] = None,
      kappa_y: Optional[Union[float, np.ndarray]] = None,
      confounders_effect_on_treatment: str = "binary_flip",
      confounders_effect_on_outcome: str = "linear",
      frac_strength_treatment: float = 1.0,
      frac_strength_outcome: float = 1.0,
      plotmethod: Optional[str] = None,
      show_progress_bar=False,
      **_,
  ) -> CausalRefutation:
      """
      This function attempts to add an unobserved common cause to the outcome and the treatment. At present, we have implemented the behavior for one dimensional behaviors for continuous
      and binary variables. This function can either take single valued inputs or a range of inputs. The function then looks at the data type of the input and then decides on the course of
      action.
  
      :param data: pd.DataFrame: Data to run the refutation
      :param target_estimand: IdentifiedEstimand: Identified estimand to run the refutation
      :param estimate: CausalEstimate: Estimate to run the refutation
      :param treatment_name: str: Name of the treatment
      :param outcome_name: str: Name of the outcome
      :param kappa_t: float, numpy.ndarray: Strength of the confounder's effect on treatment. When confounders_effect_on_treatment is linear,  it is the regression coefficient. When the confounders_effect_on_treatment is binary flip, it is the probability with which effect of unobserved confounder can invert the value of the treatment.
      :param kappa_y: float, numpy.ndarray: Strength of the confounder's effect on outcome. Its interpretation depends on confounders_effect_on_outcome and the simulation_method. When simulation_method is direct-simulation, for a linear effect it behaves like the regression coefficient and for a binary flip, it is the probability with which it can invert the value of the outcome.
      :param confounders_effect_on_treatment: str : The type of effect on the treatment due to the unobserved confounder. Possible values are ['binary_flip', 'linear']
      :param confounders_effect_on_outcome: str : The type of effect on the outcome due to the unobserved confounder. Possible values are ['binary_flip', 'linear']
      :param frac_strength_treatment: float: This parameter decides the effect strength of the simulated confounder as a fraction of the effect strength of observed confounders on treatment. Defaults to 1.
      :param frac_strength_outcome: float: This parameter decides the effect strength of the simulated confounder as a fraction of the effect strength of observed confounders on outcome. Defaults to 1.
      :param plotmethod: string: Type of plot to be shown. If None, no plot is generated. This parameter is used only only when more than one treatment confounder effect values or outcome confounder effect values are provided. Default is "colormesh". Supported values are "contour", "colormesh" when more than one value is provided for both confounder effect value parameters; "line" when provided for only one of them.
  
      :return: CausalRefuter: An object that contains the estimated effect and a new effect and the name of the refutation used.
      """
      if kappa_t is None:
          kappa_t = _infer_default_kappa_t(
              data,
              target_estimand,
              treatment_name,
              confounders_effect_on_treatment,
              frac_strength_treatment,
          )
      if kappa_y is None:
          kappa_y = _infer_default_kappa_y(
              data,
              target_estimand,
              outcome_name,
              confounders_effect_on_outcome,
              frac_strength_outcome,
          )
  
      if not isinstance(kappa_t, (list, np.ndarray)) and not isinstance(
          kappa_y, (list, np.ndarray)
      ):  # Deal with single value inputs
          new_data = copy.deepcopy(data)
          new_data = _include_confounders_effect(
              data,
              new_data,
              confounders_effect_on_treatment,
              treatment_name,
              kappa_t,
              confounders_effect_on_outcome,
              outcome_name,
              kappa_y,
          )
          new_estimator = estimate.estimator.get_new_estimator_object(
              target_estimand
          )
          new_estimator.fit(
              new_data,
              estimate.estimator._effect_modifier_names,
              **new_estimator._econml_fit_params
              if isinstance(new_estimator, Econml)
              else {},
          )
          new_effect = new_estimator.estimate_effect(
              new_data,
              control_value=estimate.control_value,
              treatment_value=estimate.treatment_value,
              target_units=estimate.estimator._target_units,
          )
          refute = CausalRefutation(
              estimate.value,
              new_effect.value,
              refutation_type="Refute: Add an Unobserved Common Cause",
          )
  
          refute.new_effect_array = np.array(new_effect.value)
          refute.new_effect = new_effect.value
          return refute
  
      else:  # Deal with multiple value inputs
          if isinstance(kappa_t, (list, np.ndarray)) and isinstance(
              kappa_y, (list, np.ndarray)
          ):  # Deal with range inputs
              # Get a 2D matrix of values
              # x,y =  np.meshgrid(self.kappa_t, self.kappa_y) # x,y are both MxN
  
              results_matrix = np.random.rand(
                  len(kappa_t), len(kappa_y)
              )  # Matrix to hold all the results of NxM
              orig_data = copy.deepcopy(data)
  
              for i in tqdm(
                  range(len(kappa_t)),
                  colour=CausalRefuter.PROGRESS_BAR_COLOR,
                  disable=not show_progress_bar,
                  desc="Refuting Estimates: ",
              ):
                  for j in range(len(kappa_y)):
                      new_data = _include_confounders_effect(
                          data,
                          orig_data,
                          confounders_effect_on_treatment,
                          treatment_name,
                          kappa_t[i],
                          confounders_effect_on_outcome,
                          outcome_name,
                          kappa_y[j],
                      )
                      new_estimator = (
                          estimate.estimator.get_new_estimator_object(
                              target_estimand
                          )
                      )
                      new_estimator.fit(
                          new_data,
                          estimate.estimator._effect_modifier_names,
                          **new_estimator._econml_fit_params
                          if isinstance(new_estimator, Econml)
                          else {},
                      )
                      new_effect = new_estimator.estimate_effect(
                          new_data,
                          control_value=estimate.control_value,
                          treatment_value=estimate.treatment_value,
                          target_units=estimate.estimator._target_units,
                      )
                      refute = CausalRefutation(
                          estimate.value,
                          new_effect.value,
                          refutation_type="Refute: Add an Unobserved Common Cause",
                      )
                      results_matrix[i][
                          j
                      ] = refute.new_effect  # Populate the results
  
              refute.new_effect_array = results_matrix
              refute.new_effect = (
                  np.min(results_matrix),
                  np.max(results_matrix),
              )
              # Store the values into the refute object
              if plotmethod is None:
                  return refute
  
              import matplotlib.pyplot as plt
  
              fig = plt.figure(figsize=(6, 5))
              left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
              ax = fig.add_axes([left, bottom, width, height])
  
              oe = estimate.value
              contour_levels = [oe / 4.0, oe / 2.0, (3.0 / 4) * oe, oe]
              contour_levels.extend(
                  [0, np.min(results_matrix), np.max(results_matrix)]
              )
              if plotmethod == "contour":
                  cp = plt.contourf(
                      kappa_y,
                      kappa_t,
                      results_matrix,
                      levels=sorted(contour_levels),
                  )
                  # Adding a label on the contour line for the original estimate
                  fmt = {}
                  trueeffect_index = np.where(cp.levels == oe)[0][0]
                  fmt[cp.levels[trueeffect_index]] = "Estimated Effect"
                  # Label every other level using strings
                  plt.clabel(
                      cp,
                      [cp.levels[trueeffect_index]],
                      inline=True,
                      fmt=fmt,
                  )
                  plt.colorbar(cp)
              elif plotmethod == "colormesh":
                  cp = plt.pcolormesh(
                      kappa_y,
                      kappa_t,
                      results_matrix,
                      shading="nearest",
                  )
                  plt.colorbar(cp, ticks=contour_levels)
              ax.yaxis.set_ticks(kappa_t)
              ax.xaxis.set_ticks(kappa_y)
              plt.xticks(rotation=45)
              ax.set_title("Effect of Unobserved Common Cause")
              ax.set_ylabel("Value of Linear Constant on Treatment")
              ax.set_xlabel("Value of Linear Constant on Outcome")
              plt.show()
  
              return refute
  
          elif isinstance(kappa_t, (list, np.ndarray)):
              outcomes = np.random.rand(len(kappa_t))
              orig_data = copy.deepcopy(data)
  
              for i in tqdm(
                  range(0, len(kappa_t)),
                  colour=CausalRefuter.PROGRESS_BAR_COLOR,
                  disable=not show_progress_bar,
                  desc="Refuting Estimates: ",
              ):
                  new_data = _include_confounders_effect(
                      data,
                      orig_data,
                      confounders_effect_on_treatment,
                      treatment_name,
                      kappa_t[i],
                      confounders_effect_on_outcome,
                      outcome_name,
                      kappa_y,
                  )
                  new_estimator = (
                      estimate.estimator.get_new_estimator_object(
                          target_estimand
                      )
                  )
                  new_estimator.fit(
                      new_data,
                      estimate.estimator._effect_modifier_names,
                      **new_estimator._econml_fit_params
                      if isinstance(new_estimator, Econml)
                      else {},
                  )
                  new_effect = new_estimator.estimate_effect(
                      new_data,
                      control_value=estimate.control_value,
                      treatment_value=estimate.treatment_value,
                      target_units=estimate.estimator._target_units,
                  )
                  refute = CausalRefutation(
                      estimate.value,
                      new_effect.value,
                      refutation_type="Refute: Add an Unobserved Common Cause",
                  )
                  logger.debug(refute)
                  outcomes[
                      i
                  ] = refute.new_effect  # Populate the results
  
              refute.new_effect_array = outcomes
              refute.new_effect = (np.min(outcomes), np.max(outcomes))
              if plotmethod is None:
                  return refute
  
              import matplotlib.pyplot as plt
  
              fig = plt.figure(figsize=(6, 5))
              left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
              ax = fig.add_axes([left, bottom, width, height])
  
              plt.plot(kappa_t, outcomes)
              plt.axhline(estimate.value, linestyle="--", color="gray")
              ax.set_title("Effect of Unobserved Common Cause")
              ax.set_xlabel("Value of Linear Constant on Treatment")
              ax.set_ylabel(
                  "Estimated Effect after adding the common cause"
              )
              plt.show()
  
              return refute
  
          elif isinstance(kappa_y, (list, np.ndarray)):
              outcomes = np.random.rand(len(kappa_y))
              orig_data = copy.deepcopy(data)
  
              for i in tqdm(
                  range(0, len(kappa_y)),
                  colour=CausalRefuter.PROGRESS_BAR_COLOR,
                  disable=not show_progress_bar,
                  desc="Refuting Estimates: ",
              ):
                  new_data = _include_confounders_effect(
                      data,
                      orig_data,
                      confounders_effect_on_treatment,
                      treatment_name,
                      kappa_t,
                      confounders_effect_on_outcome,
                      outcome_name,
                      kappa_y[i],
                  )
                  new_estimator = (
                      estimate.estimator.get_new_estimator_object(
                          target_estimand
                      )
                  )
                  new_estimator.fit(
                      new_data,
                      estimate.estimator._effect_modifier_names,
                      **new_estimator._econml_fit_params
                      if isinstance(new_estimator, Econml)
                      else {},
                  )
                  new_effect = new_estimator.estimate_effect(
                      new_data,
                      control_value=estimate.control_value,
                      treatment_value=estimate.treatment_value,
                      target_units=estimate.estimator._target_units,
                  )
                  refute = CausalRefutation(
                      estimate.value,
                      new_effect.value,
                      refutation_type="Refute: Add an Unobserved Common Cause",
                  )
                  logger.debug(refute)
                  outcomes[
                      i
                  ] = refute.new_effect  # Populate the results
  
              refute.new_effect_array = outcomes
              refute.new_effect = (np.min(outcomes), np.max(outcomes))
              if plotmethod is None:
                  return refute
  
              import matplotlib.pyplot as plt
  
              fig = plt.figure(figsize=(6, 5))
              left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
              ax = fig.add_axes([left, bottom, width, height])
  
              plt.plot(kappa_y, outcomes)
              plt.axhline(estimate.value, linestyle="--", color="gray")
              ax.set_title("Effect of Unobserved Common Cause")
              ax.set_xlabel("Value of Linear Constant on Outcome")
              ax.set_ylabel(
                  "Estimated Effect after adding the common cause"
              )
              plt.show()
  
              return refute
  
imports: import copy
  import logging
  import math
  from typing import Dict, List, Optional, Union
  import numpy
  import pandas
  import scipy.stats
  import statsmodels.api
  from sklearn.linear_model import LogisticRegression
  from sklearn.preprocessing import StandardScaler
  from tqdm.auto import tqdm
  from dowhy.causal_estimator import CausalEstimate
  from dowhy.causal_estimators.econml import Econml
  from dowhy.causal_estimators.linear_regression_estimator import LinearRegressionEstimator
  from dowhy.causal_estimators.regression_estimator import RegressionEstimator
  from dowhy.causal_identifier.identified_estimand import IdentifiedEstimand
  from dowhy.causal_refuter import CausalRefutation, CausalRefuter, choose_variables
  from dowhy.causal_refuters.evalue_sensitivity_analyzer import EValueSensitivityAnalyzer
  from dowhy.causal_refuters.linear_sensitivity_analyzer import LinearSensitivityAnalyzer
label_desc: Use image node_id 10 for calling a global function with example usage: sensitivity_simulation(data, target_estimand, estimate, treatment_name, outcome_name, kappa_t, kappa_y, confounders_effect_on_treatment, confounders_effect_on_outcome, frac_strength_treatment, frac_strength_outcome, plotmethod, show_progress_bar) and returns: refute, refute, refute, refute, refute, refute, refute