33from abc import ABC , abstractmethod
44from dataclasses import dataclass
55from typing import Callable
6+ import logging
67
78import pandas as pd
89
910from causal_testing .estimation .cubic_spline_estimator import CubicSplineRegressionEstimator
10- from causal_testing .specification .causal_specification import CausalSpecification
11+ from causal_testing .specification .scenario import Scenario
12+ from causal_testing .specification .causal_dag import CausalDAG
1113from causal_testing .testing .base_test_case import BaseTestCase
1214
15+ logger = logging .getLogger (__name__ )
16+
1317
1418@dataclass
1519class SimulationResult :
@@ -30,13 +34,11 @@ class SearchAlgorithm(ABC): # pylint: disable=too-few-public-methods
3034 space to be searched"""
3135
3236 @abstractmethod
33- def search (
34- self , surrogate_models : list [CubicSplineRegressionEstimator ], specification : CausalSpecification
35- ) -> list :
37+ def search (self , surrogate_models : list [CubicSplineRegressionEstimator ], scenario : Scenario ) -> list :
3638 """Function which implements a search routine which searches for the optimal fitness value for the specified
3739 scenario
3840 :param surrogate_models: The surrogate models to be searched
39- :param specification : The Causal Specification (combination of Scenario and Causal Dag) """
41+ :param scenario : The modelling scenario """
4042
4143
4244class Simulator (ABC ):
@@ -64,11 +66,13 @@ class CausalSurrogateAssistedTestCase:
6466
6567 def __init__ (
6668 self ,
67- specification : CausalSpecification ,
69+ scenario : Scenario ,
70+ causal_dag : CausalDAG ,
6871 search_algorithm : SearchAlgorithm ,
6972 simulator : Simulator ,
7073 ):
71- self .specification = specification
74+ self .scenario = scenario
75+ self .causal_dag = causal_dag
7276 self .search_algorithm = search_algorithm
7377 self .simulator = simulator
7478
@@ -87,8 +91,8 @@ def execute(
8791 :return: tuple containing SimulationResult or str, execution number and dataframe"""
8892
8993 for i in range (max_executions ):
90- surrogate_models = self .generate_surrogates (self . specification , df )
91- candidate_test_case , _ , surrogate_model = self .search_algorithm .search (surrogate_models , self .specification )
94+ surrogate_models = self .generate_surrogates (df )
95+ candidate_test_case , _ , surrogate_model = self .search_algorithm .search (surrogate_models , self .scenario )
9296
9397 self .simulator .startup ()
9498 test_result = self .simulator .run_with_config (candidate_test_case )
@@ -101,7 +105,7 @@ def execute(
101105 else :
102106 df = pd .concat ([df , test_result_df ], ignore_index = True )
103107 if test_result .fault :
104- print (
108+ logger . info (
105109 f"Fault found between { surrogate_model .base_test_case .treatment_variable .name } causing "
106110 f"{ surrogate_model .base_test_case .outcome_variable .name } . Contradiction with "
107111 f"expected { surrogate_model .expected_relationship } ."
@@ -113,28 +117,25 @@ def execute(
113117 )
114118 return test_result , i + 1 , df
115119
116- print ("No fault found" )
120+ logger . info ("No fault found" )
117121 return "No fault found" , i + 1 , df
118122
119- def generate_surrogates (
120- self , specification : CausalSpecification , df : pd .DataFrame
121- ) -> list [CubicSplineRegressionEstimator ]:
122- """Generate a surrogate model for each edge of the dag that specifies it is included in the DAG metadata.
123- :param specification: The Causal Specification (combination of Scenario and Causal Dag)
123+ def generate_surrogates (self , df : pd .DataFrame ) -> list [CubicSplineRegressionEstimator ]:
124+ """Generate a surrogate model for each edge of the DAG that specifies it is included in the DAG metadata.
124125 :param df: An dataframe which contains data relevant to the specified scenario
125126 :return: A list of surrogate models
126127 """
127128 surrogate_models = []
128129
129- for u , v in specification .causal_dag .edges :
130- edge_metadata = specification .causal_dag .adj [u ][v ]
130+ for u , v in self .causal_dag .edges :
131+ edge_metadata = self .causal_dag .adj [u ][v ]
131132 if "included" in edge_metadata :
132- from_var = specification .scenario .variables .get (u )
133- to_var = specification .scenario .variables .get (v )
133+ from_var = self .scenario .variables .get (u )
134+ to_var = self .scenario .variables .get (v )
134135 base_test_case = BaseTestCase (from_var , to_var )
135136
136- minimal_adjustment_set = specification .causal_dag .identification (
137- base_test_case , specification .scenario .hidden_variables ()
137+ minimal_adjustment_set = self .causal_dag .identification (
138+ base_test_case , self .scenario .hidden_variables ()
138139 )
139140
140141 surrogate = CubicSplineRegressionEstimator (
0 commit comments