ATLAS Offline Software
Functions
chainComp Namespace Reference

Functions

def get_parser ()
 
def find_reference (inputFile)
 
def find_repository (ref_path)
 
def load_yaml (path)
 
def print_event_diff (inp_data, ref_data, key)
 
def print_step_diff (inp_data, ref_data, key)
 
def print_diff (inp_dict, ref_dict, matching_only=False)
 
def create_patch (inp_path, ref_path)
 
def main ()
 

Function Documentation

◆ create_patch()

def chainComp.create_patch (   inp_path,
  ref_path 
)

Definition at line 168 of file chainComp.py.

168 def create_patch(inp_path, ref_path):
169  def find_ref_package():
170  for path in [ref_path, find_reference(inp_path), find_reference(ref_path)]:
171  for pkg in packages:
172  if '/data/'+pkg in ref_path:
173  return pkg, os.path.split(path)[1]
174  return None, None
175  package_name, ref_file_name = find_ref_package()
176  if not package_name:
177  logging.warning('Failed to find reference package name, cannot create git patch file')
178  return
179 
180  ref_rel_path = '/Trigger/TrigValidation/' + package_name + '/share/' + ref_file_name
181 
182  diff_cmd = 'diff -U 1 -b'
183  diff_cmd += ' --label a' + ref_rel_path + ' ' + ref_path
184  diff_cmd += ' --label b' + ref_rel_path + ' ' + inp_path
185 
186  diff_txt = subprocess.getoutput(diff_cmd)
187  patch_name = os.path.split(ref_path)[1]
188  if patch_name.endswith('.ref') or patch_name.endswith('.new'):
189  patch_name = patch_name[0:-4]
190  patch_name += '.patch'
191  with open(patch_name, 'w') as patch_file:
192  patch_file.write('diff --git a{p:s} b{p:s}\n'.format(p=ref_rel_path))
193  patch_file.write(diff_txt + '\n')
194  logging.info('Patch file created. To apply, run in the athena source directory:')
195  logging.info('git apply %s/%s', os.getcwd(), patch_name)
196  logging.info('Then check with git diff and, if everything is correct, add and commit')
197  if running_in_CI():
198  logging.info('or see the patch below:\n')
199  subprocess.call('cat ' + patch_name, shell=True)
200  print('\n') # noqa: ATL901
201 
202 

◆ find_reference()

def chainComp.find_reference (   inputFile)

Definition at line 50 of file chainComp.py.

50 def find_reference(inputFile):
51  ref_path = None
52  if inputFile.endswith('.new'):
53  inp_name = os.path.split(inputFile)[-1]
54  ref_name = inp_name[0:-4] + '.ref'
55  logging.debug('Searching for file %s in DATAPATH', ref_name)
56  for pkg_name in packages:
57  ref_path = unixtools.find_datafile(pkg_name+'/'+ref_name)
58  if ref_path:
59  break
60  if ref_path:
61  logging.debug('Found %s', ref_path)
62  else:
63  logging.debug('Not found')
64  return ref_path
65 
66 

◆ find_repository()

def chainComp.find_repository (   ref_path)
Try to find the athena git repository based on paths in env.
Needs to work both in local WorkDir build and in full/incremental CI build.

Definition at line 67 of file chainComp.py.

67 def find_repository(ref_path):
68  '''
69  Try to find the athena git repository based on paths in env.
70  Needs to work both in local WorkDir build and in full/incremental CI build.
71  '''
72  logging.debug('Searching for the source repository path')
73  search_str = '/Trigger/TrigValidation'
74  def try_path(p):
75  logging.debug('Trying %s', p)
76  if os.path.islink(p) and os.path.isfile(p) and search_str in os.path.realpath(p):
77  candidate = os.path.realpath(p).split(search_str)[0]
78  logging.debug('Candidate %s', candidate)
79  if os.path.isdir(candidate + '/.git'):
80  return candidate
81  return None
82 
83  result = try_path(ref_path)
84  if result:
85  return result
86 
87  env_vars = ['DATAPATH', 'JOBOPTSEARCHPATH', 'CALIBPATH', 'XMLPATH']
88  path_lists = [os.getenv(var).split(os.pathsep) for var in env_vars]
89  max_len = max([len(pl) for pl in path_lists])
90  max_len = min(max_len, 2) # Limit to first two paths to avoid very deep and slow search
91  for i in range(max_len):
92  for pl in path_lists:
93  if i >= len(pl):
94  continue
95  paths = glob.glob(pl[i]+'/**', recursive=True)
96  for p in paths:
97  result = try_path(p)
98  if result:
99  return result
100  return None
101 
102 

