CMS 3D CMS Logo

ThinnedAssociationsHelper.cc
Go to the documentation of this file.
4 #include <algorithm>
5 
6 namespace edm {
7 
9 
11  BranchID const& association,
12  BranchID const& thinned) :
13  parent_(parent),
14  association_(association),
15  thinned_(thinned) {
16  }
17 
19  }
20 
21  std::vector<ThinnedAssociationBranches>::const_iterator
23  return vThinnedAssociationBranches_.begin();
24  }
25 
26  std::vector<ThinnedAssociationBranches>::const_iterator
28  return vThinnedAssociationBranches_.end();
29  }
30 
31  std::vector<ThinnedAssociationBranches>::const_iterator
34  return std::lower_bound(vThinnedAssociationBranches_.begin(), vThinnedAssociationBranches_.end(), target,
35  [](ThinnedAssociationBranches const& x,
37  { return x.parent() < y.parent(); });
38  }
39 
40  std::vector<ThinnedAssociationBranches>::const_iterator
43  return std::upper_bound(vThinnedAssociationBranches_.begin(), vThinnedAssociationBranches_.end(), target,
44  [](ThinnedAssociationBranches const& x,
46  { return x.parent() < y.parent(); });
47  }
48 
50  std::sort(vThinnedAssociationBranches_.begin(), vThinnedAssociationBranches_.end(),
51  [](ThinnedAssociationBranches const& x,
53  { return x.parent() < y.parent() ? true : y.parent() < x.parent() ? false : x.association() < y.association(); });
54  }
55 
57  BranchID const& association,
58  BranchID const& thinned) {
59  vThinnedAssociationBranches_.push_back(ThinnedAssociationBranches(parent, association, thinned));
60  }
61 
63  vThinnedAssociationBranches_.push_back(branches);
64  }
65 
66  std::vector<std::pair<BranchID, ThinnedAssociationBranches const*> >
68  std::vector<std::pair<BranchID, ThinnedAssociationBranches const*> > temp;
69  for(auto const& item : vThinnedAssociationBranches_) {
70  temp.push_back(std::make_pair(item.association(), &item));
71  }
72  std::sort(temp.begin(), temp.end(), [](std::pair<BranchID, ThinnedAssociationBranches const*> const& x,
73  std::pair<BranchID, ThinnedAssociationBranches const*> const& y)
74  { return x.first < y.first; });
75  return temp;
76  }
77 
78  void
80  selectAssociationProducts(std::vector<BranchDescription const*> const& associationDescriptions,
81  std::set<BranchID> const& keptProductsInEvent,
82  std::map<BranchID, bool>& keepAssociation) const {
83 
84  keepAssociation.clear();
85  // Copy the elements in vThinnedAssociationBranches_ into a vector sorted on
86  // the association BranchID so we can do searches on that BranchID faster.
87  std::vector<std::pair<BranchID, ThinnedAssociationBranches const*> > assocToBranches =
88  associationToBranches();
89 
90  for(auto association : associationDescriptions) {
91  if(association->isAlias()) { // There is no reason to configure an association product with an EDAlias (ignore and drop them if they exist)
92  keepAssociation.insert(std::make_pair(association->branchID(), false));
93  } else {
94  std::set<BranchID> branchesInRecursion;
95  shouldKeepAssociation(association->branchID(),
96  assocToBranches,
97  branchesInRecursion,
98  keptProductsInEvent,
99  keepAssociation);
100  }
101  }
102  }
103 
105  BranchID const& association,
106  std::vector<std::pair<BranchID, ThinnedAssociationBranches const*> > const& associationToBranches,
107  std::set<BranchID>& branchesInRecursion,
108  std::set<BranchID> const& keptProductsInEvent,
109  std::map<BranchID, bool>& keepAssociation) const {
110 
111  // If we already decided to keep or drop this one, then
112  // return the same decision.
113  auto decision = keepAssociation.find(association);
114  if(decision != keepAssociation.end()) {
115  return decision->second;
116  }
117 
118  // Be careful not to fall into an infinite loop because
119  // of a circular recursion.
120  if(!branchesInRecursion.insert(association).second) {
121  return false;
122  }
123 
124  // If the thinned collection is being kept then keep the association
125  auto branches = std::lower_bound(associationToBranches.begin(), associationToBranches.end(),
126  std::make_pair(association, static_cast<ThinnedAssociationBranches const*>(nullptr)),
127  [](std::pair<BranchID, ThinnedAssociationBranches const*> const& x,
128  std::pair<BranchID, ThinnedAssociationBranches const*> const& y)
129  { return x.first < y.first; });
130  // This should never happen
131  if(branches == associationToBranches.end() || branches->first != association) {
132  throw edm::Exception(errors::LogicError, "ThinnedAssociationHelper::shouldKeepAssociation could not find branches information, contact Framework developers");
133  }
134  BranchID const& thinnedCollection = branches->second->thinned();
135  if(keptProductsInEvent.find(thinnedCollection) != keptProductsInEvent.end()) {
136  keepAssociation.insert(std::make_pair(association , true));
137  return true;
138  }
139  // otherwise loop over any associations where the thinned collection
140  // is also a parent collection and recursively examine those to see
141  // if their thinned collections are being kept.
142  auto iterEnd = parentEnd(thinnedCollection);
143  for(auto match = parentBegin(thinnedCollection); match != iterEnd; ++match) {
144  if(shouldKeepAssociation(match->association(),
145  associationToBranches,
146  branchesInRecursion,
147  keptProductsInEvent,
148  keepAssociation)) {
149  keepAssociation.insert(std::make_pair(association , true));
150  return true;
151  }
152  }
153  // drop the association
154  keepAssociation.insert(std::make_pair(association , false));
155  return false;
156  }
157 
159  bool foundMatch = false;
160  for(auto entry = parentBegin(input.parent()), iEnd = parentEnd(input.parent());
161  entry != iEnd; ++entry) {
162  if(entry->association() == input.association() &&
163  entry->thinned() == input.thinned()) {
164  foundMatch = true;
165  break;
166  }
167  }
168  if(!foundMatch) {
169  throw edm::Exception(errors::MismatchedInputFiles, "ThinnedAssociationHelper::requireMatch, Illegal attempt to merge files with different ThinnedAssociations");
170  }
171  }
172 
174  if(vThinnedAssociationBranches_.empty()) {
175  vThinnedAssociationBranches_ = helper.data();
176  return;
177  }
178  std::vector<ThinnedAssociationBranches> const& inputData = helper.data();
179  for (auto const& inputEntry : inputData) {
180  requireMatch(inputEntry);
181  }
182  }
183 
185  std::vector<BranchID> const& associationsFromSecondary) {
186  if(associationsFromSecondary.empty()) return;
187 
188  std::vector<std::pair<BranchID, ThinnedAssociationBranches const*> > assocToBranches = helper.associationToBranches();
189 
190  for(BranchID const& association : associationsFromSecondary) {
191 
192  auto branches = std::lower_bound(assocToBranches.begin(), assocToBranches.end(),
193  std::make_pair(association, static_cast<ThinnedAssociationBranches const*>(nullptr)),
194  [](std::pair<BranchID, ThinnedAssociationBranches const*> const& x,
195  std::pair<BranchID, ThinnedAssociationBranches const*> const& y)
196  { return x.first < y.first; });
197  // This should never happen
198  if(branches == assocToBranches.end() || branches->first != association) {
200  "ThinnedAssociationHelper::initAssociationsFromSecondary could not find branches information, contact Framework developers");
201  }
202  requireMatch(*(branches->second));
203  }
204  }
205 
206  void
208  std::map<BranchID, bool> const& keepAssociation,
209  std::map<BranchID::value_type, BranchID::value_type> const& droppedBranchIDToKeptBranchID) {
210  clear();
211  for(auto const& associationBranches : parentThinnedAssociationsHelper.data()) {
212  auto keep = keepAssociation.find(associationBranches.association());
213  if(keep != keepAssociation.end() && keep->second) {
214  BranchID parent = associationBranches.parent();
215  auto iter = droppedBranchIDToKeptBranchID.find(parent.id());
216  if(iter != droppedBranchIDToKeptBranchID.end()) {
217  parent = BranchID(iter->second);
218  }
219  BranchID thinned = associationBranches.thinned();
220  iter = droppedBranchIDToKeptBranchID.find(thinned.id());
221  if(iter != droppedBranchIDToKeptBranchID.end()) {
222  thinned = BranchID(iter->second);
223  }
224  addAssociation(parent, associationBranches.association(), thinned);
225  }
226  }
227  sort();
228  }
229 
230  void
231  ThinnedAssociationsHelper::initAssociationsFromSecondary(std::vector<BranchID> const& associationsFromSecondary,
232  ThinnedAssociationsHelper const& fileAssociationsHelper) {
233  if(associationsFromSecondary.empty()) return;
234 
235  std::vector<std::pair<BranchID, ThinnedAssociationBranches const*> > assocToBranches =
236  fileAssociationsHelper.associationToBranches();
237 
238  for(BranchID const& association : associationsFromSecondary) {
239 
240  auto branches = std::lower_bound(assocToBranches.begin(), assocToBranches.end(),
241  std::make_pair(association, static_cast<ThinnedAssociationBranches const*>(nullptr)),
242  [](std::pair<BranchID, ThinnedAssociationBranches const*> const& x,
243  std::pair<BranchID, ThinnedAssociationBranches const*> const& y)
244  { return x.first < y.first; });
245  // This should never happen
246  if(branches == assocToBranches.end() || branches->first != association) {
248  "ThinnedAssociationHelper::initAssociationsFromSecondary could not find branches information, contact Framework developers");
249  }
250  addAssociation(*(branches->second));
251  }
252  sort();
253  }
254 }
void initAssociationsFromSecondary(std::vector< BranchID > const &, ThinnedAssociationsHelper const &)
std::vector< ThinnedAssociationBranches > const & data() const
Definition: helper.py:1
void addAssociation(BranchID const &, BranchID const &, BranchID const &)
void requireMatch(ThinnedAssociationBranches const &input) const
std::vector< std::pair< BranchID, ThinnedAssociationBranches const * > > associationToBranches() const
unsigned int id() const
Definition: BranchID.h:23
void updateFromPrimaryInput(ThinnedAssociationsHelper const &)
std::vector< ThinnedAssociationBranches >::const_iterator end() const
static std::string const input
Definition: EdmProvDump.cc:48
std::vector< ThinnedAssociationBranches >::const_iterator parentEnd(BranchID const &) const
void selectAssociationProducts(std::vector< BranchDescription const * > const &associationDescriptions, std::set< BranchID > const &keptProductsInEvent, std::map< BranchID, bool > &keepAssociation) const
const int keep
void clear(CLHEP::HepGenMatrix &m)
Helper function: Reset all elements of a matrix to 0.
Definition: matutil.cc:167
void updateFromSecondaryInput(ThinnedAssociationsHelper const &, std::vector< BranchID > const &associationsFromSecondary)
std::vector< ThinnedAssociationBranches >::const_iterator begin() const
std::vector< ThinnedAssociationBranches >::const_iterator parentBegin(BranchID const &) const
void updateFromParentProcess(ThinnedAssociationsHelper const &parentThinnedAssociationsHelper, std::map< BranchID, bool > const &keepAssociation, std::map< BranchID::value_type, BranchID::value_type > const &droppedBranchIDToKeptBranchID)
HLT enums.
bool shouldKeepAssociation(BranchID const &association, std::vector< std::pair< BranchID, ThinnedAssociationBranches const * > > const &associationToBranches, std::set< BranchID > &branchesInRecursion, std::set< BranchID > const &keptProductsInEvent, std::map< BranchID, bool > &keepAssociation) const
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName)