Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Public Member Functions | Public Attributes | List of all members
MenuAlignmentTools.MenuAlignment Class Reference
Collaboration diagram for MenuAlignmentTools.MenuAlignment:

Public Member Functions

def __init__ (self, combinations_in_menu, groups_to_align, length_of_configs)
 
def analyse_combinations (self)
 
def alignment_group_is_alone (self, alignment_grp)
 
def alignment_group_is_first (self, alignment_grp)
 
def get_groups_to_align (self, alignment_grp)
 
def single_align (self, chainDict, chainConfig)
 
def multi_align (self, chainDict, chainConfig, lengthOfChainConfigs)
 

Public Attributes

 combinations_in_menu
 
 length_of_configs
 
 groups_to_align
 
 signature_dict
 
 inverse_sig_dict
 
 sets_to_align
 

Detailed Description

Class to hold/calculate chain alignment 

Definition at line 61 of file MenuAlignmentTools.py.

Constructor & Destructor Documentation

◆ __init__()

def MenuAlignmentTools.MenuAlignment.__init__ (   self,
  combinations_in_menu,
  groups_to_align,
  length_of_configs 
)

Definition at line 63 of file MenuAlignmentTools.py.

63  def __init__(self, combinations_in_menu, groups_to_align, length_of_configs):
64 
65  self.combinations_in_menu = combinations_in_menu
66  self.length_of_configs = length_of_configs
67  self.groups_to_align = groups_to_align
68 
69  self.signature_dict = {}
70  self.inverse_sig_dict ={}
71 
72  self.sets_to_align = {}
73 
74  # first we make a dictionary of the ordering, based on the_signature_grouping
75  # e.g. 1 electron+photon, 2 muon, 3 tau, 4 jet/met/b-jet, 5 noL1 muons
76  igrp = 0
77  for value in the_signature_grouping.values():
78  if value not in self.signature_dict:
79  self.signature_dict[value] = igrp
80  igrp += 1
81 
82  self.inverse_sig_dict = {v: k for k, v in self.signature_dict.items()}
83 

Member Function Documentation

◆ alignment_group_is_alone()

def MenuAlignmentTools.MenuAlignment.alignment_group_is_alone (   self,
  alignment_grp 
)

Definition at line 164 of file MenuAlignmentTools.py.

164  def alignment_group_is_alone(self, alignment_grp):
165  # no need to align lonely alignment groups
166  # the latter condition should never happen, because we only put in alignment groups that are
167  # in combined chains, and thus will need *some* aligning. but good to check in any case.
168  if alignment_grp not in self.sets_to_align:
169  return True
170  elif len(self.sets_to_align[alignment_grp]) == 1:
171  return True
172  return False
173 

◆ alignment_group_is_first()

def MenuAlignmentTools.MenuAlignment.alignment_group_is_first (   self,
  alignment_grp 
)

Definition at line 174 of file MenuAlignmentTools.py.

174  def alignment_group_is_first(self, alignment_grp):
175 
176  # if it's the first chain in the set to be aligned, again - nothing to do here.
177  if alignment_grp == self.sets_to_align[alignment_grp][0]:
178  return True
179  return False
180 

◆ analyse_combinations()

def MenuAlignmentTools.MenuAlignment.analyse_combinations (   self)

Definition at line 105 of file MenuAlignmentTools.py.