◆ get_parser()

def chainComp.get_parser ( )

Definition at line 24 of file chainComp.py.

24 def get_parser():
25  parser = argparse.ArgumentParser(usage='%(prog)s [options] inputFile',
26  description=__doc__)
27  parser.add_argument('inputFile',
28  metavar='PATH',
29  help='Name of input counts file')
30  parser.add_argument('-r', '--referenceFile',
31  metavar='PATH',
32  help='Name of reference counts file. If empty, try to guess from inputFile')
33  parser.add_argument('-s', '--sourceRepository',
34  metavar='PATH',
35  help='Path to the git checkout of the athena repository.'
36  'If empty, try to guess from the environment')
37  parser.add_argument('-p', '--patch',
38  action='store_true',
39  help='Create a git patch file with the count differences')
40  parser.add_argument('-m', '--matchingOnly',
41  action='store_true',
42  help='Ignore added and removed chains, and only compare counts for chains ' + \
43  'present in both reference and input file')
44  parser.add_argument('-v', '--verbose',
45  action='store_true',
46  help='Increase output verbosity')
47  return parser
48 
49 

◆ load_yaml()

def chainComp.load_yaml (   path)

Definition at line 103 of file chainComp.py.

103 def load_yaml(path):
104  result = None
105  if not os.path.isfile(path):
106  logging.error('Not a file: %s', path)
107  return result
108  with open(path) as f:
109  result = yaml.safe_load(f)
110  return result
111 
112 

◆ main()

def chainComp.main ( )

Definition at line 203 of file chainComp.py.

203 def main():
204  args = get_parser().parse_args()
205  logging.basicConfig(stream=sys.stdout,
206  format='chainComp %(levelname)-8s %(message)s',
207  level=logging.DEBUG if args.verbose else logging.INFO)
208 
209  inp_path = args.inputFile
210  ref_path = args.referenceFile or find_reference(inp_path)
211  if not ref_path:
212  logging.error('No reference file specified and couldn\'t guess from '
213  'input name. Please use the -r argument (see --help).')
214  return 1
215 
216  logging.info('Test file: %s', inp_path)
217  logging.info('Reference file: %s', ref_path)
218 
219  # Currently not used, but ready for implementing checks against upstream
220  # src_path = args.sourceRepository or find_repository(ref_path)
221  # logging.info('Repository path: %s', src_path)
222 
223  inp_dict = load_yaml(inp_path)
224  ref_dict = load_yaml(ref_path)
225  if (not inp_dict) or (not ref_dict):
226  return 1
227 
228  retcode = print_diff(inp_dict, ref_dict, args.matchingOnly)
229  if retcode:
230  logging.error('Trigger counts differ from the reference. If the above differences are intended, update the reference')
231  if args.patch:
232  create_patch(inp_path, ref_path)
233  else:
234  logging.info('Trigger counts match the reference')
235 
236  return retcode
237 
238 

◆ print_diff()

def chainComp.print_diff (   inp_dict,
  ref_dict,
  matching_only = False 
)

Definition at line 130 of file chainComp.py.

