code: def estimate_effect(
      data: pd.DataFrame,
      treatment: Union[str, List[str]],
      outcome: Union[str, List[str]],
      identifier_name: str,
      estimator: CausalEstimator,
      control_value: int = 0,
      treatment_value: int = 1,
      target_units: str = "ate",
      effect_modifiers: List[str] = None,
      fit_estimator: bool = True,
      method_params: Optional[Dict] = None,
  ):
      """Estimate the identified causal effect.
  
      In addition, you can directly call any of the EconML estimation methods. The convention is "backdoor.econml.path-to-estimator-class". For example, for the double machine learning estimator ("DML" class) that is located inside "dml" module of EconML, you can use the method name, "backdoor.econml.dml.DML". CausalML estimators can also be called. See `this demo notebook <https://py-why.github.io/dowhy/example_notebooks/dowhy-conditional-treatment-effects.html>`_.
  
      :param treatment: Name of the treatment
      :param outcome: Name of the outcome
      :param identified_estimand: a probability expression
          that represents the effect to be estimated. Output of
          CausalModel.identify_effect method
      :param estimator: Instance of a CausalEstimator to use
      :param control_value: Value of the treatment in the control group, for effect estimation.  If treatment is multi-variate, this can be a list.
      :param treatment_value: Value of the treatment in the treated group, for effect estimation. If treatment is multi-variate, this can be a list.
      :param target_units: (Experimental) The units for which the treatment effect should be estimated. This can be of three types. (1) a string for common specifications of target units (namely, "ate", "att" and "atc"), (2) a lambda function that can be used as an index for the data (pandas DataFrame), or (3) a new DataFrame that contains values of the effect_modifiers and effect will be estimated only for this new data.
      :param effect_modifiers: Names of effect modifier variables can be (optionally) specified here too, since they do not affect identification. If None, the effect_modifiers from the CausalModel are used.
      :param fit_estimator: Boolean flag on whether to fit the estimator.
          Setting it to False is useful to estimate the effect on new data using a previously fitted estimator.
      :returns: An instance of the CausalEstimate class, containing the causal effect estimate
          and other method-dependent information
      """
  
      if effect_modifiers is None:
          effect_modifiers = []
  
      treatment = parse_state(treatment)
      outcome = parse_state(outcome)
      causal_estimator_class = estimator.__class__
  
      identified_estimand = estimator._target_estimand
      identified_estimand.set_identifier_method(identifier_name)
  
      if identified_estimand.no_directed_path:
          logger.warning(
              "No directed path from {0} to {1}.".format(
                  treatment, outcome
              )
          )
          return CausalEstimate(
              None,
              None,
              None,
              0,
              identified_estimand,
              None,
              control_value=control_value,
              treatment_value=treatment_value,
          )
      # Check if estimator's target estimand is identified
      elif identified_estimand.estimands[identifier_name] is None:
          logger.error("No valid identified estimand available.")
          return CausalEstimate(
              None,
              None,
              None,
              None,
              None,
              None,
              control_value=control_value,
              treatment_value=treatment_value,
          )
  
      if fit_estimator:
          estimator.fit(
              data=data,
              effect_modifier_names=effect_modifiers,
              **method_params["fit_params"]
              if "fit_params" in method_params
              else {},
          )
  
      estimate = estimator.estimate_effect(
          data,
          treatment_value=treatment_value,
          control_value=control_value,
          target_units=target_units,
          confidence_intervals=estimator._confidence_intervals,
      )
  
      if estimator._significance_test:
          estimator.test_significance(
              data, estimate.value, method=estimator._significance_test
          )
      if estimator._confidence_intervals:
          estimator.estimate_confidence_intervals(
              data,
              estimate.value,
              confidence_level=estimator.confidence_level,
              method=estimator._confidence_intervals,
          )
      if estimator._effect_strength_eval:
          effect_strength_dict = estimator.evaluate_effect_strength(
              data, estimate
          )
          estimate.add_effect_strength(effect_strength_dict)
  
      # Store parameters inside estimate object for refutation methods
      # TODO: This add_params needs to move to the estimator class
      # inside estimate_effect and estimate_conditional_effect
      estimate.add_params(
          estimand_type=identified_estimand.estimand_type,
          estimator_class=causal_estimator_class,
          test_significance=estimator._significance_test,
          evaluate_effect_strength=estimator._effect_strength_eval,
          confidence_intervals=estimator._confidence_intervals,
          target_units=target_units,
          effect_modifiers=effect_modifiers,
      )
  
      return estimate
  
imports: import copy
  import logging
  from collections import namedtuple
  from typing import Dict, List, Optional, Union
  import numpy
  import pandas
  import sympy
  from sklearn.utils import resample
  import dowhy.interpreters
  from dowhy.causal_identifier.identified_estimand import IdentifiedEstimand
  from dowhy.utils.api import parse_state
label_desc: Use image node_id 1 for calling a global function with example usage: estimate_effect(data, treatment, outcome, identifier_name, estimator, control_value, treatment_value, target_units, effect_modifiers, fit_estimator, method_params) and returns: estimate, CausalEstimate, CausalEstimate