105  def analyse_combinations(self): #combinations_in_menu, alignmentGroups_in_combinations):
106 
107  # need to find out of if an alignment group, or anything in combination with that
108  # aligment group, is in combination with any other alignment group.
109 
110  the_matrix = np.eye((len(self.signature_dict)))
111 
112  for comb in self.combinations_in_menu:
113  for comb_pair in list(itertools.combinations(comb,2)):
114  the_matrix[self.signature_dict[comb_pair[0]]][self.signature_dict[comb_pair[1]]] = 1
115  the_matrix[self.signature_dict[comb_pair[1]]][self.signature_dict[comb_pair[0]]] = 1
116 
117  _,eigenvecs = np.linalg.eig(the_matrix)
118  # eigenvecs: The normalized (unit length) eigenvectors, such that the column v[:,i]
119  # is the eigenvector corresponding to the eigenvalue w[i].
120  # so we do the transpose!
121  eigenvecs = np.transpose(eigenvecs)
122 
123  # find the indices filled by each eigenvector, and make a unique list of these
124  pre_unique_sets = list(set([tuple(np.nonzero(eigenvec)[0]) for eigenvec in eigenvecs]))
125 
126  # remove any that are subsets of another (e.g. because something like (1,1,1), (1,-1,1),(0,1,1)
127  # could be an answer but (0,1,1) clearly is not spanning a unique subspace from (1,1,1))
128  unique_sets = []
129  for aset in pre_unique_sets:
130  if len(unique_sets) == 0 :
131  unique_sets +=[aset]
132  else:
133  inlist = True
134  for ibset,bset in enumerate(unique_sets):
135  if aset == bset:
136  inlist = True
137  break
138  elif set(aset).issubset(set(bset)):
139  inlist = True
140  break
141  elif set(bset).issubset(set(aset)):
142  unique_sets.pop(ibset)
143  unique_sets += [aset]
144  inlist = True
145  break
146  else:
147  inlist = False
148  if not inlist:
149  unique_sets +=[aset]
150 
151  # convert the indices back to actual signature names
152  unique_by_sig = [[ self.inverse_sig_dict[sig_int] for sig_int in setlist ] for setlist in unique_sets]
153 
154  sig_to_set = {}
155  for sig in self.groups_to_align:
156  for aset in unique_by_sig:
157  if sig in aset:
158  sig_to_set[sig] = aset
159 
160  self.sets_to_align = sig_to_set
161 
162  return
163 

◆ get_groups_to_align()

def MenuAlignmentTools.MenuAlignment.get_groups_to_align (   self,
  alignment_grp 
)

Definition at line 181 of file MenuAlignmentTools.py.

181  def get_groups_to_align(self, alignment_grp):
182 
183  all_groups_to_align = self.sets_to_align[alignment_grp]
184  index_of_chain_group = self.sets_to_align[alignment_grp].index(alignment_grp)
185 
186  # we don't need to add empty steps for alignment groups that happen *after* the
187  # one our chain belongs to - so just cut off at the chain's alignment group here.
188  return all_groups_to_align[:index_of_chain_group]
189 
190 

◆ multi_align()

def MenuAlignmentTools.MenuAlignment.multi_align (   self,
  chainDict,
  chainConfig,
  lengthOfChainConfigs 
)

Definition at line 221 of file MenuAlignmentTools.py.