130 def print_diff(inp_dict, ref_dict, matching_only=False):
131  retcode = 0
132  chains_not_in_ref = [c[0] for c in inp_dict.items() if c[0] not in ref_dict]
133  chains_not_in_inp = [c[0] for c in ref_dict.items() if c[0] not in inp_dict]
134  chains_count_diff = [c[0] for c in inp_dict.items() if c[0] in ref_dict and c[1] != ref_dict[c[0]]]
135 
136  # New chains (missing in reference)
137  n_new_chains = len(chains_not_in_ref)
138  if n_new_chains > 0 and not matching_only:
139  retcode = 1
140  logging.info('Found %d new chain%s added:', n_new_chains, 's' if n_new_chains > 1 else '')
141  for chain_name in chains_not_in_ref:
142  logging.info(' %s', chain_name)
143 
144  # Removed chains (missing in test file)
145  n_removed_chains = len(chains_not_in_inp)
146  if n_removed_chains > 0 and not matching_only:
147  retcode = 1
148  logging.info('Found %d chain%s removed:', n_removed_chains, 's' if n_removed_chains > 1 else '')
149  for chain_name in chains_not_in_inp:
150  logging.info(' %s', chain_name)
151 
152  # Count differences
153  n_diff_chains = len(chains_count_diff)
154  if n_diff_chains > 0:
155  retcode = 1
156  logging.info('Found %d chain%s with count differences:', n_diff_chains, 's' if n_diff_chains > 1 else '')
157  for chain_name in chains_count_diff:
158  logging.info(' %s:', chain_name)
159  inp_data = inp_dict[chain_name]
160  ref_data = ref_dict[chain_name]
161  print_event_diff(inp_data, ref_data, 'eventCount')
162  print_step_diff(inp_data, ref_data, 'stepCounts')
163  print_step_diff(inp_data, ref_data, 'stepFeatures')
164 
165  return retcode
166 
167 

◆ print_event_diff()

def chainComp.print_event_diff (   inp_data,
  ref_data,
  key 
)

Definition at line 113 of file chainComp.py.

113 def print_event_diff(inp_data, ref_data, key):
114  if inp_data[key] != ref_data[key]:
115  logging.info(' %s: %d -> %d', key, ref_data[key], inp_data[key])
116 
117 

◆ print_step_diff()

def chainComp.print_step_diff (   inp_data,
  ref_data,
  key 
)

Definition at line 118 of file chainComp.py.

118 def print_step_diff(inp_data, ref_data, key):
119  inp_steps = inp_data.get(key, dict())
120  ref_steps = ref_data.get(key, dict())
121  if inp_steps != ref_steps:
122  logging.info(' %s:', key)
123  for step in range(max(len(inp_steps), len(ref_steps))):
124  inp_count = inp_steps.get(step, 0)
125  ref_count = ref_steps.get(step, 0)
126  if inp_count != ref_count:
127  logging.info(' %d: %d -> %d', step, ref_count, inp_count)
128 
129 
max
#define max(a, b)
Definition: cfImp.cxx:41
vtune_athena.format
format
Definition: vtune_athena.py:14
chainComp.print_diff
def print_diff(inp_dict, ref_dict, matching_only=False)
Definition: chainComp.py:130
chainComp.create_patch
def create_patch(inp_path, ref_path)
Definition: chainComp.py:168
chainComp.find_reference
def find_reference(inputFile)
Definition: chainComp.py:50
chainComp.print_event_diff
def print_event_diff(inp_data, ref_data, key)
Definition: chainComp.py:113
python.TrigValSteering.Common.running_in_CI
def running_in_CI()
Definition: Common.py:78
chainComp.main
def main()
Definition: chainComp.py:203
chainComp.get_parser
def get_parser()
Definition: chainComp.py:24
chainComp.find_repository
def find_repository(ref_path)
Definition: chainComp.py:67
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
min
#define min(a, b)
Definition: cfImp.cxx:40
chainComp.print_step_diff
def print_step_diff(inp_data, ref_data, key)
Definition: chainComp.py:118
Trk::open
@ open
Definition: BinningType.h:40
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
confTool.parse_args
def parse_args()
Definition: confTool.py:35
chainComp.load_yaml
def load_yaml(path)
Definition: chainComp.py:103
Trk::split
@ split
Definition: LayerMaterialProperties.h:38