CMS 3D CMS Logo

CleanAndMergeProducer.cc
Go to the documentation of this file.
27 
28 #include <iostream>
29 #include <memory>
30 #include <vector>
31 
33 public:
35 
36  ~CleanAndMergeProducer() override;
37 
38  void produce(edm::Event&, const edm::EventSetup&) override;
39 
40 private:
43 
44  // the names of the products to be produced:
48 };
49 
52 
53 /*
54 CleanAndMergeProducer:
55 ^^^^^^^^^^^^^^^^^^^^^^
56 
57 Takes as input the cleaned and the uncleaned collection of SC
58 and produces an uncleaned collection of SC without the duplicates
59 and a collection of references to the cleaned collection of SC
60 
61 25 June 2010
62 Nikolaos Rompotis and Chris Seez - Imperial College London
63 many thanks to Shahram Rahatlou and Federico Ferri
64 
65 
66 */
67 
69  // get the parameters
70  // the cleaned collection:
71  cleanScToken_ = consumes<reco::SuperClusterCollection>(ps.getParameter<edm::InputTag>("cleanScInputTag"));
72  uncleanScToken_ = consumes<reco::SuperClusterCollection>(ps.getParameter<edm::InputTag>("uncleanScInputTag"));
73 
74  // the names of the products to be produced:
75  bcCollection_ = ps.getParameter<std::string>("bcCollection");
76  scCollection_ = ps.getParameter<std::string>("scCollection");
77  refScCollection_ = ps.getParameter<std::string>("refScCollection");
78 
79  std::map<std::string, double> providedParameters;
80  providedParameters.insert(std::make_pair("LogWeighted", ps.getParameter<bool>("posCalc_logweight")));
81  providedParameters.insert(std::make_pair("T0_barl", ps.getParameter<double>("posCalc_t0")));
82  providedParameters.insert(std::make_pair("W0", ps.getParameter<double>("posCalc_w0")));
83  providedParameters.insert(std::make_pair("X0", ps.getParameter<double>("posCalc_x0")));
84 
85  // the products:
86  produces<reco::BasicClusterCollection>(bcCollection_);
87  produces<reco::SuperClusterCollection>(scCollection_);
88  produces<reco::SuperClusterRefVector>(refScCollection_);
89 }
90 
92 
94  // get the input collections
95  // ______________________________________________________________________________________
96  //
97  // cluster collections:
98 
101 
102  evt.getByToken(cleanScToken_, pCleanSC);
103  evt.getByToken(uncleanScToken_, pUncleanSC);
104 
105  //
106  // collections are all taken now _____________________________________________________
107  //
108  //
109  // the collections to be produced:
110  reco::BasicClusterCollection basicClusters;
113 
114  //
115  // run over the uncleaned SC and check how many of them are matched to the cleaned ones
116  // if you find a matched one, create a reference to the cleaned collection and store it
117  // if you find an unmatched one, then keep all its basic clusters in the basic Clusters
118  // vector
119  int uncleanSize = pUncleanSC->size();
120  int cleanSize = pCleanSC->size();
121 
122  LogTrace("EcalCleaning") << "Size of Clean Collection: " << cleanSize << ", uncleanSize: " << uncleanSize
123  << std::endl;
124  //
125  // keep whether the SC in unique in the uncleaned collection
126  std::vector<int> isUncleanOnly; // 1 if unique in the uncleaned
127  std::vector<int> basicClusterOwner; // contains the index of the SC that owns that BS
128  std::vector<int> isSeed; // if this basic cluster is a seed it is 1
129  for (int isc = 0; isc < uncleanSize; ++isc) {
130  reco::SuperClusterRef unscRef(pUncleanSC, isc);
131  const std::vector<std::pair<DetId, float> >& uhits = unscRef->hitsAndFractions();
132  int uhitsSize = uhits.size();
133  bool foundTheSame = false;
134  for (int jsc = 0; jsc < cleanSize; ++jsc) { // loop over the cleaned SC
135  reco::SuperClusterRef cscRef(pCleanSC, jsc);
136  const std::vector<std::pair<DetId, float> >& chits = cscRef->hitsAndFractions();
137  int chitsSize = chits.size();
138  foundTheSame = true;
139  if (unscRef->seed()->seed() == cscRef->seed()->seed() && chitsSize == uhitsSize) {
140  // if the clusters are exactly the same then because the clustering
141  // algorithm works in a deterministic way, the order of the rechits
142  // will be the same
143  for (int i = 0; i < chitsSize; ++i) {
144  if (uhits[i].first != chits[i].first) {
145  foundTheSame = false;
146  break;
147  }
148  }
149  if (foundTheSame) { // ok you have found it!
150  // make the reference
151  //scRefs->push_back( edm::Ref<reco::SuperClusterCollection>(pCleanSC, jsc) );
152  scRefs->push_back(cscRef);
153  isUncleanOnly.push_back(0);
154  break;
155  }
156  }
157  }
158  if (not foundTheSame) {
159  // mark it as unique in the uncleaned
160  isUncleanOnly.push_back(1);
161  // keep all its basic clusters
162  for (reco::CaloCluster_iterator bciter = unscRef->clustersBegin(); bciter != unscRef->clustersEnd(); ++bciter) {
163  // the basic clusters
164  basicClusters.push_back(**bciter);
165  basicClusterOwner.push_back(isc);
166  }
167  }
168  }
169  int bcSize = basicClusters.size();
170 
171  LogDebug("EcalCleaning") << "Found cleaned SC: " << cleanSize << " uncleaned SC: " << uncleanSize << " from which "
172  << scRefs->size() << " will become refs to the cleaned collection";
173 
174  // now you have the collection of basic clusters of the SC to be remain in the
175  // in the clean collection, export them to the event
176  // you will need to reread them later in order to make correctly the refs to the SC
177  auto basicClusters_p = std::make_unique<reco::BasicClusterCollection>();
178  basicClusters_p->assign(basicClusters.begin(), basicClusters.end());
180  if (!(bccHandle.isValid())) {
181  edm::LogWarning("MissingInput") << "could not get a handle on the BasicClusterCollection!" << std::endl;
182  return;
183  }
184 
185  LogDebug("EcalCleaning") << "Got the BasicClusters from the event again";
186  // now you have to create again your superclusters
187  // you run over the uncleaned SC, but now you know which of them are
188  // the ones that are needed and which are their basic clusters
189  for (int isc = 0; isc < uncleanSize; ++isc) {
190  if (isUncleanOnly[isc] == 1) { // look for sc that are unique in the unclean collection
191  // make the basic cluster collection
192  reco::CaloClusterPtrVector clusterPtrVector;
193  reco::CaloClusterPtr seed; // the seed is the basic cluster with the highest energy
194  double energy = -1;
195  for (int jbc = 0; jbc < bcSize; ++jbc) {
196  if (basicClusterOwner[jbc] == isc) {
197  reco::CaloClusterPtr currentClu = reco::CaloClusterPtr(bccHandle, jbc);
198  clusterPtrVector.push_back(currentClu);
199  if (energy < currentClu->energy()) {
200  energy = currentClu->energy();
201  seed = currentClu;
202  }
203  }
204  }
205  reco::SuperClusterRef unscRef(pUncleanSC, isc);
206  reco::SuperCluster newSC(unscRef->energy(), unscRef->position(), seed, clusterPtrVector);
207  superClusters.push_back(newSC);
208  }
209  }
210  // export the collection of references to the clean collection
211  std::unique_ptr<reco::SuperClusterRefVector> scRefs_p(scRefs);
212  evt.put(std::move(scRefs_p), refScCollection_);
213 
214  // the collection of basic clusters is already in the event
215  // the collection of uncleaned SC
216  auto superClusters_p = std::make_unique<reco::SuperClusterCollection>();
217  superClusters_p->assign(superClusters.begin(), superClusters.end());
218  evt.put(std::move(superClusters_p), scCollection_);
219  LogDebug("EcalCleaning") << "Hybrid Clusters (Basic/Super) added to the Event! :-)";
220 }
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
void push_back(Ptr< T > const &iPtr)
Definition: PtrVector.h:149
edm::EDGetTokenT< reco::SuperClusterCollection > uncleanScToken_
void produce(edm::Event &, const edm::EventSetup &) override
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:528
edm::Ptr< CaloCluster > CaloClusterPtr
#define LogTrace(id)
edm::EDGetTokenT< reco::SuperClusterCollection > cleanScToken_
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
size_type size() const
Size of the RefVector.
Definition: RefVector.h:102
std::vector< BasicCluster > BasicClusterCollection
collection of BasicCluster objects
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
Definition: RefVector.h:67
Log< level::Warning, false > LogWarning
edm::RefVector< SuperClusterCollection > SuperClusterRefVector
vector of references to objects in the same colletion of SuperCluster objects
CleanAndMergeProducer(const edm::ParameterSet &ps)
def move(src, dest)
Definition: eostools.py:511
#define LogDebug(id)