CMS 3D CMS Logo

PileUpSubtractor.cc
Go to the documentation of this file.
1 
3 
8 
14 
15 #include <map>
16 using namespace std;
17 
19  geo_ = nullptr;
20  doAreaFastjet_ = iConfig.getParameter<bool>("doAreaFastjet");
21  doRhoFastjet_ = iConfig.getParameter<bool>("doRhoFastjet");
22  nSigmaPU_ = iConfig.getParameter<double>("nSigmaPU");
23  radiusPU_ = iConfig.getParameter<double>("radiusPU");
24  jetPtMin_ = iConfig.getParameter<double>("jetPtMin");
25  puPtMin_ = iConfig.getParameter<double>("puPtMin");
26  ghostEtaMax = iConfig.getParameter<double>("Ghost_EtaMax");
27  activeAreaRepeats = iConfig.getParameter<int>("Active_Area_Repeats");
28  ghostArea = iConfig.getParameter<double>("GhostArea");
29 
30  if (doAreaFastjet_ || doRhoFastjet_) {
31  fjActiveArea_ = ActiveAreaSpecPtr(new fastjet::ActiveAreaSpec(ghostEtaMax, activeAreaRepeats, ghostArea));
32  if ((ghostEtaMax < 0) || (activeAreaRepeats < 0) || (ghostArea < 0))
33  throw cms::Exception("doAreaFastjet or doRhoFastjet")
34  << "Parameters ghostEtaMax, activeAreaRepeats or ghostArea for doAreaFastjet/doRhoFastjet are not defined."
35  << std::endl;
36  }
37 }
38 
40  std::vector<fastjet::PseudoJet>& towers,
41  std::vector<fastjet::PseudoJet>& output) {
42  inputs_ = &input;
43  fjInputs_ = &towers;
44  fjJets_ = &output;
45  fjOriginalInputs_ = (*fjInputs_);
46  for (unsigned int i = 0; i < fjInputs_->size(); ++i) {
47  fjOriginalInputs_[i].set_user_index((*fjInputs_)[i].user_index());
48  }
49 }
50 
52  fjJetDefinition_ = JetDefPtr(new fastjet::JetDefinition(*jetDef));
53 }
54 
56  LogDebug("PileUpSubtractor") << "The subtractor setting up geometry...\n";
57 
58  if (geo_ == nullptr) {
60  iSetup.get<CaloGeometryRecord>().get(pG);
61  geo_ = pG.product();
62  std::vector<DetId> alldid = geo_->getValidDetIds();
63 
64  int ietaold = -10000;
65  ietamax_ = -10000;
66  ietamin_ = 10000;
67  for (std::vector<DetId>::const_iterator did = alldid.begin(); did != alldid.end(); did++) {
68  if ((*did).det() == DetId::Hcal) {
69  HcalDetId hid = HcalDetId(*did);
70  if ((hid).depth() == 1) {
71  allgeomid_.push_back(*did);
72 
73  if ((hid).ieta() != ietaold) {
74  ietaold = (hid).ieta();
75  geomtowers_[(hid).ieta()] = 1;
76  if ((hid).ieta() > ietamax_)
77  ietamax_ = (hid).ieta();
78  if ((hid).ieta() < ietamin_)
79  ietamin_ = (hid).ieta();
80  } else {
81  geomtowers_[(hid).ieta()]++;
82  }
83  }
84  }
85  }
86  }
87 
88  for (int i = ietamin_; i < ietamax_ + 1; i++) {
89  ntowersWithJets_[i] = 0;
90  }
91 }
92 
93 //
94 // Calculate mean E and sigma from jet collection "coll".
95 //
96 void PileUpSubtractor::calculatePedestal(vector<fastjet::PseudoJet> const& coll) {
97  LogDebug("PileUpSubtractor") << "The subtractor calculating pedestals...\n";
98  map<int, double> emean2;
99  map<int, int> ntowers;
100 
101  int ietaold = -10000;
102  int ieta0 = -100;
103 
104  // Initial values for emean_, emean2, esigma_, ntowers
105 
106  for (int i = ietamin_; i < ietamax_ + 1; i++) {
107  emean_[i] = 0.;
108  emean2[i] = 0.;
109  esigma_[i] = 0.;
110  ntowers[i] = 0;
111  }
112 
113  for (vector<fastjet::PseudoJet>::const_iterator input_object = coll.begin(), fjInputsEnd = coll.end();
114  input_object != fjInputsEnd;
115  ++input_object) {
116  const reco::CandidatePtr& originalTower = (*inputs_)[input_object->user_index()];
117  ieta0 = ieta(originalTower);
118  double Original_Et = originalTower->et();
119  if (ieta0 - ietaold != 0) {
120  emean_[ieta0] = emean_[ieta0] + Original_Et;
121  emean2[ieta0] = emean2[ieta0] + Original_Et * Original_Et;
122  ntowers[ieta0] = 1;
123  ietaold = ieta0;
124  } else {
125  emean_[ieta0] = emean_[ieta0] + Original_Et;
126  emean2[ieta0] = emean2[ieta0] + Original_Et * Original_Et;
127  ntowers[ieta0]++;
128  }
129  }
130 
131  for (map<int, int>::const_iterator gt = geomtowers_.begin(); gt != geomtowers_.end(); gt++) {
132  int it = (*gt).first;
133 
134  double e1 = (*(emean_.find(it))).second;
135  double e2 = (*emean2.find(it)).second;
136  int nt = (*gt).second - (*(ntowersWithJets_.find(it))).second;
137 
138  LogDebug("PileUpSubtractor") << " ieta : " << it << " number of towers : " << nt << " e1 : " << e1 << " e2 : " << e2
139  << "\n";
140  if (nt > 0) {
141  emean_[it] = e1 / nt;
142  double eee = e2 / nt - e1 * e1 / (nt * nt);
143  if (eee < 0.)
144  eee = 0.;
145  esigma_[it] = nSigmaPU_ * sqrt(eee);
146  } else {
147  emean_[it] = 0.;
148  esigma_[it] = 0.;
149  }
150  LogDebug("PileUpSubtractor") << " ieta : " << it << " Pedestals : " << emean_[it] << " " << esigma_[it] << "\n";
151  }
152 }
153 
154 //
155 // Subtract mean and sigma from fjInputs_
156 //
157 void PileUpSubtractor::subtractPedestal(vector<fastjet::PseudoJet>& coll) {
158  LogDebug("PileUpSubtractor") << "The subtractor subtracting pedestals...\n";
159 
160  int it = -100;
161  for (vector<fastjet::PseudoJet>::iterator input_object = coll.begin(), fjInputsEnd = coll.end();
162  input_object != fjInputsEnd;
163  ++input_object) {
164  reco::CandidatePtr const& itow = (*inputs_)[input_object->user_index()];
165 
166  it = ieta(itow);
167 
168  double etnew = itow->et() - (*(emean_.find(it))).second - (*(esigma_.find(it))).second;
169  float mScale = etnew / input_object->Et();
170  if (etnew < 0.)
171  mScale = 0.;
172 
173  math::XYZTLorentzVectorD towP4(input_object->px() * mScale,
174  input_object->py() * mScale,
175  input_object->pz() * mScale,
176  input_object->e() * mScale);
177 
178  int index = input_object->user_index();
179  input_object->reset_momentum(towP4.px(), towP4.py(), towP4.pz(), towP4.energy());
180  input_object->set_user_index(index);
181  }
182 }
183 
184 void PileUpSubtractor::calculateOrphanInput(vector<fastjet::PseudoJet>& orphanInput) {
185  LogDebug("PileUpSubtractor") << "The subtractor calculating orphan input...\n";
186 
187  (*fjInputs_) = fjOriginalInputs_;
188 
189  vector<int> jettowers; // vector of towers indexed by "user_index"
190  vector<pair<int, int> > excludedTowers; // vector of excluded ieta, iphi values
191 
192  vector<fastjet::PseudoJet>::iterator pseudojetTMP = fjJets_->begin(), fjJetsEnd = fjJets_->end();
193  for (; pseudojetTMP != fjJetsEnd; ++pseudojetTMP) {
194  if (pseudojetTMP->perp() < puPtMin_)
195  continue;
196 
197  // find towers within radiusPU_ of this jet
198  for (vector<HcalDetId>::const_iterator im = allgeomid_.begin(); im != allgeomid_.end(); im++) {
199  double dr = reco::deltaR(geo_->getPosition((DetId)(*im)), (*pseudojetTMP));
200  vector<pair<int, int> >::const_iterator exclude =
201  find(excludedTowers.begin(), excludedTowers.end(), pair<int, int>(im->ieta(), im->iphi()));
202  if (dr < radiusPU_ && exclude == excludedTowers.end()) {
203  ntowersWithJets_[(*im).ieta()]++;
204  excludedTowers.push_back(pair<int, int>(im->ieta(), im->iphi()));
205  }
206  }
207  vector<fastjet::PseudoJet>::const_iterator it = fjInputs_->begin(), fjInputsEnd = fjInputs_->end();
208 
209  for (; it != fjInputsEnd; ++it) {
210  int index = it->user_index();
211  int ie = ieta((*inputs_)[index]);
212  int ip = iphi((*inputs_)[index]);
213  vector<pair<int, int> >::const_iterator exclude =
214  find(excludedTowers.begin(), excludedTowers.end(), pair<int, int>(ie, ip));
215  if (exclude != excludedTowers.end()) {
216  jettowers.push_back(index);
217  } //dr < radiusPU_
218  } // initial input collection
219  } // pseudojets
220 
221  //
222  // Create a new collections from the towers not included in jets
223  //
224  for (vector<fastjet::PseudoJet>::const_iterator it = fjInputs_->begin(), fjInputsEnd = fjInputs_->end();
225  it != fjInputsEnd;
226  ++it) {
227  int index = it->user_index();
228  vector<int>::const_iterator itjet = find(jettowers.begin(), jettowers.end(), index);
229  if (itjet == jettowers.end()) {
230  const reco::CandidatePtr& originalTower = (*inputs_)[index];
231  fastjet::PseudoJet orphan(originalTower->px(), originalTower->py(), originalTower->pz(), originalTower->energy());
232  orphan.set_user_index(index);
233 
234  orphanInput.push_back(orphan);
235  }
236  }
237 }
238 
240  LogDebug("PileUpSubtractor") << "The subtractor correcting jets...\n";
241  jetOffset_.clear();
242  using namespace reco;
243 
244  //
245  // Reestimate energy of jet (energy of jet with initial map)
246  //
247  jetOffset_.reserve(fjJets_->size());
248  vector<fastjet::PseudoJet>::iterator pseudojetTMP = fjJets_->begin(), jetsEnd = fjJets_->end();
249  for (; pseudojetTMP != jetsEnd; ++pseudojetTMP) {
250  int ijet = pseudojetTMP - fjJets_->begin();
251  jetOffset_[ijet] = 0;
252 
253  std::vector<fastjet::PseudoJet> towers = fastjet::sorted_by_pt(pseudojetTMP->constituents());
254  double newjetet = 0.;
255  for (vector<fastjet::PseudoJet>::const_iterator ito = towers.begin(), towEnd = towers.end(); ito != towEnd; ++ito) {
256  const reco::CandidatePtr& originalTower = (*inputs_)[ito->user_index()];
257  int it = ieta(originalTower);
258  double Original_Et = originalTower->et();
259  double etnew = Original_Et - (*emean_.find(it)).second - (*esigma_.find(it)).second;
260  if (etnew < 0.)
261  etnew = 0;
262  newjetet = newjetet + etnew;
263  jetOffset_[ijet] += Original_Et - etnew;
264  }
265  double mScale = newjetet / pseudojetTMP->Et();
266  LogDebug("PileUpSubtractor") << "pseudojetTMP->Et() : " << pseudojetTMP->Et() << '\n';
267  LogDebug("PileUpSubtractor") << "newjetet : " << newjetet << '\n';
268  LogDebug("PileUpSubtractor") << "jetOffset_[ijet] : " << jetOffset_[ijet] << '\n';
269  LogDebug("PileUpSubtractor") << "pseudojetTMP->Et() - jetOffset_[ijet] : " << pseudojetTMP->Et() - jetOffset_[ijet]
270  << '\n';
271  LogDebug("PileUpSubtractor") << "Scale is : " << mScale << '\n';
272  int cshist = pseudojetTMP->cluster_hist_index();
273  pseudojetTMP->reset_momentum(pseudojetTMP->px() * mScale,
274  pseudojetTMP->py() * mScale,
275  pseudojetTMP->pz() * mScale,
276  pseudojetTMP->e() * mScale);
277  pseudojetTMP->set_cluster_hist_index(cshist);
278  }
279 }
280 
281 double PileUpSubtractor::getCone(double cone, double eta, double phi, double& et, double& pu) {
282  pu = 0;
283 
284  for (vector<HcalDetId>::const_iterator im = allgeomid_.begin(); im != allgeomid_.end(); im++) {
285  if (im->depth() != 1)
286  continue;
287  const GlobalPoint& point = geo_->getPosition((DetId)(*im));
288  double dr = reco::deltaR(point.eta(), point.phi(), eta, phi);
289  if (dr < cone) {
290  pu += (*emean_.find(im->ieta())).second + (*esigma_.find(im->ieta())).second;
291  }
292  }
293 
294  return pu;
295 }
296 
298  int it = ieta(in);
299  return (*emean_.find(it)).second;
300 }
301 
303  int it = ieta(in);
304  return (*esigma_.find(it)).second;
305 }
306 
308  int it = ieta(in);
309  return (*emean_.find(it)).second + (*esigma_.find(it)).second;
310 }
311 
313  int it = ieta(in);
314 
315  int n = (*(geomtowers_.find(it))).second - (*(ntowersWithJets_.find(it))).second;
316  return n;
317 }
318 
320  int it = ieta(in);
321  int n = (*(ntowersWithJets_.find(it))).second;
322  return n;
323 }
324 
326  int it = 0;
327  const CaloTower* ctc = dynamic_cast<const CaloTower*>(in.get());
328  if (ctc) {
329  it = ctc->id().ieta();
330  } else {
331  throw cms::Exception("Invalid Constituent") << "CaloJet constituent is not of CaloTower type";
332  }
333  return it;
334 }
335 
337  int it = 0;
338  const CaloTower* ctc = dynamic_cast<const CaloTower*>(in.get());
339  if (ctc) {
340  it = ctc->id().iphi();
341  } else {
342  throw cms::Exception("Invalid Constituent") << "CaloJet constituent is not of CaloTower type";
343  }
344  return it;
345 }
346 
#define LogDebug(id)
std::shared_ptr< fastjet::JetDefinition > JetDefPtr
T getParameter(std::string const &) const
virtual void calculateOrphanInput(std::vector< fastjet::PseudoJet > &orphanInput)
virtual double getMeanAtTower(const reco::CandidatePtr &in) const
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
#define EDM_REGISTER_PLUGINFACTORY(_factory_, _category_)
Definition: PluginFactory.h:89
int getNwithJets(const reco::CandidatePtr &in) const
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:139
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
virtual double getPileUpAtTower(const reco::CandidatePtr &in) const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
static std::string const input
Definition: EdmProvDump.cc:48
int ieta(const reco::CandidatePtr &in) const
U second(std::pair< T, U > const &p)
virtual void offsetCorrectJets()
int iEvent
Definition: GenABIO.cc:224
T sqrt(T t)
Definition: SSEVec.h:19
int iphi() const
get the tower iphi
virtual void subtractPedestal(std::vector< fastjet::PseudoJet > &coll)
int nt
Definition: AMPTWrapper.h:42
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
Definition: DetId.h:17
int iphi(const reco::CandidatePtr &in) const
CaloTowerDetId id() const
Definition: CaloTower.h:127
JetCorrectorParametersCollection coll
Definition: classes.h:10
virtual double getSigmaAtTower(const reco::CandidatePtr &in) const
virtual void setDefinition(JetDefPtr const &jetDef)
std::vector< DetId > getValidDetIds() const
Get the list of all valid detector ids.
Definition: CaloGeometry.cc:75
T eta() const
Definition: PV3DBase.h:73
fixed size matrix
std::shared_ptr< fastjet::GhostedAreaSpec > ActiveAreaSpecPtr
T get() const
Definition: EventSetup.h:73
PileUpSubtractor(const edm::ParameterSet &iConfig, edm::ConsumesCollector &&iC)
virtual void calculatePedestal(std::vector< fastjet::PseudoJet > const &coll)
virtual void setupGeometryMap(edm::Event &iEvent, const edm::EventSetup &iSetup)
int ieta() const
get the tower ieta
virtual double getCone(double cone, double eta, double phi, double &et, double &pu)
virtual void reset(std::vector< edm::Ptr< reco::Candidate > > &input, std::vector< fastjet::PseudoJet > &towers, std::vector< fastjet::PseudoJet > &output)
T const * product() const
Definition: ESHandle.h:86
std::shared_ptr< fastjet::JetDefinition > JetDefPtr
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
int getN(const reco::CandidatePtr &in) const