@@ -59,7 +59,7 @@ def __init__(self):
59
59
self .config_path : str = ""
60
60
self .config : Dict [str , Any ] = {}
61
61
self .datasets : List [Dataset ] = []
62
- self .selected_metrics : Optional [ List [ str ]] = None
62
+ self .likely_dir : str = ""
63
63
64
64
def run_metrics (self , metrics : List [BaseMetric ]) -> None :
65
65
"""Run a list of metrics."""
@@ -87,30 +87,28 @@ def _parse_args(self) -> None:
87
87
type = str ,
88
88
required = False ,
89
89
default = "" ,
90
- help = "The path to your openlayer.json. Uses working dir if not provided." ,
90
+ help = (
91
+ "The path to your openlayer.json. Uses parent parent dir if not "
92
+ "provided (assuming location is metrics/metric_name/run.py)."
93
+ ),
91
94
)
92
95
93
96
# Parse the arguments
94
97
args = parser .parse_args ()
95
98
self .config_path = args .config_path
99
+ self .likely_dir = os .path .dirname (os .path .dirname (os .getcwd ()))
96
100
97
101
def _load_openlayer_json (self ) -> None :
98
102
"""Load the openlayer.json file."""
99
103
100
104
if not self .config_path :
101
- openlayer_json_path = os .path .join (os . getcwd () , "openlayer.json" )
105
+ openlayer_json_path = os .path .join (self . likely_dir , "openlayer.json" )
102
106
else :
103
107
openlayer_json_path = self .config_path
104
108
105
109
with open (openlayer_json_path , "r" , encoding = "utf-8" ) as f :
106
110
self .config = json .load (f )
107
111
108
- # Extract selected metrics
109
- if "metrics" in self .config and "settings" in self .config ["metrics" ]:
110
- self .selected_metrics = [
111
- metric ["key" ] for metric in self .config ["metrics" ]["settings" ] if metric ["selected" ]
112
- ]
113
-
114
112
def _load_datasets (self ) -> None :
115
113
"""Compute the metric from the command line."""
116
114
@@ -125,20 +123,34 @@ def _load_datasets(self) -> None:
125
123
# Read the outputs directory for dataset folders. For each, load
126
124
# the config.json and the dataset.json files into a dict and a dataframe
127
125
128
- for dataset_folder in os .listdir (output_directory ):
126
+ full_output_dir = os .path .join (self .likely_dir , output_directory )
127
+
128
+ for dataset_folder in os .listdir (full_output_dir ):
129
129
if dataset_folder not in dataset_names :
130
130
continue
131
- dataset_path = os .path .join (output_directory , dataset_folder )
131
+ dataset_path = os .path .join (full_output_dir , dataset_folder )
132
132
config_path = os .path .join (dataset_path , "config.json" )
133
133
with open (config_path , "r" , encoding = "utf-8" ) as f :
134
134
dataset_config = json .load (f )
135
+ # Merge with the dataset fields from the openlayer.json
136
+ dataset_dict = next (
137
+ (
138
+ item
139
+ for item in datasets_list
140
+ if item ["name" ] == dataset_folder
141
+ ),
142
+ None ,
143
+ )
144
+ dataset_config = {** dataset_dict , ** dataset_config }
135
145
136
146
# Load the dataset into a pandas DataFrame
137
147
if os .path .exists (os .path .join (dataset_path , "dataset.csv" )):
138
148
dataset_df = pd .read_csv (os .path .join (dataset_path , "dataset.csv" ))
139
149
data_format = "csv"
140
150
elif os .path .exists (os .path .join (dataset_path , "dataset.json" )):
141
- dataset_df = pd .read_json (os .path .join (dataset_path , "dataset.json" ), orient = "records" )
151
+ dataset_df = pd .read_json (
152
+ os .path .join (dataset_path , "dataset.json" ), orient = "records"
153
+ )
142
154
data_format = "json"
143
155
else :
144
156
raise ValueError (f"No dataset found in { dataset_folder } ." )
@@ -153,19 +165,20 @@ def _load_datasets(self) -> None:
153
165
)
154
166
)
155
167
else :
156
- raise ValueError ("No model found in the openlayer.json file. Cannot compute metric." )
168
+ raise ValueError (
169
+ "No model found in the openlayer.json file. Cannot compute metric."
170
+ )
157
171
158
172
if not datasets :
159
- raise ValueError ("No datasets found in the openlayer.json file. Cannot compute metric." )
173
+ raise ValueError (
174
+ "No datasets found in the openlayer.json file. Cannot compute metric."
175
+ )
160
176
161
177
self .datasets = datasets
162
178
163
179
def _compute_metrics (self , metrics : List [BaseMetric ]) -> None :
164
180
"""Compute the metrics."""
165
181
for metric in metrics :
166
- if self .selected_metrics and metric .key not in self .selected_metrics :
167
- print (f"Skipping metric { metric .key } as it is not a selected metric." )
168
- continue
169
182
metric .compute (self .datasets )
170
183
171
184
def _write_updated_datasets_to_output (self ) -> None :
@@ -200,10 +213,14 @@ class BaseMetric(abc.ABC):
200
213
Your metric's class should inherit from this class and implement the compute method.
201
214
"""
202
215
216
+ @abc .abstractmethod
217
+ def get_key (self ) -> str :
218
+ """Return the key of the metric. This should correspond to the folder name."""
219
+ pass
220
+
203
221
@property
204
222
def key (self ) -> str :
205
- """Return the key of the metric."""
206
- return self .__class__ .__name__
223
+ return self .get_key ()
207
224
208
225
def compute (self , datasets : List [Dataset ]) -> None :
209
226
"""Compute the metric on the model outputs."""
@@ -226,15 +243,26 @@ def compute_on_dataset(self, dataset: Dataset) -> MetricReturn:
226
243
"""Compute the metric on a specific dataset."""
227
244
pass
228
245
229
- def _write_metric_return_to_file (self , metric_return : MetricReturn , output_dir : str ) -> None :
246
+ def _write_metric_return_to_file (
247
+ self , metric_return : MetricReturn , output_dir : str
248
+ ) -> None :
230
249
"""Write the metric return to a file."""
231
250
232
251
# Create the directory if it doesn't exist
233
252
os .makedirs (output_dir , exist_ok = True )
234
253
235
254
# Turn the metric return to a dict
236
255
metric_return_dict = asdict (metric_return )
256
+ # Convert the set to a list
257
+ metric_return_dict ["added_cols" ] = list (metric_return .added_cols )
237
258
238
- with open (os .path .join (output_dir , f"{ self .key } .json" ), "w" , encoding = "utf-8" ) as f :
259
+ with open (
260
+ os .path .join (output_dir , f"{ self .key } .json" ), "w" , encoding = "utf-8"
261
+ ) as f :
239
262
json .dump (metric_return_dict , f , indent = 4 )
240
263
print (f"Metric ({ self .key } ) value written to { output_dir } /{ self .key } .json" )
264
+
265
+ def run (self ) -> None :
266
+ """Run the metric."""
267
+ metric_runner = MetricRunner ()
268
+ metric_runner .run_metrics ([self ])
0 commit comments