221  def multi_align(self, chainDict, chainConfig, lengthOfChainConfigs):
222 
223  lengthOfChainConfigs = remove_duplicates(lengthOfChainConfigs)
224 
225  alignment_grps = chainDict['alignmentGroups']
226 
227  #check for a few bad conditions first:
228  if not set(alignment_grps).issubset(self.sets_to_align):
229  log.error(" one of the alignmentGroups in %s is not available in the sets to align dictionary!", alignment_grps)
230  raise Exception("MenuAlignment.analyse_combinations() needs checking, this should never happen.")
231  elif len(set([tuple(self.sets_to_align[x]) for x in alignment_grps])) != 1:
232  log.error(" the alignmentGroups %s point to different sets in the sets to align dictionary", alignment_grps)
233  for x in alignment_grps:
234  log.error(" Set: %s, group %s", self.sets_to_align[x] , x)
235  raise Exception("MenuAlignment.analyse_combinations() needs checking, this should never happen.")
236 
237  #now we know that all alignmentGroups points to the same set, so just use the first entry
238  if len(self.sets_to_align[alignment_grps[0]]) == 2:
239 
240  # if the pair is on its own, then we just make sure the first signature's number
241  # of steps is equal to the max in that signature (so the next signature starts at the right step)
242 
243  # not a dictionary because we could have a chain mu_jet_munoL1? Not sure. But don't want to
244  # overwrite duplicates yet.
245  # probably, at some point, will need to divide this beyond signature but instead as unique sequence within a signature.
246  # munoL1 is already one case...
247  length_firstgrp = 0
248  max_length_firstgrp = self.length_of_configs[self.sets_to_align[alignment_grps[0]][0]]
249 
250  for config_length,config_grp in lengthOfChainConfigs:
251  if config_grp == self.sets_to_align[alignment_grps[0]][0]:
252  length_firstgrp = config_length
253 
254  if length_firstgrp < max_length_firstgrp:
255  #too short! need to add padding steps between two alignment groups...
256  needed_steps = max_length_firstgrp - length_firstgrp
257  chainConfig.insertEmptySteps('Empty'+self.sets_to_align[alignment_grps[0]][0]+'Align',needed_steps,length_firstgrp)
258 
259  elif length_firstgrp > max_length_firstgrp:
260  log.error("%s first signature length %d is greater than the max calculated, %d",chainDict.name,length_firstgrp, max_length_firstgrp)
261  raise Exception("Probably something went wrong in GenerateMenuMT.generateChains()!")
262 
263  #this should probably work for signatures > 2, but might be a few gotchas (and errors need updating)
264  #Can't properly test until ATR-22206 is resolved.
265  elif len(self.sets_to_align[alignment_grps[0]]) > 2:
266  if not set(alignment_grps).issubset(self.sets_to_align):
267  log.error(" one of the alignmentGroups in %s is not available in the sets to align dictionary!", alignment_grps)
268  raise Exception("MenuAlignment.analyse_combinations() needs checking, this should never happen.")
269  elif len(set([tuple(self.sets_to_align[x]) for x in alignment_grps])) != 1:
270  log.error(" the alignmentGroups %s point to different sets in the sets to align dictionary", alignment_grps)
271  for x in alignment_grps:
272  log.error(" Set: %s, group %s", self.sets_to_align[x] , x)
273  raise Exception("MenuAlignment.analyse_combinations() needs checking, this should never happen.")
274 
275  # first, we need to convert alignment_grps from the order it is based on the chain naming
276  # convention into the order it needs to be for the alignment
277  # these are not always the same thing!
278 
279  # takes the values of the ordering dictionary and creates a list of unique values
280  # so it isn't just e.g. [egamma, egamma, egamma, JetMET, JetMET] but actually
281  # [egamma, JetMET]
282  alignment_grp_ordering = get_alignment_group_ordering()
283  alignment_grps_ordered = [x for x in alignment_grp_ordering if x in alignment_grps]
284 
285  # we need to know which alignment_grps are in the chain in which order. Assume this is always stored correctly.
286  # (this should be true, once it is sorted! If not, there is a bug.)
287  # never need to add empty steps to the last leg - it can end at a different
288  # time (be a different number of steps) - no problem.
289  # ignore any signatures after the end of those in this chain
290  aligngroups_set = self.get_groups_to_align(alignment_grps_ordered[-1])
291  aligngroups_set.reverse()
292  grp_masks = [x in alignment_grps_ordered for x in aligngroups_set]
293  grp_lengths = []
294  for align_grp,grp_in_chain in zip(aligngroups_set,grp_masks):
295  if grp_in_chain:
296  for config_length,config_grp in lengthOfChainConfigs:
297  if config_grp == align_grp:
298  grp_lengths += [config_length]
299  else:
300  grp_lengths += [0]
301 
302  for istep,(align_grp,grp_in_chain,length_in_chain) in enumerate(zip(aligngroups_set,grp_masks,grp_lengths)):
303  # We're working our way backwards through the chain
304  # need to know how many steps are already before us!
305  n_steps_before_grp = 0
306  if istep < len(grp_lengths)-1:
307  n_steps_before_grp = sum(grp_lengths[istep+1:])
308  max_length_grp = self.length_of_configs[align_grp]
309  if grp_in_chain:
310  if length_in_chain < max_length_grp:
311  #too short! gotta add padding steps between two alignmentGroups...
312  needed_steps = max_length_grp - length_in_chain
313  start_step = n_steps_before_grp + length_in_chain
314  chainConfig.insertEmptySteps('Empty'+align_grp+'Align',needed_steps,start_step)
315  else:
316  # this sig isn't in the chain, but we still will need empty steps for it
317  # always add them to the start, because we're running in reverse order
318  chainConfig.insertEmptySteps('Empty'+align_grp+'Align',self.length_of_configs[align_grp],n_steps_before_grp)
319  else:
320  log.error("Should never reach this point. Ordered alignmentGroups: %s, sets_to_align: %s",alignment_grps_ordered,self.sets_to_align)
321  raise Exception("MenuAlignment.multi_align() needs checking, this should never happen.")
322 
323  log.debug("Finished with retrieving chain configuration for chain %s", chainDict['chainName'])
324  chainConfig.numberAllSteps()
325 
326  return chainConfig

