ATLAS Offline Software
Loading...
Searching...
No Matches
MenuAlignmentTools.MenuAlignment Class Reference
Collaboration diagram for MenuAlignmentTools.MenuAlignment:

Public Member Functions

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

Public Attributes

 combinations_in_menu = combinations_in_menu
 length_of_configs = length_of_configs
 groups_to_align = groups_to_align
dict signature_dict = {}
dict inverse_sig_dict = {}
dict sets_to_align = {}

Detailed Description

Class to hold/calculate chain alignment 

Definition at line 55 of file MenuAlignmentTools.py.

Constructor & Destructor Documentation

◆ __init__()

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

Definition at line 57 of file MenuAlignmentTools.py.

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

Member Function Documentation

◆ alignment_group_is_alone()

MenuAlignmentTools.MenuAlignment.alignment_group_is_alone ( self,
alignment_grp )

Definition at line 158 of file MenuAlignmentTools.py.

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

◆ alignment_group_is_first()

MenuAlignmentTools.MenuAlignment.alignment_group_is_first ( self,
alignment_grp )

Definition at line 168 of file MenuAlignmentTools.py.

168 def alignment_group_is_first(self, alignment_grp):
169
170 # if it's the first chain in the set to be aligned, again - nothing to do here.
171 if alignment_grp == self.sets_to_align[alignment_grp][0]:
172 return True
173 return False
174

◆ analyse_combinations()

MenuAlignmentTools.MenuAlignment.analyse_combinations ( self)

Definition at line 99 of file MenuAlignmentTools.py.

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

◆ get_groups_to_align()

MenuAlignmentTools.MenuAlignment.get_groups_to_align ( self,
alignment_grp )

Definition at line 175 of file MenuAlignmentTools.py.

175 def get_groups_to_align(self, alignment_grp):
176
177 all_groups_to_align = self.sets_to_align[alignment_grp]
178 index_of_chain_group = self.sets_to_align[alignment_grp].index(alignment_grp)
179
180 # we don't need to add empty steps for alignment groups that happen *after* the
181 # one our chain belongs to - so just cut off at the chain's alignment group here.
182 return all_groups_to_align[:index_of_chain_group]
183
184
Definition index.py:1

◆ multi_align()

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

Definition at line 215 of file MenuAlignmentTools.py.

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

◆ single_align()

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

Definition at line 185 of file MenuAlignmentTools.py.

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

Member Data Documentation

◆ combinations_in_menu

MenuAlignmentTools.MenuAlignment.combinations_in_menu = combinations_in_menu

Definition at line 59 of file MenuAlignmentTools.py.

◆ groups_to_align

MenuAlignmentTools.MenuAlignment.groups_to_align = groups_to_align

Definition at line 61 of file MenuAlignmentTools.py.

◆ inverse_sig_dict

dict MenuAlignmentTools.MenuAlignment.inverse_sig_dict = {}

Definition at line 64 of file MenuAlignmentTools.py.

◆ length_of_configs

MenuAlignmentTools.MenuAlignment.length_of_configs = length_of_configs

Definition at line 60 of file MenuAlignmentTools.py.

◆ sets_to_align

MenuAlignmentTools.MenuAlignment.sets_to_align = {}

Definition at line 66 of file MenuAlignmentTools.py.

◆ signature_dict

dict MenuAlignmentTools.MenuAlignment.signature_dict = {}

Definition at line 63 of file MenuAlignmentTools.py.


The documentation for this class was generated from the following file: