CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
UnifiedSCCollectionProducer.cc
Go to the documentation of this file.
1 // C/C++ headers
2 #include <iostream>
3 #include <vector>
4 #include <memory>
5 
6 // Framework
12 // Reconstruction Classes
22 
23 // Class header file
27 
28 
29 /*
30 UnifiedSCCollectionProducer:
31 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32 
33 Takes as input the cleaned and the uncleaned collection of SC
34 and produces two collections of SC: one with the clean SC, but flagged
35 such that with the algoID value one can identify the SC that are also
36 in the unclean collection and a collection with the unclean only SC.
37 This collection has the algoID enumeration of the SC altered
38 such that:
39 flags = 0 (cleanedOnly) cluster is only in the cleaned collection
40 flags = 100 (common) cluster is common in both collections
41 flags = 200 (uncleanedOnly) cluster is only in the uncleaned collection
42 
43 In that way the user can get hold of objects from the
44 - cleaned collection only if they choose flags < 200
45 - uncleaned collection only if they choose flags >= 100
46 
47 18 Aug 2010
48 Nikolaos Rompotis and Chris Seez - Imperial College London
49 many thanks to David Wardrope, Shahram Rahatlou and Federico Ferri
50 */
51 
52 
54 {
57  // get the parameters
58  // the cleaned collection:
60  consumes<BasicClusterCollection>(ps.getParameter<edm::InputTag>("cleanBcCollection"));
62  consumes<SuperClusterCollection>(ps.getParameter<edm::InputTag>("cleanScCollection"));
63 
64  // the uncleaned collection
66  consumes<BasicClusterCollection>(ps.getParameter<edm::InputTag>("uncleanBcCollection"));
68  consumes<SuperClusterCollection>(ps.getParameter<edm::InputTag>("uncleanScCollection"));
69 
70  // the names of the products to be produced:
71  //
72  // the clean collection: this is as it was before, but labeled
73  bcCollection_ = ps.getParameter<std::string>("bcCollection");
74  scCollection_ = ps.getParameter<std::string>("scCollection");
75  // the unclean only collection: SC unique to the unclean collection
76  bcCollectionUncleanOnly_ = ps.getParameter<std::string>("bcCollectionUncleanOnly");
77  scCollectionUncleanOnly_ = ps.getParameter<std::string>("scCollectionUncleanOnly");
78  // the products:
79  produces< reco::BasicClusterCollection >(bcCollection_);
80  produces< reco::SuperClusterCollection >(scCollection_);
81  produces< reco::BasicClusterCollection >(bcCollectionUncleanOnly_);
82  produces< reco::SuperClusterCollection >(scCollectionUncleanOnly_);
83 
84 }
85 
86 
87 
89  const edm::EventSetup& es)
90 {
91 
92  edm::LogInfo("UnifiedSC")<< ">>>>> Entering UnifiedSCCollectionProducer <<<<<";
93  // get the input collections
94  // __________________________________________________________________________
95  //
96  // cluster collections:
99  //
102 
103  evt.getByToken(cleanScCollection_, pCleanSC);
104  evt.getByToken(cleanBcCollection_, pCleanBC);
105  evt.getByToken(uncleanBcCollection_, pUncleanBC);
106  evt.getByToken(uncleanScCollection_, pUncleanSC);
107 
108  // the collections to be produced ___________________________________________
109  reco::BasicClusterCollection basicClusters;
110  reco::SuperClusterCollection superClusters;
111  //
112  reco::BasicClusterCollection basicClustersUncleanOnly;
113  reco::SuperClusterCollection superClustersUncleanOnly;
114  //
115  // run over the uncleaned SC and check how many of them are matched to
116  // the cleaned ones
117  // if you find a matched one, then keep the info that it is matched
118  // along with which clean SC was matched + its basic clusters
119  // if you find an unmatched one, keep the info and store its basic clusters
120  //
121  //
122  int uncleanSize = pUncleanSC->size();
123  int cleanSize = pCleanSC->size();
124 
125  LogTrace("UnifiedSC") << "Size of Clean Collection: " << cleanSize
126  << ", uncleanSize: " << uncleanSize;
127 
128 
129  // keep the indices
130  std::vector<int> inUncleanOnlyInd; // counting the unclean
131  std::vector<int> inCleanInd; // counting the unclean
132  std::vector<int> inCleanOnlyInd; // counting the clean
133  std::vector<DetId> scUncleanSeedDetId; // counting the unclean
134  std::vector<DetId> scCleanSeedDetId; // counting the clean
135  // ontains the index of the SC that owns that BS
136  // first basic cluster index, second: 0 for unclean and 1 for clean
137  std::vector< std::pair<int, int> > basicClusterOwner;
138  std::vector< std::pair<int, int> > basicClusterOwnerUncleanOnly;
139  // if this basic cluster is a seed it is 1
140  std::vector<int> uncleanBasicClusterIsSeed;
141 
142  // loop over unclean SC _____________________________________________________
143  for (int isc =0; isc< uncleanSize; ++isc) {
144  reco::SuperClusterRef unscRef( pUncleanSC, isc);
145  const std::vector< std::pair<DetId, float> > & uhits = unscRef->hitsAndFractions();
146  int uhitsSize = uhits.size();
147  bool foundTheSame = false;
148  for (int jsc=0; jsc < cleanSize; ++jsc) { // loop over the cleaned SC
149  reco::SuperClusterRef cscRef( pCleanSC, jsc );
150  const std::vector<std::pair<DetId,float> > & chits = cscRef->hitsAndFractions();
151  int chitsSize = chits.size();
152  foundTheSame = false;
153  if (unscRef->seed()->seed()==cscRef->seed()->seed() && chitsSize == uhitsSize) {
154  // if the clusters are exactly the same then because the clustering
155  // algorithm works in a deterministic way, the order of the rechits
156  // will be the same
157  foundTheSame = true;
158  for (int i=0; i< chitsSize; ++i) {
159  if (uhits[i].first != chits[i].first ) {
160  foundTheSame=false;
161  break;
162  }
163  }
164 
165  }
166  if (foundTheSame) { // ok you have found it:
167  // this supercluster belongs to both collections
168  inUncleanOnlyInd.push_back(0);
169  inCleanInd.push_back(jsc); // keeps the index of the clean SC
170  scUncleanSeedDetId.push_back(unscRef->seed()->seed());
171  //
172  // keep its basic clusters:
173  for (reco::CaloCluster_iterator bciter = unscRef->clustersBegin(); bciter != unscRef->clustersEnd(); ++bciter) {
174  // the basic clusters
175  basicClusters.push_back(**bciter);
176  // index of the unclean SC
177  basicClusterOwner.push_back( std::make_pair(isc,0) );
178  }
179  break; // break the loop over unclean sc
180  }
181  }
182  if (not foundTheSame) { // this SC is only in the unclean collection
183  // mark it as unique in the uncleaned
184  inUncleanOnlyInd.push_back(1);
185  scUncleanSeedDetId.push_back(unscRef->seed()->seed());
186  // keep all its basic clusters
187  for (reco::CaloCluster_iterator bciter = unscRef->clustersBegin(); bciter != unscRef->clustersEnd(); ++bciter) {
188  // the basic clusters
189  basicClustersUncleanOnly.push_back(**bciter);
190  basicClusterOwnerUncleanOnly.push_back( std::make_pair(isc,0) );
191  }
192  }
193  } // loop over the unclean SC _______________________________________________
194  //
195  int inCleanSize = inCleanInd.size();
196  //
197  // loop over the clean SC, check that are not in common with the unclean
198  // ones and then store their SC as before ___________________________________
199  for (int jsc =0; jsc< cleanSize; ++jsc) {
200  // check whether this index is already in the common collection
201  bool takenAlready = false;
202  for (int j=0; j< inCleanSize; ++j) {
203  if (jsc == inCleanInd[j]) { takenAlready = true ;break;}
204  }
205  if (takenAlready) {
206  inCleanOnlyInd.push_back(0);
207  scCleanSeedDetId.push_back(DetId(0));
208  continue;
209  }
210  inCleanOnlyInd.push_back(1);
211  reco::SuperClusterRef cscRef( pCleanSC, jsc );
212  scCleanSeedDetId.push_back(cscRef->seed()->seed());
213  for (reco::CaloCluster_iterator bciter = cscRef->clustersBegin(); bciter != cscRef->clustersEnd(); ++bciter) {
214  // the basic clusters
215  basicClusters.push_back(**bciter);
216  basicClusterOwner.push_back( std::make_pair(jsc,1) );
217  }
218  } // end loop over clean SC _________________________________________________
219  //
220  //
221 
222  // Final check: in the endcap BC may exist that are not associated to SC,
223  // we need to recover them as well (e.g. multi5x5 algo)
224  // This is should be optimized (SA, 20110621)
225 
226 
227  // loop on original clean BC collection and see if the BC is missing from the new one
228  for (reco::BasicClusterCollection::const_iterator bc = pCleanBC->begin();
229  bc!=pCleanBC->end();
230  ++bc){
231 
232  bool foundTheSame = false;
233  for (reco::BasicClusterCollection::const_iterator cleanonly_bc = basicClusters.begin();
234  cleanonly_bc!=basicClusters.end();
235  ++cleanonly_bc){
236 
237  const std::vector<std::pair<DetId,float> > & chits = bc->hitsAndFractions();
238  int chitsSize = chits.size();
239 
240  const std::vector<std::pair<DetId,float> > & uhits = cleanonly_bc->hitsAndFractions();
241  int uhitsSize = uhits.size();
242 
243 
244  if (cleanonly_bc->seed()==bc->seed() && chitsSize == uhitsSize) {
245  foundTheSame = true;
246  for (int i=0; i< chitsSize; ++i) {
247  if (uhits[i].first != chits[i].first ) {
248  foundTheSame=false;
249  break;
250  }
251  }
252  }
253 
254  } // loop on new clean BC collection
255 
256  // clean basic cluster is not associated to SC and does not belong to the
257  // new collection, add it
258  if (!foundTheSame){
259  basicClusters.push_back(*bc);
260  LogTrace("UnifiedSC")<<"found BC to add that was not associated to any SC";
261  }
262 
263  } // loop on original clean BC collection
264 
265 
266  // at this point we have the basic cluster collection ready
267  // Up to index basicClusterOwner.size() we have the BC owned by a SC
268  // The remaining are BCs not owned by a SC
269 
270  int bcSize = (int) basicClusterOwner.size();
271  int bcSizeUncleanOnly = (int) basicClustersUncleanOnly.size();
272 
273  LogTrace("UnifiedSC") << "Found cleaned SC: " << cleanSize
274  << " uncleaned SC: " << uncleanSize ;
275  //
276  // export the clusters to the event from the clean clusters
277  std::auto_ptr< reco::BasicClusterCollection>
278  basicClusters_p(new reco::BasicClusterCollection);
279  basicClusters_p->assign(basicClusters.begin(), basicClusters.end());
281  evt.put(basicClusters_p, bcCollection_);
282  if (!(bccHandle.isValid())) {
283 
284  edm::LogWarning("MissingInput")<< "could not handle the new BasicClusters!";
285  return;
286  }
287  reco::BasicClusterCollection basicClustersProd = *bccHandle;
288 
289  LogTrace("UnifiedSC")<< "Got the BasicClusters from the event again" ;
290  //
291  // export the clusters to the event: from the unclean only clusters
292  std::auto_ptr< reco::BasicClusterCollection>
293  basicClustersUncleanOnly_p(new reco::BasicClusterCollection);
294  basicClustersUncleanOnly_p->assign(basicClustersUncleanOnly.begin(),
295  basicClustersUncleanOnly.end());
297  evt.put(basicClustersUncleanOnly_p, bcCollectionUncleanOnly_);
298  if (!(bccHandleUncleanOnly.isValid())) {
299 
300  edm::LogWarning("MissingInput")<< "could not handle the new BasicClusters (Unclean Only)!" ;
301  return;
302  }
303  reco::BasicClusterCollection basicClustersUncleanOnlyProd = *bccHandleUncleanOnly;
304  LogTrace("UnifiedSC")<< "Got the BasicClusters from the event again (Unclean Only)" ;
305  //
306 
307  // now we can build the SC collection
308  //
309  // start again from the unclean collection
310  // all the unclean SC will become members of the new collection
311  // with different algoIDs ___________________________________________________
312  for (int isc=0; isc< uncleanSize; ++isc) {
313  reco::CaloClusterPtrVector clusterPtrVector;
314  // the seed is the basic cluster with the highest energy
316  if (inUncleanOnlyInd[isc] == 1) { // unclean SC Unique in Unclean
317  for (int jbc=0; jbc< bcSizeUncleanOnly; ++jbc) {
318  std::pair<int, int> theBcOwner = basicClusterOwnerUncleanOnly[jbc];
319  if (theBcOwner.first == isc && theBcOwner.second == 0) {
320  reco::CaloClusterPtr currentClu=reco::CaloClusterPtr(bccHandleUncleanOnly,jbc);
321  clusterPtrVector.push_back(currentClu);
322  if (scUncleanSeedDetId[isc] == currentClu->seed()) {
323  seed = currentClu;
324  }
325  }
326  }
327 
328  }
329  else { // unclean SC common in clean and unclean
330  for (int jbc=0; jbc< bcSize; ++jbc) {
331  std::pair<int, int> theBcOwner = basicClusterOwner[jbc];
332  if (theBcOwner.first == isc && theBcOwner.second == 0) {
333  reco::CaloClusterPtr currentClu=reco::CaloClusterPtr(bccHandle,jbc);
334  clusterPtrVector.push_back(currentClu);
335  if (scUncleanSeedDetId[isc] == currentClu->seed()) {
336  seed = currentClu;
337  }
338  }
339  }
340  }
341  //std::cout << "before getting the uncl" << std::endl;
342  reco::SuperClusterRef unscRef( pUncleanSC, isc );
343  reco::SuperCluster newSC(unscRef->energy(), unscRef->position(),
344  seed, clusterPtrVector );
345  // now set the algoID for this SC again
346  if (inUncleanOnlyInd[isc] == 1) {
347  // set up the quality to unclean only .............
349  superClustersUncleanOnly.push_back(newSC);
350  }
351  else {
352  // set up the quality to common .............
353  newSC.setFlags(reco::CaloCluster::common);
354  superClusters.push_back(newSC);
355  }
356  // now you can store your SC
357 
358  } // end loop over unclean SC _______________________________________________
359  // flags numbering scheme
360  // flags = 0 = cleanedOnly cluster is only in the cleaned collection
361  // flags = 100 = common cluster is common in both collections
362  // flags = 200 = uncleanedOnly cluster is only in the uncleaned collection
363 
364  // now loop over the clean SC and do the same but now you have to avoid the
365  // the duplicated ones ______________________________________________________
366  for (int jsc=0; jsc< cleanSize; ++jsc) {
367  //std::cout << "working in cl #" << jsc << std::endl;
368  // check that the SC is not in the unclean collection
369  if (inCleanOnlyInd[jsc] == 0) continue;
370  reco::CaloClusterPtrVector clusterPtrVector;
371  // the seed is the basic cluster with the highest energy
373  for (int jbc=0; jbc< bcSize; ++jbc) {
374  std::pair<int, int> theBcOwner = basicClusterOwner[jbc];
375  if (theBcOwner.first == jsc && theBcOwner.second == 1) {
376  reco::CaloClusterPtr currentClu=reco::CaloClusterPtr(bccHandle,jbc);
377  clusterPtrVector.push_back(currentClu);
378  if (scCleanSeedDetId[jsc] == currentClu->seed()) {
379  seed = currentClu;
380  }
381  }
382  }
383  reco::SuperClusterRef cscRef( pCleanSC, jsc );
384  reco::SuperCluster newSC(cscRef->energy(), cscRef->position(),
385  seed, clusterPtrVector );
387 
388  // add it to the collection:
389  superClusters.push_back(newSC);
390 
391  } // end loop over clean SC _________________________________________________
392 
393 
394 
395 
396 
397 
398 
399  LogTrace("UnifiedSC")<< "New SC collection was created";
400 
401  std::auto_ptr< reco::SuperClusterCollection>
402  superClusters_p(new reco::SuperClusterCollection);
403  superClusters_p->assign(superClusters.begin(), superClusters.end());
404 
405  evt.put(superClusters_p, scCollection_);
406 
407  LogTrace("UnifiedSC") << "Clusters (Basic/Super) added to the Event! :-)";
408 
409  std::auto_ptr< reco::SuperClusterCollection>
410  superClustersUncleanOnly_p(new reco::SuperClusterCollection);
411  superClustersUncleanOnly_p->assign(superClustersUncleanOnly.begin(),
412  superClustersUncleanOnly.end());
413 
414  evt.put(superClustersUncleanOnly_p, scCollectionUncleanOnly_);
415 
416  // ----- debugging ----------
417  // print the new collection SC quantities
418 
419  // print out the clean collection SC
420  LogTrace("UnifiedSC") << "Clean Collection SC ";
421  for (int i=0; i < cleanSize; ++i) {
422  reco::SuperClusterRef cscRef( pCleanSC, i );
423  LogTrace("UnifiedSC") << " >>> clean #" << i << "; Energy: " << cscRef->energy()
424  << " eta: " << cscRef->eta()
425  << " sc seed detid: " << cscRef->seed()->seed().rawId()
426  << std::endl;
427  }
428  // the unclean SC
429  LogTrace("UnifiedSC") << "Unclean Collection SC ";
430  for (int i=0; i < uncleanSize; ++i) {
431  reco::SuperClusterRef uscRef( pUncleanSC, i );
432  LogTrace("UnifiedSC") << " >>> unclean #" << i << "; Energy: " << uscRef->energy()
433  << " eta: " << uscRef->eta()
434  << " sc seed detid: " << uscRef->seed()->seed().rawId();
435  }
436  // the new collection
437  LogTrace("UnifiedSC")<< "The new SC clean collection with size "<< superClusters.size() << std::endl;
438 
439  int new_unclean = 0, new_clean=0;
440  for (int i=0; i < (int) superClusters.size(); ++i) {
441  const reco::SuperCluster & nsc = superClusters[i];
442  LogTrace("UnifiedSC") << "SC was got" << std::endl
443  << " ---> energy: " << nsc.energy() << std::endl
444  << " ---> eta: " << nsc.eta() << std::endl
445  << " ---> inClean: " << nsc.isInClean() << std::endl
446  << " ---> id: " << nsc.seed()->seed().rawId() << std::endl
447  << " >>> newSC #" << i << "; Energy: " << nsc.energy()
448  << " eta: " << nsc.eta() << " isClean="
449  << nsc.isInClean() << " isUnclean=" << nsc.isInUnclean()
450  << " sc seed detid: " << nsc.seed()->seed().rawId();
451 
452  if (nsc.isInUnclean()) ++new_unclean;
453  if (nsc.isInClean()) ++new_clean;
454  }
455  LogTrace("UnifiedSC")<< "The new SC unclean only collection with size "<< superClustersUncleanOnly.size();
456  for (int i=0; i < (int) superClustersUncleanOnly.size(); ++i) {
457  const reco::SuperCluster nsc = superClustersUncleanOnly[i];
458  LogTrace ("UnifiedSC") << " >>> newSC #" << i << "; Energy: " << nsc.energy()
459  << " eta: " << nsc.eta() << " isClean="
460  << nsc.isInClean() << " isUnclean=" << nsc.isInUnclean()
461  << " sc seed detid: " << nsc.seed()->seed().rawId();
462  if (nsc.isInUnclean()) ++new_unclean;
463  if (nsc.isInClean()) ++new_clean;
464  }
465  if ( (new_unclean != uncleanSize) || (new_clean != cleanSize) ) {
466  LogTrace("UnifiedSC") << ">>>>!!!!!! MISMATCH: new unclean/ old unclean= "
467  << new_unclean << " / " << uncleanSize
468  << ", new clean/ old clean" << new_clean << " / " << cleanSize;
469  }
470 
471 }
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
edm::EDGetTokenT< reco::SuperClusterCollection > uncleanScCollection_
bool isInUnclean() const
Definition: CaloCluster.h:181
virtual void produce(edm::Event &, const edm::EventSetup &)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:464
void push_back(Ptr< T > const &iPtr)
Definition: PtrVector.h:141
edm::Ptr< CaloCluster > CaloClusterPtr
double eta() const
pseudorapidity of cluster centroid
Definition: CaloCluster.h:163
void setFlags(uint32_t flags)
Definition: CaloCluster.h:176
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:120
int j
Definition: DBlmapReader.cc:9
double energy() const
cluster energy
Definition: CaloCluster.h:121
edm::EDGetTokenT< reco::BasicClusterCollection > uncleanBcCollection_
#define LogTrace(id)
bool isInClean() const
Definition: CaloCluster.h:180
edm::EDGetTokenT< reco::SuperClusterCollection > cleanScCollection_
edm::EDGetTokenT< reco::BasicClusterCollection > cleanBcCollection_
Definition: DetId.h:18
std::vector< BasicCluster > BasicClusterCollection
collection of BasicCluster objects
UnifiedSCCollectionProducer(const edm::ParameterSet &ps)
const CaloClusterPtr & seed() const
seed BasicCluster
Definition: SuperCluster.h:66