◆ single_align()

def MenuAlignmentTools.MenuAlignment.single_align (   self,
  chainDict,
  chainConfig 
)

Definition at line 191 of file MenuAlignmentTools.py.

191  def single_align(self, chainDict, chainConfig):
192 
193  if len(set(chainDict['alignmentGroups'])) != 1:
194  log.error("Cannot call single_align on chain %s with alignment groups %s",
195  chainDict['chainName'], ",".join(chainDict['alignmentGroups']))
196  raise Exception("Will not proceed, the chain is not suitable for single alignment.")
197 
198  alignment_grp = chainDict['alignmentGroups'][0]
199 
200  if self.alignment_group_is_alone(alignment_grp):
201  log.debug("Finished with retrieving chain configuration for chain %s", chainDict['chainName'])
202  chainConfig.numberAllSteps()
203  elif self.alignment_group_is_first(alignment_grp):
204  # if it's the first chain in the set to be aligned, again - nothing to do here,
205  # since this is single_align
206  log.debug("Finished with retrieving chain configuration for chain %s", chainDict['chainName'])
207  chainConfig.numberAllSteps()
208  else:
209  # now we know that empty steps are necessary before this chain. we can loop through and add accordingly
210  aligngroups_set = self.get_groups_to_align(alignment_grp)
211  # but we want to do this in reverse
212  aligngroups_set.reverse()
213 
214  for align_grp_to_align in aligngroups_set:
215  chainConfig.insertEmptySteps('Empty'+align_grp_to_align+'Align',self.length_of_configs[align_grp_to_align],0)
216  log.debug("Finished with retrieving chain configuration for chain %s", chainDict['chainName'])
217  chainConfig.numberAllSteps()
218 
219  return chainConfig
220 

Member Data Documentation

◆ combinations_in_menu

MenuAlignmentTools.MenuAlignment.combinations_in_menu

Definition at line 65 of file MenuAlignmentTools.py.

◆ groups_to_align

MenuAlignmentTools.MenuAlignment.groups_to_align

Definition at line 67 of file MenuAlignmentTools.py.

◆ inverse_sig_dict

MenuAlignmentTools.MenuAlignment.inverse_sig_dict

Definition at line 70 of file MenuAlignmentTools.py.

◆ length_of_configs

MenuAlignmentTools.MenuAlignment.length_of_configs

Definition at line 66 of file MenuAlignmentTools.py.

◆ sets_to_align

MenuAlignmentTools.MenuAlignment.sets_to_align

Definition at line 72 of file MenuAlignmentTools.py.

◆ signature_dict

MenuAlignmentTools.MenuAlignment.signature_dict

Definition at line 69 of file MenuAlignmentTools.py.


The documentation for this class was generated from the following file:
index
Definition: index.py:1
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
MenuAlignmentTools.remove_duplicates
def remove_duplicates(config_tuples)
Definition: MenuAlignmentTools.py:38
MenuAlignmentTools.get_alignment_group_ordering
def get_alignment_group_ordering()
Definition: MenuAlignmentTools.py:20
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:71
python.processes.powheg.ZZ.ZZ.__init__
def __init__(self, base_directory, **kwargs)
Constructor: all process options are set here.
Definition: ZZ.py:18