-
Notifications
You must be signed in to change notification settings - Fork 6
/
cpac_pipe_diff.py
104 lines (77 loc) · 2.64 KB
/
cpac_pipe_diff.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import yaml
import math
def read_yaml_file(yaml_file):
'''Function to read a dict YAML file at a given path.
Parameters
----------
yaml_file: str
path to YAML file
Returns
-------
dict
parsed YAML
Example
-------
>>> read_yaml_file('/code/dev/docker_data/default_pipeline.yml')[
... 'pipeline_setup']['pipeline_name']
'cpac-default-pipeline'
'''
return yaml.safe_load(open(yaml_file, 'r'))
def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
def dct_diff(dct1, dct2):
'''Function to compare 2 nested dicts, dropping values unspecified
in the second.
Parameters
----------
dct1: dict
dct2: dict
Returns
-------
diff: set
a tuple of values from dct1, dct2 for each differing key
Example
-------
>>> pipeline = read_yaml_file('/code/dev/docker_data/default_pipeline.yml')
>>> dct_diff(pipeline, pipeline)
{}
>>> pipeline2 = read_yaml_file('/code/CPAC/resources/configs/'
... 'pipeline_config_fmriprep-options.yml')
>>> dct_diff(pipeline, pipeline2)['pipeline_setup']['pipeline_name']
('cpac-default-pipeline', 'cpac_fmriprep-options')
'''
diff = {}
for key in dct1:
if isinstance(dct1[key], dict):
diff[key] = dct_diff(dct1[key], dct2.get(key, {}))
else:
dct1_val = dct1.get(key)
dct2_val = dct2.get(key) if isinstance(dct2, dict) else None
# skip unspecified values
if dct2_val is None:
continue
if isinstance(dct1_val, float) and isinstance(dct2_val, float):
if isclose(dct1_val, dct2_val):
continue
else:
diff[key] = (dct1_val, dct2_val)
if dct1_val != dct2_val:
diff[key] = (dct1_val, dct2_val)
# only return non-empty diffs
return {k: diff[k] for k in diff if diff[k]}
def main():
import os
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("pipe1", type=str, \
help="path to a C-PAC pipeline configuration " \
"YAML file")
parser.add_argument("pipe2", type=str, \
help="path to a C-PAC pipeline configuration " \
"YAML file")
args = parser.parse_args()
pipe_dct1 = read_yaml_file(args.pipe1)
pipe_dct2 = read_yaml_file(args.pipe2)
diff_dct = dct_diff(pipe_dct1, pipe_dct2)
for key in diff_dct:
print("{0}: {1}".format(key, diff_dct[key]))