ATLAS Offline Software
IdDictDictionary.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3  */
4 
6 
7 #include "IdDict/IdDictField.h"
8 #include "IdDict/IdDictLabel.h"
9 #include "IdDict/IdDictRegion.h"
10 #include "IdDict/IdDictGroup.h"
11 #include "IdDict/IdDictSubRegion.h"
13 #include "IdDict/IdDictMgr.h"
14 #include "IdDict/IdDictRange.h"
15 #include "src/Debugger.h"
16 #include "src/get_bits.h"
17 #include "Identifier/MultiRange.h"
18 #include <iostream>
19 
20 using IdDict::get_bits;
21 
22 static bool isNumber(const std::string& str) {
23  bool result = true;
24 
25  for (unsigned int i = 0; i < str.size(); ++i) {
26  if (!isdigit(str[i])) return(false);
27  }
28  if (0 == str.size()) return(false);
29 
30  return(result);
31 }
32 
34  :
35  m_parent_dict(0),
36  //m_resolved_references(false),
37  m_generated_implementation(false),
38  m_do_checks(false),
39  m_do_neighbours(true)
40 {}
41 
43 }
44 
45 IdDictField* IdDictDictionary::find_field(const std::string& name) const {
46  std::map <std::string, IdDictField*>::const_iterator it;
47 
48  it = m_fields.find(name);
49 
50  if (it == m_fields.end()) {
51  // If parent exists, look for field there
52  if (m_parent_dict) {
53  it = m_parent_dict->m_fields.find(name);
54  if (it == m_parent_dict->m_fields.end()) {
55  return(0);
56  }
57  } else {
58  return(0);
59  }
60  }
61 
62  return((*it).second);
63 }
64 
65 IdDictLabel* IdDictDictionary::find_label(const std::string& field, const std::string& label) const {
66  IdDictField* idField = find_field(field);
67 
68  if (!idField) return nullptr;
69 
70  return(idField->find_label(label));
71 }
72 
73 int IdDictDictionary::get_label_value(const std::string& field, const std::string& label, int& value) const {
74  IdDictLabel* idLabel = find_label(field, label);
75 
76  if (!idLabel || !idLabel->m_valued) return(1);
77 
78  value = idLabel->m_value;
79  return(0);
80 }
81 
83  if (field == 0) return;
84 
85  std::string& name = field->m_name;
86 
87  m_fields[name] = field;
88 }
89 
91 IdDictDictionary::find_subregion(const std::string& name) const {
92  std::map <std::string, IdDictSubRegion*>::const_iterator it;
93 
94  it = m_subregions.find(name);
95 
96  if (it == m_subregions.end()) return(0);
97 
98  return((*it).second);
99 }
100 
101 IdDictRegion* IdDictDictionary::find_region(const std::string& region_name) const {
102  return find_region(region_name, "");
103 }
104 
105 IdDictRegion* IdDictDictionary::find_region(const std::string& region_name, const std::string& group_name) const {
106  for (size_t i = 0; i < m_regions.size(); ++i) {
107  IdDictRegion* region = m_regions[i];
108  if ((group_name != "") && (region->group_name() != group_name)) continue;
109  if ((region != 0) && (region_name == region->m_name)) return(region);
110  }
111 
112  return(0);
113 }
114 
116  for (size_t i = 0; i < m_groups.size(); ++i) {
118  if ((group != 0) && (group->name() == group_name)) return(group);
119  }
120 
121  return(0);
122 }
123 
125  if (subregion == 0) return;
126 
127  std::string& name = subregion->m_name;
128 
129  m_subregions[name] = subregion;
130 }
131 
133  m_subdictionary_names.push_back(name);
134 }
135 
137  // Add region to corresponding group
138  IdDictGroup* group = find_group(region->group_name());
139 
140  if (0 == group) {
141  group = new IdDictGroup(region->group_name());
142  m_groups.push_back(group);
143  }
144  group->add_dictentry(region);
145 }
146 
148  {
150 
151  for (it = m_fields.begin(); it != m_fields.end(); ++it) {
152  IdDictField* field = (*it).second;
153  field->resolve_references(idd);
154  }
155  }
156  {
158 
159  for (it = m_subregions.begin(); it != m_subregions.end(); ++it) {
160  IdDictSubRegion* subregion = (*it).second;
161  subregion->resolve_references(idd, *this);
162  }
163  }
164  {
165  size_t index = 0;
166 
168  for (it = m_groups.begin(); it != m_groups.end(); ++it) {
169  (*it)->resolve_references(idd, *this, index);
170  }
171  }
172 }
173 
175  const std::string& tag) {
176  if (Debugger::debug()) {
177  std::cout << "IdDictDictionary::generate_implementation>" << std::endl;
178  }
179 
181  // Propagate to each region and copy their generation into the
182  // dict's vector.
184  for (it = m_groups.begin(); it != m_groups.end(); ++it) {
185  (*it)->generate_implementation(idd, *this, tag);
186  // Get regions from group and save in m_regions
187  const regions_type& regions = (*it)->regions();
189  for (it1 = regions.begin(); it1 != regions.end(); ++it1) {
190  m_regions.push_back(*it1);
191  }
192  }
193 
194  // Loop again over groups and set the bit-packing - starting at
195  // level 0
196  for (it = m_groups.begin(); it != m_groups.end(); ++it) {
197  // Copy to temporary vector all regions in the group. And
198  // look for regions in local m_regions vector for any
199  // regions "dummy", which come from reference
200  // dictionaries.
201  // Skip special group
202  if ("dummy" == (*it)->name()) continue;
203 
204  get_bits(m_regions, 0, (*it)->name());
205 // get_bits (regions, 0, (*it)->name());
206  }
207 
208  // Set integral over the number of bits
209  integrate_bits();
210 
211  // Set neighbours for regions
213  for (itr = m_regions.begin(); itr != m_regions.end(); ++itr) {
214  (*itr)->find_neighbours(*this);
215  }
216 
218  }
219 }
220 
223  m_regions.clear();
225  for (it = m_groups.begin(); it != m_groups.end(); ++it) {
226  (*it)->reset_implementation();
227  }
229  }
230 }
231 
232 int
234  // Find first region that matches id
235 
237 
238  size_type i = 0;
239  for (it = m_regions.begin(); it != m_regions.end(); ++it, ++i) {
240  const IdDictRegion& region = *(*it);
241 
242  Range range = region.build_range();
243 
244  if (range.match(id) && range.fields() >= id.fields()) {
245  index = i;
246  return(0);
247  }
248  }
249 
250  return(1);
251 }
252 
254  return find_region(id, "");
255 }
256 
258  // Find first region that matches id
259 
260  IdDictRegion* pRegion = 0;
261 
263 
264  for (it = m_regions.begin(); it != m_regions.end(); ++it) {
265  IdDictRegion& region = *(*it);
266  if ((group_name != "") && (region.group_name() != group_name)) continue;
267 
268  Range range = region.build_range();
269 
270  if (range.match(id) && range.fields() >= id.fields()) {
271  pRegion = &region;
272  }
273  }
274 
275  return(pRegion);
276 }
277 
278 void
280  // For each region, loop over its levels and set the bit offset
281  // for each FieldImplementation
282 
283  for (IdDictRegion* region : m_regions) {
284  size_t bits_offset = 0;
285  for (IdDictFieldImplementation& impl : region->m_implementation) {
286  impl.optimize(); // optimize for decoding
287  impl.set_bits_offset(bits_offset);
288  bits_offset += impl.bits();
289 
290  // Set whether or not to decode index
291  Range::field field = impl.ored_field();
292  if ((not field.isBounded()) || (0 != field.get_minimum())) {
293  impl.set_decode_index(true);
294  }
295  }
296  }
297 }
298 
301 
303 
304  for (it = m_groups.begin(); it != m_groups.end(); ++it) {
305  const IdDictGroup& group = *(*it);
306 
307  MultiRange group_mr = group.build_multirange();
308 
309  for (unsigned int i = 0; i < group_mr.size(); ++i) {
310  const Range& range = group_mr[i];
311  result.add(range);
312  }
313  }
314 
315  return(result);
316 }
317 
319  const Range& prefix,
320  const std::string& last_field) const {
322 
324  if ("" == last_field) {
325  // Take all fields
326  for (it = m_regions.begin(); it != m_regions.end(); ++it) {
327  const IdDictRegion& region = *(*it);
328 
329  // skip regions created from parents
330  if ("dummy" == region.m_name) continue;
331 
332  // skip empty regions - may arise from alternate_regions
333  // where a tag selects an empty region
334  if (region.m_is_empty) continue;
335 
336  Range range(region.build_range());
337  // Check region selection
338  if (range.match(region_id)) result.add(std::move(range));
339  }
340  } else {
341  // Not all fields required
342  for (it = m_regions.begin(); it != m_regions.end(); ++it) {
343  const IdDictRegion& region = *(*it);
344 
345  // skip regions created from parents
346  if ("dummy" == region.m_name) continue;
347 
348  // skip empty regions - may arise from alternate_regions
349  // where a tag selects an empty region
350  if (region.m_is_empty) continue;
351 
352  Range range(region.build_range());
353  // Check region selection
354  if (range.match(region_id)) {
355  // Build new range up to last_field and add it to result -
356  // remove duplicate ranges with addRangeToMR
357  Range new_range(prefix); // Prepend with prefix
358 
359  std::vector <IdDictFieldImplementation>::const_iterator fit;
360  for (fit = region.m_implementation.begin();
361  fit != region.m_implementation.end();
362  ++fit) {
364 
365 // new_range.add(impl.m_field);
366  new_range.add(impl.range()->build_range());
367 
368  if (last_field == impl.range()->m_field->m_name) {
369  break;
370  }
371  }
372  result.add(std::move(new_range));
373  }
374  }
375  }
376 
377  return(result);
378 }
379 
381  const std::string& group_name,
382  const Range& prefix,
383  const std::string& last_field) const {
385 
387  if ("" == last_field) {
388  // Take all fields
389  for (it = m_regions.begin(); it != m_regions.end(); ++it) {
390  const IdDictRegion& region = *(*it);
391 
392  // skip regions created from parents
393  if ("dummy" == region.m_name) continue;
394 
395  // skip empty regions - may arise from alternate_regions
396  // where a tag selects an empty region
397  if (region.m_is_empty) continue;
398 
399  Range range(region.build_range());
400  // Check region selection
401  if (range.match(region_id) && region.group_name() == group_name) result.add(std::move(range));
402  }
403  } else {
404  // Not all fields required
405  for (it = m_regions.begin(); it != m_regions.end(); ++it) {
406  const IdDictRegion& region = *(*it);
407 
408  // skip regions created from parents
409  if ("dummy" == region.m_name) continue;
410 
411  // skip empty regions - may arise from alternate_regions
412  // where a tag selects an empty region
413  if (region.m_is_empty) continue;
414 
415  Range range(region.build_range());
416  // Check region selection
417  if (range.match(region_id) && region.group_name() == group_name) {
418  // Build new range up to last_field and add it to result -
419  // remove duplicate ranges with addRangeToMR
420  Range new_range(prefix); // Prepend with prefix
421 
422  std::vector <IdDictFieldImplementation>::const_iterator fit;
423  for (fit = region.m_implementation.begin();
424  fit != region.m_implementation.end();
425  ++fit) {
427 
428 // new_range.add(impl.m_field);
429  new_range.add(impl.range()->build_range());
430 
431  if (last_field == impl.range()->m_field->m_name) {
432  break;
433  }
434  }
435  result.add(std::move(new_range));
436  }
437  }
438  }
439 
440  return(result);
441 }
442 
456 int
458  size_t index1,
459  size_t index2,
460  Identifier& packedId) const {
461  packedId = 0;
462 
463 
464  // Preconditions...
465 
466  if (index2 < index1) {
467  // bad parameters.
468  return(1);
469  }
470 
471  if (index1 >= id.fields()) {
472  // nothing very useful !!
473  return(1);
474  }
475 
476  if (index2 >= id.fields()) {
477  // bad parameter...
478  return(1);
479  }
480 
490  for (size_t k = 0; k < m_regions.size(); ++k) {
491  bool selected = true;
492 
493  const IdDictRegion& region = *m_regions[k];
494 
495  // Must skip empty regions - can arise when a tag selects an
496  // empty region
497  if (region.m_is_empty) continue;
498 
499  for (size_t i = 0; i < region.m_implementation.size(); ++i) {
500  if (i >= id.fields()) break;
501 
503 
504  if (!impl.field().match(id[i])) {
505  selected = false;
506  break;
507  }
508  }
509 
510  if (selected) {
511  size_t position = Identifier::NBITS;
512  // We have the proper region.
513  for (size_t i = index1; i <= index2; ++i) {
515 
516  Identifier::value_type index = impl.ored_field().get_value_index(id[i]);
517 
518  if (0 == position && impl.bits() > 0) {
519  return(1);
520  }
521 
522  position -= impl.bits();
523  packedId |= (index << position);
524  }
525  break;
526  }
527  }
528 
529 
530  return(0);
531 }
532 
533 int
535  size_t index1,
536  size_t index2,
537  size_t region_index,
538  Identifier& packedId,
539  size_t first_field_index) const {
540  // Preconditions...
541 
542  if (m_do_checks) {
543  if (index2 < index1) {
544  // bad parameters.
545  std::cout << "IdDictDictionary::pack32 - index2 < index1 - 1,2"
546  << index1 << " " << index2 << std::endl;
547  return(1);
548  }
549 
550  if (region_index >= m_regions.size()) {
551  // bad parameters.
552  std::cout << "IdDictDictionary::pack32 - region index incorrect - index,size"
553  << region_index << " " << m_regions.size() << std::endl;
554  return(1);
555  }
556  }
557 
558 
559  // Get the region
560  const IdDictRegion& region = *m_regions[region_index];
561 
562  if (m_do_checks) {
563  if (region.m_is_empty) {
564  std::cout << "IdDictDictionary::pack32 - region id empty" << std::endl;
565  // bad parameters.
566  return(1);
567  }
568  if (index1 < first_field_index) {
569  std::cout << "IdDictDictionary::pack32 - first_field_index > index1 "
570  << first_field_index << " " << index1 << std::endl;
571  return(1);
572  }
573  }
574 
575  // Set the starting position
576  size_t position = Identifier::NBITS;
577  if (!first_field_index) {
579  position -= impl.bits_offset();
580  }
581 
582  size_t field_index = 0;
583  for (size_t i = index1; i <= index2; ++i, ++field_index) {
585 
586  if (m_do_checks) {
587  // Field should be within allowed range
588  if (!impl.ored_field().match(fields[field_index])) {
589  std::cout << "IdDictDictionary::pack32 - field does NOT match: value, allowed values "
590  << fields[field_index] << " " << (std::string) impl.ored_field()
591  << std::endl;
592  // bad parameters.
593  return(1);
594  }
595 
596  // Check that we don't try to go below 0
597  if (0 == position && impl.bits() > 0) {
598  std::cout << "IdDictDictionary::pack32 - going past 0" << std::endl;
599  return(1);
600  }
601  }
602 
604  if (impl.decode_index()) {
605  index = impl.ored_field().get_value_index(fields[field_index]);
606  } else {
607  index = (Identifier::value_type) fields[field_index];
608  }
609 
610  position -= impl.bits();
611  packedId |= (index << position);
612  }
613 
614 
615  return(0);
616 }
617 
622  size_t index2,
623  size_t region_index,
624  Identifier& packedId) const {
625  // Preconditions...
626 
627  if (m_do_checks) {
628  if (index2 < index1) {
629  // bad parameters.
630  std::cout << "IdDictDictionary::pack32 - index2 < index1 - 1,2"
631  << index1 << " " << index2 << std::endl;
632  return(1);
633  }
634 
635  if (region_index >= m_regions.size()) {
636  // bad parameters.
637  std::cout << "IdDictDictionary::pack32 - region index incorrect - index,size"
638  << region_index << " " << m_regions.size() << std::endl;
639  return(1);
640  }
641  }
642 
643 
644  // Get the region
645  const IdDictRegion& region = *m_regions[region_index];
646 
647  if (m_do_checks) {
648  if (region.m_is_empty) {
649  std::cout << "IdDictDictionary::pack32 - region id empty" << std::endl;
650  // bad parameters.
651  return(1);
652  }
653  }
654 
655  size_t field_index = 0;
656  for (size_t i = index1; i <= index2; ++i, ++field_index) {
658 
659  size_t position = Identifier::NBITS - impl.bits_offset() - impl.bits();
660 
661  Identifier::value_type mask = (((Identifier::value_type) 1 << impl.bits()) - 1) << position;
662 
664 
665  packedId &= (mask);
666  }
667  return(0);
668 }
669 
674 #if defined(FLATTEN) && defined(__GNUC__)
675 // We compile this package with optimization, even in debug builds; otherwise,
676 // the heavy use of Eigen makes it too slow. However, from here we may call
677 // to out-of-line Eigen code that is linked from other DSOs; in that case,
678 // it would not be optimized. Avoid this by forcing all Eigen code
679 // to be inlined here if possible.
680 __attribute__ ((flatten))
681 #endif
682 int
684  const ExpandedIdentifier& prefix,
685  size_t index2,
686  ExpandedIdentifier& unpackedId) const {
687  ExpandedIdentifier localPrefix(prefix);
688 
689  unpackedId.clear();
690  if (0 < localPrefix.fields()) unpackedId = localPrefix;
691 
697  size_t index1 = 0; // field index
698  size_t position = Identifier::NBITS; // overall bit position - used for debugging only
699 
700  for (size_t k = 0; k < m_regions.size(); ++k) {
701  bool selected = false;
702 
703  const IdDictRegion& region = *m_regions[k];
704 
705  // Must skip empty regions - can arise when a tag selects an
706  // empty region
707  if (region.m_is_empty) continue;
708 
709 // for (size_t i = index1; i < region.m_implementation.size (); ++i)
710  for (size_t i = 0; i < region.m_implementation.size(); ++i) {
711  if (i >= localPrefix.fields()) {
716  selected = true;
717  index1 = i;
718  break;
719  }
720 
722 
723  if (!impl.field().match(localPrefix[i])) {
724  break;
725  }
726  }
727 
728  if (selected) {
737  for (size_t i = index1; i < region.m_implementation.size(); ++i) {
739 
740  if (impl.bits() == 0) continue;
741 
742  Identifier::value_type mask = (static_cast<Identifier::value_type>(1) << impl.bits()) - 1;
743 
744  if (position < impl.bits()) break; // Nothing more to get
745  size_t index = id.extract(position - impl.bits(), mask);
746 
747  if (index >= impl.ored_field().get_indices()) {
754  selected = false;
755  break;
756  }
757 
758  ExpandedIdentifier::element_type value = impl.ored_field().get_value_at(index);
759 
766  if (!impl.field().match(value)) {
767  selected = false;
768  break;
769  }
770 
771 
772 
773  // Found value
774 
775  unpackedId.add(value);
776  localPrefix.add(value);
777 
778  position -= impl.bits(); // overall bit position
779 
780 
781 
782  index1++; // next field
783 
784  if (index1 > index2) break; // quit at index2
785  }
786 
787  if (selected) break;
788  }
789  }
790 
791  return(0);
792 }
793 
799 int
801  const ExpandedIdentifier& prefix,
802  size_t index2,
803  const std::string& sep,
804  std::string& unpackedId) const {
805  ExpandedIdentifier localPrefix(prefix);
806 
807 
813  size_t index1 = 0; // field index
814  size_t position = Identifier::NBITS; // overall bit position - used for debugging only
815 
816  for (size_t k = 0; k < m_regions.size(); ++k) {
817  bool selected = false;
818 
819  const IdDictRegion& region = *m_regions[k];
820 
821  // Must skip empty regions - can arise when a tag selects an
822  // empty region
823  if (region.m_is_empty) continue;
824 
825 // for (size_t i = index1; i < region.m_implementation.size (); ++i)
826  for (size_t i = 0; i < region.m_implementation.size(); ++i) {
827  if (i >= localPrefix.fields()) {
832  selected = true;
833  index1 = i;
834  break;
835  }
836 
838 
839  if (!impl.field().match(localPrefix[i])) {
840  break;
841  }
842  }
843 
844  if (selected) {
851 // bits32 temp = id;
852 
853 // std::cout << "Region #" << region.m_index << " selected" << std::endl;
854 
855  for (size_t i = index1; i < region.m_implementation.size(); ++i) {
857 
858  if (impl.bits() == 0) continue;
859 
860  Identifier::value_type mask = (static_cast<Identifier::value_type>(1) << impl.bits()) - 1;
861 
862  if (position < impl.bits()) break; // Nothing more to get
863  size_t index = id.extract(position - impl.bits(), mask);
864 
865  if (index >= impl.ored_field().get_indices()) {
866  selected = false;
867  break;
868  }
869 
870  ExpandedIdentifier::element_type value = impl.ored_field().get_value_at(index);
871 
878  if (!impl.field().match(value)) {
879  selected = false;
880  break;
881  }
882 
883 
884  // Add value to string
885 
886  std::string str_value("nil");
887  char temp[20];
888 
889  // The policy below is:
890  // - if a value is a character string or name, just add this name
891  // - if a value is a number, then prefix it with the
892  // name of the field
893  //
894  // NOTE: min/max is a number, but for value/label we
895  // distinguish between number and name by looking for an IdDictLabel
896  const IdDictRange* range = impl.range();
897  IdDictLabel* label = range->m_field->find_label(range->m_label);
898  switch (range->m_specification) {
900  // For a range of values (numbers), add in the field name
901  str_value = range->m_field->m_name + ' ';
902  sprintf(temp, "%d", value);
903  str_value += temp;
904  break;
905 
908  str_value = "";
909  if (!label) {
910  // Is a number, add in field name
911  str_value += range->m_field->m_name + ' ';
912  }
913  str_value += range->m_label;
914  break;
915 
918  str_value = "";
919  // Is a name
920  if (label) {
921  // Found label with "find_label" on the field
922  if (label->m_valued) {
923  str_value += range->m_label;
924  }
925  } else {
926  // If not found with the "find" above, we must
927  // get the value and name from the range
928  // itself.
929 
930  unsigned int index1 = 0;
931  for (; index1 < range->m_values.size(); ++index1) {
932  if (value == range->m_values[index1]) {
933  break;
934  }
935  }
936 
937  // In some cases we
938  if (index1 < range->m_labels.size()) {
939  if (isNumber(range->m_labels[index1])) {
940  str_value += range->m_field->m_name + ' ';
941  }
942  str_value += range->m_labels[index1];
943  } else {
944  std::cout << "IdDictDictionary::unpack - Could not find value." << std::endl;
945  std::cout << "value " << value << std::endl;
946  std::cout << "field values " << std::endl;
947  for (unsigned int i = 0; i < range->m_values.size(); ++i) {
948  std::cout << range->m_values[i] << " ";
949  }
950  std::cout << std::endl;
951  }
952  }
953  break;
954 
956 
957  std::cout << "unknown" << std::endl;
958 
959  break;
960  }
961 
962 
963  if (index1) unpackedId += sep;
964  unpackedId += str_value;
965  localPrefix.add(value);
966 
967  position -= impl.bits(); // overall bit position
968 
969 
970 
971  index1++; // next field
972 
973  if (index1 > index2) break; // quit at index2
974  }
975  if (selected) break;
976  }
977  }
978 
979  return(0);
980 }
981 
990 int
992  size_t first_field_index,
993  size_t field_index,
994  size_t region_index,
995  int& field) const {
996  field = 0;
997 
998  if (m_do_checks) {
999  // Check regions
1000  if (region_index >= m_regions.size()) {
1001  std::cout << "IdDictDictionary::unpack - region index too large. Index, nregions "
1002  << region_index << " " << m_regions.size() << std::endl;
1003  return(1);
1004  }
1005  }
1006 
1007  const IdDictRegion& region = *m_regions.at(region_index);
1008 
1009  if (m_do_checks) {
1010  // check number of fields
1011  if (field_index >= region.m_implementation.size()) {
1012  std::cout << "IdDictDictionary::unpack - field index too large. Index, nfields "
1013  << field_index << " " << region.m_implementation.size()
1014  << std::endl;
1015  return(1);
1016  }
1017  }
1018 
1019  const IdDictFieldImplementation& impl = region.m_implementation.at(field_index);
1020  size_t prefix_offset = 0;
1021 
1022  size_t position = Identifier::NBITS; // overall bit position
1023 
1024  // One or more fields missing from prefix, get the offset
1025  if (first_field_index) {
1026  if (m_do_checks) {
1027  if (first_field_index >= region.m_implementation.size()) {
1028  std::cout << "IdDictDictionary::unpack - first_field_index too large. Index, nfields "
1029  << first_field_index << " " << region.m_implementation.size()
1030  << std::endl;
1031  return(1);
1032  }
1033  }
1034 
1035  // One or more fields missing from prefix, get the offset
1036  prefix_offset = region.m_implementation[first_field_index].bits_offset();
1037 
1038  if (m_do_checks) {
1039  // Should have a non-zero number of bits
1040  if (impl.bits() == 0) {
1041  std::cout << "IdDictDictionary::unpack - no bits for this field. Region, field indexes "
1042  << region_index << " " << field_index << std::endl;
1043  return(1);
1044  }
1045 
1046  // Check the shift value
1047  if (impl.bits() + impl.bits_offset() - prefix_offset > position) {
1048  std::cout << "IdDictDictionary::unpack - bits + offset too large. Region, field indexes, bits, offset "
1049  << region_index << " " << field_index << " "
1050  << impl.bits() << " " << impl.bits_offset() << " " << prefix_offset
1051  << std::endl;
1052  return(1);
1053  }
1054  }
1055  }
1056 
1057  Identifier::value_type mask = (static_cast<Identifier::value_type>(1) << impl.bits()) - 1;
1058 
1059  size_t index = id.extract(position -= impl.bits() + impl.bits_offset() - prefix_offset, mask);
1060 
1061  field = index;
1062  if (impl.decode_index()) field = impl.ored_field().get_value_at(index);
1063 
1064 
1065  return(0);
1066 }
1067 
1077 int
1079  size_t first_field_index,
1080  size_t begin_field_index,
1081  size_t end_field_index,
1082  size_t region_index,
1083  Identifier& idout) const {
1084  idout = Identifier();
1085  if (region_index >= m_regions.size()) {
1086  std::cout << "IdDictDictionary::copy - region index too large. Index, nregions "
1087  << region_index << " " << m_regions.size() << std::endl;
1088  return(1);
1089  }
1090 
1091  const IdDictRegion& region = *m_regions[region_index];
1092 
1093  if (first_field_index >= region.m_implementation.size() ||
1094  begin_field_index >= region.m_implementation.size() ||
1095  end_field_index >= region.m_implementation.size()) {
1096  std::cout << "IdDictDictionary::copy - field index too large. Indexes first, begin, end, nfields "
1097  << first_field_index << " "
1098  << begin_field_index << " "
1099  << end_field_index << " "
1100  << region.m_implementation.size()
1101  << std::endl;
1102  return(1);
1103  }
1104 
1105  size_t missing_offset = 0;
1106  if (first_field_index) {
1107  if (first_field_index > begin_field_index) {
1108  std::cout << "IdDictDictionary::copy - first_field_index > begin_field_index. Indexes "
1109  << first_field_index << " " << begin_field_index << std::endl;
1110  return(1);
1111  }
1112  // One or more fields missing from prefix, get the offset
1113  missing_offset = region.m_implementation[first_field_index].bits_offset();
1114  }
1115 
1116  size_t prefix_offset = 0;
1117  if (begin_field_index) {
1118  if (begin_field_index > end_field_index) {
1119  std::cout << "IdDictDictionary::copy - begin_field_index > end_field_index. Indexes "
1120  << begin_field_index << " " << end_field_index << std::endl;
1121  return(1);
1122  }
1123  // One or more fields missing from prefix, get the offset
1124  prefix_offset = region.m_implementation[begin_field_index].bits_offset();
1125  }
1126 
1127  const IdDictFieldImplementation& impl = region.m_implementation[end_field_index];
1128  size_t suffix_offset = impl.bits() + impl.bits_offset();
1129 
1130  size_t position = Identifier::NBITS; // overall bit position
1131 
1132  if (position < prefix_offset - missing_offset) {
1133  std::cout << "IdDictDictionary::copy - position < prefix + missing. "
1134  << prefix_offset << " " << missing_offset << std::endl;
1135  return(1);
1136  }
1137 
1138 
1139  if (position < suffix_offset + missing_offset) {
1140  std::cout << "IdDictDictionary::copy - position < suffix + missing. "
1141  << suffix_offset << " " << missing_offset << std::endl;
1142  return(1);
1143  }
1144 
1145 
1146  // prepare the mask for copying
1147 
1149 
1150  Identifier::value_type prefix_mask =
1151  prefix_offset ? (static_cast<Identifier::value_type>(1) << (position - prefix_offset + missing_offset)) - 1 : 0;
1152 
1153  Identifier::value_type suffix_mask =
1154  (static_cast<Identifier::value_type>(1) << (position - suffix_offset + missing_offset)) - 1;
1155 
1156  mask -= prefix_mask + suffix_mask;
1157 
1158  idout = idin.mask_shift(mask, missing_offset);
1159 
1160 
1161  return(0);
1162 }
1163 
1164 bool
1166  return(m_do_checks);
1167 }
1168 
1169 void
1172 }
1173 
1174 bool
1176  return(m_do_neighbours);
1177 }
1178 
1179 void
1182 }
1183 
1209  // check #1
1210 
1212 
1213  if (mr.has_overlap()) return(false);
1214 
1215 
1216  return(true);
1217 }
1218 
1230  // verify
1231  if (verify()) {
1232  std::map< ExpandedIdentifier, IdDictDictEntry* > regions;
1233 
1235 
1236  for (it = m_groups.begin(); it != m_groups.end(); ++it) {
1237  (*it)->sort();
1238  }
1239  } else {
1240  std::cout << "IdDictDictionary::sort - WARNING verify is FALSE - cannot sort "
1241  << std::endl;
1242  }
1243 }
1244 
1246  {
1248 
1249  for (it = m_subregions.begin(); it != m_subregions.end(); ++it) {
1250  IdDictSubRegion* subregion = (*it).second;
1251  subregion->clear();
1252  delete subregion;
1253  }
1254 
1255  m_subregions.clear();
1256  }
1257 
1258  {
1260 
1261  for (it = m_fields.begin(); it != m_fields.end(); ++it) {
1262  IdDictField* field = (*it).second;
1263  field->clear();
1264  delete field;
1265  }
1266 
1267  m_fields.clear();
1268  }
1269 
1270  {
1272 
1273  for (it = m_groups.begin(); it != m_groups.end(); ++it) {
1274  IdDictGroup* group = *it;
1275  group->clear();
1276  delete group;
1277  }
1278 
1279  m_groups.clear();
1280  }
1281 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
IdDictDictionary::find_region
IdDictRegion * find_region(const std::string &region_name) const
Definition: IdDictDictionary.cxx:101
IdDictRange.h
IdDictMgr.h
IdDictDictionary::build_multirange
MultiRange build_multirange() const
Get MultiRange for full dictionary.
Definition: IdDictDictionary.cxx:299
IdDictDictionary::unpack
int unpack(const Identifier &id, const ExpandedIdentifier &prefix, size_t index2, ExpandedIdentifier &unpackedId) const
Unpack the value_type id to an expanded Identifier, considering the provided prefix (result will incl...
Definition: IdDictDictionary.cxx:683
IdDictRegion::resolve_references
void resolve_references(const IdDictMgr &idd, IdDictDictionary &dictionary)
Definition: IdDictRegion.cxx:28
IdDictDictionary::reset
int reset(size_t index1, size_t index2, size_t region_index, Identifier &packedId) const
Reset fields from index1 to index2.
Definition: IdDictDictionary.cxx:621
get_generator_info.result
result
Definition: get_generator_info.py:21
IdDictGroup
Definition: IdDictGroup.h:19
IdDictDictionary::do_neighbours
bool do_neighbours(void) const
Neighbour initialization is performed by default One can switch or query this mode for any idHelper w...
Definition: IdDictDictionary.cxx:1175
IdDictLabel.h
IdDictDictionary::generate_implementation
void generate_implementation(const IdDictMgr &idd, const std::string &tag="")
Definition: IdDictDictionary.cxx:174
IdDictRange::by_minmax
@ by_minmax
Definition: IdDictRange.h:40
IdDictLabel::m_value
int m_value
Definition: IdDictLabel.h:13
IdDictDictionary::m_groups
std::vector< IdDictGroup * > m_groups
Definition: IdDictDictionary.h:237
IdDictDictionary::do_checks
bool do_checks(void) const
Checks are performed by default in debug compilation and NOT in optimized compilation.
Definition: IdDictDictionary.cxx:1165
IdDict::get_bits
void get_bits(const RV &regions, size_t level, const std::string &group)
Definition: get_bits.cxx:45
index
Definition: index.py:1
PlotCalibFromCool.label
label
Definition: PlotCalibFromCool.py:78
IdDictRange::by_label
@ by_label
Definition: IdDictRange.h:38
IdDictDictionary::find_label
IdDictLabel * find_label(const std::string &field, const std::string &label) const
Definition: IdDictDictionary.cxx:65
Identifier::mask_shift
value_type mask_shift(value_type mask, size_type shift) const
extract field(s) by masking first, then shifting
IdDictDictionary.h
IdDictDictionary::groups_const_it
groups_type::const_iterator groups_const_it
Definition: IdDictDictionary.h:231
ExpandedIdentifier::add
void add(element_type value)
Append a value into a new field.
skel.it
it
Definition: skel.GENtoEVGEN.py:396
IdDictRange::by_labels
@ by_labels
Definition: IdDictRange.h:39
IdDictDictionary::regions_type
std::vector< IdDictRegion * > regions_type
Definition: IdDictDictionary.h:225
ExpandedIdentifier
Definition: DetectorDescription/Identifier/Identifier/ExpandedIdentifier.h:102
IdDictDictionary::m_do_checks
bool m_do_checks
Definition: IdDictDictionary.h:245
IdDictField::find_label
IdDictLabel * find_label(const std::string &name) const
Definition: IdDictField.cxx:26
athena.value
value
Definition: athena.py:124
ExpandedIdentifier::fields
size_type fields() const
IdDictSubRegion.h
IdDictDictionary::~IdDictDictionary
~IdDictDictionary()
Definition: IdDictDictionary.cxx:42
Debugger.h
ReadOfcFromCool.field
field
Definition: ReadOfcFromCool.py:48
IdDictRegion::clear
void clear()
Definition: IdDictRegion.cxx:126
IdDictDictEntry
Definition: IdDictDictEntry.h:13
IdDictDictionary::pack32
int pack32(const ExpandedIdentifier &id, size_t index1, size_t index2, Identifier &packedId) const
Pack to 32bits the subset of id between (inclusive) index1 and index2 - this is generic,...
Definition: IdDictDictionary.cxx:457
IdDictGroup.h
IdDictDictionary::find_field
IdDictField * find_field(const std::string &name) const
Definition: IdDictDictionary.cxx:45
CalibDbCompareRT.region_id
region_id
Definition: CalibDbCompareRT.py:68
IdDictRegion
Definition: IdDictRegion.h:20
IdDictDictionary::resolve_references
void resolve_references(const IdDictMgr &idd)
Definition: IdDictDictionary.cxx:147
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
IdDictRegion::m_name
std::string m_name
Definition: IdDictRegion.h:44
IdDictDictionary::verify
bool verify() const
Here, we verify global constraints : (this must only be applied after the resolve_references and gene...
Definition: IdDictDictionary.cxx:1208
IdDictLabel::m_valued
bool m_valued
Definition: IdDictLabel.h:12
IdDictDictionary::reset_implementation
void reset_implementation()
Definition: IdDictDictionary.cxx:221
IdDictDictionary::m_parent_dict
IdDictDictionary * m_parent_dict
Definition: IdDictDictionary.h:239
get_bits.h
IdDictDictionary::size_type
Identifier::size_type size_type
Definition: IdDictDictionary.h:33
IdDictMgr
Definition: IdDictMgr.h:14
IdDictDictionary::groups_it
groups_type::iterator groups_it
Definition: IdDictDictionary.h:230
IdDictDictionary::m_fields
std::map< std::string, IdDictField * > m_fields
Definition: IdDictDictionary.h:233
IdDictDictionary::IdDictDictionary
IdDictDictionary()
Definition: IdDictDictionary.cxx:33
IdDictDictionary::find_group
IdDictGroup * find_group(const std::string &group_name) const
Definition: IdDictDictionary.cxx:115
IdDictRegion::build_range
Range build_range() const
Definition: IdDictRegion.cxx:147
Trk::index1
@ index1
Definition: BoundarySurfaceFace.h:48
lumiFormat.i
int i
Definition: lumiFormat.py:85
DetDescrDictionaryDict::it1
std::vector< HWIdentifier >::iterator it1
Definition: DetDescrDictionaryDict.h:17
IdDictDictionary::m_generated_implementation
bool m_generated_implementation
Definition: IdDictDictionary.h:244
IdDictRegion::m_is_empty
bool m_is_empty
Definition: IdDictRegion.h:47
IdDictDictionary::m_regions
std::vector< IdDictRegion * > m_regions
Definition: IdDictDictionary.h:235
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
mc.group_name
group_name
Definition: mc.PhPy8EG_A14NNPDF23_NNLOPS_example.py:33
IdDictRegion::group_name
std::string group_name() const
Definition: IdDictRegion.cxx:13
IdDictRange::unknown
@ unknown
Definition: IdDictRange.h:35
IdDictDictionary::add_subdictionary_name
void add_subdictionary_name(const std::string &name)
Definition: IdDictDictionary.cxx:132
IdDictDictionary::regions_it
regions_type::iterator regions_it
Definition: IdDictDictionary.h:226
IdDictLabel
Definition: IdDictLabel.h:10
Debugger::debug
static bool debug()
Definition: Debugger.h:18
MuonValidation_CreateResolutionProfiles.fit
def fit(h, emin, emax)
Definition: MuonValidation_CreateResolutionProfiles.py:69
Identifier::ALL_BITS
@ ALL_BITS
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:34
IdDictDictionary::regions_const_it
regions_type::const_iterator regions_const_it
Definition: IdDictDictionary.h:227
IdDictDictionary::get_label_value
int get_label_value(const std::string &field, const std::string &label, int &value) const
Definition: IdDictDictionary.cxx:73
python.update_ci_reference_files.mr
mr
Definition: update_ci_reference_files.py:415
grepfile.sep
sep
Definition: grepfile.py:38
IdDictDictionary::sort
void sort()
Sort:
Definition: IdDictDictionary.cxx:1229
MultiRange
A MultiRange combines several Ranges.
Definition: MultiRange.h:17
Trk::index2
@ index2
Definition: BoundarySurfaceFace.h:49
IdDictDictionary::clear
void clear()
Definition: IdDictDictionary.cxx:1245
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
IdDictDictionary::add_field
void add_field(IdDictField *field)
Definition: IdDictDictionary.cxx:82
Identifier::NBITS
@ NBITS
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
IdDictDictionary::m_do_neighbours
bool m_do_neighbours
Definition: IdDictDictionary.h:246
IdDictDictEntry::group_name
virtual std::string group_name() const =0
Range
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
Definition: DetectorDescription/Identifier/Identifier/Range.h:29
MultiRange.h
Range::add
void add()
Add a wild card field.
Definition: DetectorDescription/Identifier/src/Range.cxx:75
IdDictFieldImplementation.h
IdDictDictionary::find_subregion
IdDictSubRegion * find_subregion(const std::string &subregion_name) const
Definition: IdDictDictionary.cxx:91
IdDictRange
Definition: IdDictRange.h:18
impl
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:46
DeMoScan.index
string index
Definition: DeMoScan.py:364
__attribute__
__attribute__((always_inline)) inline uint16_t TileCalibDrawerBase
Definition: TileCalibDrawerBase.h:190
IdDictDictionary::m_subdictionary_names
std::vector< std::string > m_subdictionary_names
Definition: IdDictDictionary.h:238
IdDictField.h
CaloLCW_tf.group
group
Definition: CaloLCW_tf.py:28
IdDictDictionary::m_subregions
std::map< std::string, IdDictSubRegion * > m_subregions
Definition: IdDictDictionary.h:234
IdDictDictionary::add_dictentry
void add_dictentry(IdDictDictEntry *entry)
Definition: IdDictDictionary.cxx:136
MultiRange::size
size_type size() const
Definition: MultiRange.cxx:70
IdentifierField
This is the individual specification for the range of one ExpandedIdentifier IdentifierField.
Definition: IdentifierField.h:21
IdDictRange::by_values
@ by_values
Definition: IdDictRange.h:37
ExpandedIdentifier::clear
void clear()
Erase all fields.
Identifier::value_type
unsigned long long value_type
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:27
isNumber
bool isNumber(const std::string &s)
Definition: PoolSvc.cxx:52
str
Definition: BTagTrackIpAccessor.cxx:11
IdDictRegion.h
IdDictSubRegion
Definition: IdDictSubRegion.h:13
IdDictRange::by_value
@ by_value
Definition: IdDictRange.h:36
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
IdDictDictionary::set_do_neighbours
void set_do_neighbours(bool do_neighbours)
Definition: IdDictDictionary.cxx:1180
CaloCondBlobAlgs_fillNoiseFromASCII.fields
fields
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:106
IdDictField
Definition: IdDictField.h:15
IdDictFieldImplementation
IdDictFieldImplementation is used to capture the specification of a single field of an Identifier.
Definition: IdDictFieldImplementation.h:58
IdDictDictionary::integrate_bits
void integrate_bits()
Set up integral of bits for efficient unpacking.
Definition: IdDictDictionary.cxx:279
ExpandedIdentifier::element_type
int element_type
Definition: DetectorDescription/Identifier/Identifier/ExpandedIdentifier.h:106
IdDictRegion::m_implementation
std::vector< IdDictFieldImplementation > m_implementation
Definition: IdDictRegion.h:42
IdDictDictionary::copy
int copy(const Identifier &idin, size_t first_field_index, size_t begin_field_index, size_t end_field_index, size_t region_index, Identifier &idout) const
Copy a number of fields of the value_type id into another value_type id.
Definition: IdDictDictionary.cxx:1078
IdDictDictionary::add_subregion
void add_subregion(IdDictSubRegion *subregion)
Definition: IdDictDictionary.cxx:124
fitman.k
k
Definition: fitman.py:528
Identifier
Definition: IdentifierFieldParser.cxx:14
IdDictDictionary::set_do_checks
void set_do_checks(bool do_checks)
Definition: IdDictDictionary.cxx:1170