class_docstr: Class for creating and modifying the causal graph.
  
  Accepts a networkx DiGraph, a :py:class:`ProbabilisticCausalModel <dowhy.gcm.ProbabilisticCausalModel`, a graph string (or a text file) in gml format (preferred) or dot format. Graphviz-like attributes can be set for edges and nodes. E.g. style="dashed" as an edge attribute ensures that the edge is drawn with a dashed line.
  
   If a graph string is not given, names of treatment, outcome, and confounders, instruments and effect modifiers (if any) can be provided to create the graph.
class_docstr_tok: ["Class","for","creating","and","modifying","the","causal","graph",".","Accepts","a","networkx","DiGraph",",","a",":","py",":","class",":","`","ProbabilisticCausalModel","<","dowhy.gcm.ProbabilisticCausalModel","`",",","a","graph","string","(","or","a","text","file",")","in","gml","format","(","preferred",")","or","dot","format",".","Graphviz-like","attributes","can","be","set","for","edges","and","nodes",".","E.g",".","style=","''","dashed","''","as","an","edge","attribute","ensures","that","the","edge","is","drawn","with","a","dashed","line",".","If","a","graph","string","is","not","given",",","names","of","treatment",",","outcome",",","and","confounders",",","instruments","and","effect","modifiers","(","if","any",")","can","be","provided","to","create","the","graph","."]
docstr: Assume that nodes1 causes nodes2 (e.g., nodes1 are the treatments and nodes2 are the outcomes)
docstr_tok: ["Assume","that","nodes1","causes","nodes2","(","e.g.",",","nodes1","are","the","treatments","and","nodes2","are","the","outcomes",")"]
code: def get_common_causes(self, nodes1, nodes2):
      """
      Assume that nodes1 causes nodes2 (e.g., nodes1 are the treatments and nodes2 are the outcomes)
      """
      # TODO Refactor to remove this from here and only implement this logic in causalIdentifier. Unnecessary assumption of nodes1 to be causing nodes2.
      nodes1 = parse_state(nodes1)
      nodes2 = parse_state(nodes2)
      causes_1 = set()
      causes_2 = set()
      for node in nodes1:
          causes_1 = causes_1.union(self.get_ancestors(node))
      for node in nodes2:
          # Cannot simply compute ancestors, since that will also include nodes1 and its parents (e.g. instruments)
          parents_2 = self.get_parents(node)
          for parent in parents_2:
              if parent not in nodes1:
                  causes_2 = causes_2.union(
                      set(
                          [
                              parent,
                          ]
                      )
                  )
                  causes_2 = causes_2.union(self.get_ancestors(parent))
      return list(causes_1.intersection(causes_2))
  
imports: import itertools
  import logging
  import re
  import networkx
  from dowhy.gcm.causal_models import ProbabilisticCausalModel
  from dowhy.utils.api import parse_state
  from dowhy.utils.graph_operations import daggity_to_dot
  from dowhy.utils.plotting import plot
label_desc: Use image node_id 14 for calling the CausalGraph obj's underlying member method code with example usage: obj.get_common_causes(nodes1, nodes2) and returns: list