CMS 3D CMS Logo

HGCalShowerSeparation.cc
Go to the documentation of this file.
1 // user include files
2 
6 
9 
11 
13 
20 
25 
28 
30 
31 #include <map>
32 #include <array>
33 #include <string>
34 #include <numeric>
35 
37 public:
39  ~HGCalShowerSeparation() override = default;
40 
41  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
42 
43 private:
44  void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
45  void analyze(const edm::Event&, const edm::EventSetup&) override;
46 
47  void fillWithRecHits(std::unordered_map<DetId, const HGCRecHit*>&, DetId, unsigned int, float, int&, float&);
48 
52 
53  int debug_;
56 
68  std::vector<MonitorElement*> profileOnLayer_;
69  std::vector<MonitorElement*> globalProfileOnLayer_;
70  std::vector<MonitorElement*> distanceOnLayer_;
71  std::vector<MonitorElement*> idealDistanceOnLayer_;
72  std::vector<MonitorElement*> idealDeltaXY_;
73  std::vector<MonitorElement*> centers_;
74 
75  static constexpr int layers_ = 52;
76 };
77 
80  debug_(iConfig.getParameter<int>("debug")),
81  filterOnEnergyAndCaloP_(iConfig.getParameter<bool>("filterOnEnergyAndCaloP")) {
82  auto hitMapInputTag = iConfig.getParameter<edm::InputTag>("hitMapTag");
83  auto caloParticles = iConfig.getParameter<edm::InputTag>("caloParticles");
84  hitMap_ = consumes<std::unordered_map<DetId, const HGCRecHit*>>(hitMapInputTag);
85  caloParticles_ = consumes<std::vector<CaloParticle>>(caloParticles);
86 }
87 
89  ibooker.cd();
90  ibooker.setCurrentFolder("HGCalShowerSeparation");
91  scEnergy_ = ibooker.book1D("SCEnergy", "SCEnergy", 240, 0., 120.);
92  eta1_ = ibooker.book1D("eta1", "eta1", 80, 0., 4.);
93  eta2_ = ibooker.book1D("eta2", "eta2", 80, 0., 4.);
94  energy1_ = ibooker.book1D("energy1", "energy1", 240, 0., 120.);
95  energy2_ = ibooker.book1D("energy2", "energy2", 240, 0., 120.);
96  energytot_ = ibooker.book1D("energytot", "energytot", 200, 100., 200.);
97  showerProfile_ = ibooker.book2D("ShowerProfile", "ShowerProfile", 800, -400., 400., layers_, 0., (float)layers_);
98  layerEnergy_ = ibooker.book2D("LayerEnergy", "LayerEnergy", 60, 0., 60., 50, 0., 0.1);
99  layerDistance_ = ibooker.book2D("LayerDistance", "LayerDistance", 60, 0., 60., 400, -400., 400.);
100  etaPhi_ = ibooker.book2D("EtaPhi", "EtaPhi", 800, -4., 4., 800, -4., 4.);
101  deltaEtaPhi_ = ibooker.book2D("DeltaEtaPhi", "DeltaEtaPhi", 100, -0.5, 0.5, 100, -0.5, 0.5);
102  for (int i = 0; i < layers_; ++i) {
103  profileOnLayer_.push_back(ibooker.book2D(std::string("ProfileOnLayer_") + std::to_string(i),
104  std::string("ProfileOnLayer_") + std::to_string(i),
105  120,
106  -600.,
107  600.,
108  120,
109  -600.,
110  600.));
111  globalProfileOnLayer_.push_back(ibooker.book2D(std::string("GlobalProfileOnLayer_") + std::to_string(i),
112  std::string("GlobalProfileOnLayer_") + std::to_string(i),
113  320,
114  -160.,
115  160.,
116  320,
117  -160.,
118  160.));
119  distanceOnLayer_.push_back(ibooker.book1D(std::string("DistanceOnLayer_") + std::to_string(i),
120  std::string("DistanceOnLayer_") + std::to_string(i),
121  120,
122  -600.,
123  600.));
124  idealDistanceOnLayer_.push_back(ibooker.book1D(std::string("IdealDistanceOnLayer_") + std::to_string(i),
125  std::string("IdealDistanceOnLayer_") + std::to_string(i),
126  120,
127  -600.,
128  600.));
129  idealDeltaXY_.push_back(ibooker.book2D(std::string("IdealDeltaXY_") + std::to_string(i),
130  std::string("IdealDeltaXY_") + std::to_string(i),
131  800,
132  -400.,
133  400.,
134  800,
135  -400.,
136  400.));
137  centers_.push_back(ibooker.book2D(std::string("Centers_") + std::to_string(i),
138  std::string("Centers_") + std::to_string(i),
139  320,
140  -1600.,
141  1600.,
142  320,
143  -1600.,
144  1600.));
145  }
146 }
147 
150 
151  const edm::Handle<std::vector<CaloParticle>>& caloParticleHandle = iEvent.getHandle(caloParticles_);
152  const std::vector<CaloParticle>& caloParticles = *(caloParticleHandle.product());
153 
155  iEvent.getByToken(hitMap_, hitMapHandle);
156  const auto hitmap = *hitMapHandle;
157 
158  // loop over caloParticles
159  IfLogTrace(debug_ > 0, "HGCalShowerSeparation") << "Number of caloParticles: " << caloParticles.size() << std::endl;
160  if (caloParticles.size() == 2) {
161  auto eta1 = caloParticles[0].eta();
162  auto phi1 = caloParticles[0].phi();
163  auto theta1 = 2. * std::atan(exp(-eta1));
164  auto eta2 = caloParticles[1].eta();
165  auto phi2 = caloParticles[1].phi();
166  auto theta2 = 2. * std::atan(exp(-eta2));
167  eta1_->Fill(eta1);
168  eta2_->Fill(eta2);
169 
170  // Select event only if the sum of the energy of its recHits
171  // is close enough to the gen energy
172  int count = 0;
173  int size = 0;
174  float energy = 0.;
175  float energy_tmp = 0.;
176  for (const auto& it_caloPart : caloParticles) {
177  count++;
178  const SimClusterRefVector& simClusterRefVector = it_caloPart.simClusters();
179  size += simClusterRefVector.size();
180  for (const auto& it_sc : simClusterRefVector) {
181  const SimCluster& simCluster = (*(it_sc));
182  const std::vector<std::pair<uint32_t, float>>& hits_and_fractions = simCluster.hits_and_fractions();
183  for (const auto& it_haf : hits_and_fractions) {
184  if (hitmap.count(it_haf.first))
185  energy += hitmap.at(it_haf.first)->energy() * it_haf.second;
186  } //hits and fractions
187  } // simcluster
188  if (count == 1) {
189  energy1_->Fill(energy);
190  energy_tmp = energy;
191  } else {
192  energy2_->Fill(energy - energy_tmp);
193  }
194  } // caloParticle
196  if (filterOnEnergyAndCaloP_ && (energy < 2. * 0.8 * 80 or size != 2))
197  return;
198 
199  deltaEtaPhi_->Fill(eta1 - eta2, phi1 - phi2);
200 
201  for (const auto& it_caloPart : caloParticles) {
202  const SimClusterRefVector& simClusterRefVector = it_caloPart.simClusters();
203  IfLogTrace(debug_ > 0, "HGCalShowerSeparation") << ">>> " << simClusterRefVector.size() << std::endl;
204  for (const auto& it_sc : simClusterRefVector) {
205  const SimCluster& simCluster = (*(it_sc));
206  if (simCluster.energy() < 80 * 0.8)
207  continue;
208  scEnergy_->Fill(simCluster.energy());
209  IfLogTrace(debug_ > 1, "HGCalShowerSeparation")
210  << ">>> SC.energy(): " << simCluster.energy() << " SC.simEnergy(): " << simCluster.simEnergy() << std::endl;
211  const std::vector<std::pair<uint32_t, float>>& hits_and_fractions = simCluster.hits_and_fractions();
212 
213  for (const auto& it_haf : hits_and_fractions) {
214  if (!hitmap.count(it_haf.first))
215  continue;
216  unsigned int hitlayer = recHitTools_.getLayerWithOffset(it_haf.first);
217  auto global = recHitTools_.getPosition(it_haf.first);
218  float globalx = global.x();
219  float globaly = global.y();
220  float globalz = global.z();
221  if (globalz == 0)
222  continue;
223  auto rho1 = globalz * tan(theta1);
224  auto rho2 = globalz * tan(theta2);
225  auto x1 = rho1 * cos(phi1);
226  auto y1 = rho1 * sin(phi1);
227  auto x2 = rho2 * cos(phi2);
228  auto y2 = rho2 * sin(phi2);
229  auto half_point_x = (x1 + x2) / 2.;
230  auto half_point_y = (y1 + y2) / 2.;
231  auto half_point = sqrt((x1 - half_point_x) * (x1 - half_point_x) + (y1 - half_point_y) * (y1 - half_point_y));
232  auto d_len = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
233  auto dn_x = (x2 - x1) / d_len;
234  auto dn_y = (y2 - y1) / d_len;
235  auto distance = (globalx - x1) * dn_x + (globaly - y1) * dn_y;
236  distance -= half_point;
237  auto idealDistance = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
238  if (hitmap.count(it_haf.first)) {
239  profileOnLayer_[hitlayer]->Fill(10. * (globalx - half_point_x),
240  10. * (globaly - half_point_y),
241  hitmap.at(it_haf.first)->energy() * it_haf.second);
242  profileOnLayer_[55]->Fill(10. * (globalx - half_point_x),
243  10. * (globaly - half_point_y),
244  hitmap.at(it_haf.first)->energy() * it_haf.second);
245  globalProfileOnLayer_[hitlayer]->Fill(globalx, globaly, hitmap.at(it_haf.first)->energy() * it_haf.second);
246  globalProfileOnLayer_[55]->Fill(globalx, globaly, hitmap.at(it_haf.first)->energy() * it_haf.second);
247  layerEnergy_->Fill(hitlayer, hitmap.at(it_haf.first)->energy());
248  layerDistance_->Fill(hitlayer, std::abs(10. * distance), hitmap.at(it_haf.first)->energy() * it_haf.second);
249  etaPhi_->Fill(global.eta(), global.phi());
250  distanceOnLayer_[hitlayer]->Fill(10. * distance); //,
251  idealDistanceOnLayer_[hitlayer]->Fill(10. * idealDistance); //,
252  idealDeltaXY_[hitlayer]->Fill(10. * (x1 - x2), 10. * (y1 - y2)); //,
253  centers_[hitlayer]->Fill(10. * half_point_x, 10. * half_point_y); //,
254  IfLogTrace(debug_ > 0, "HGCalShowerSeparation")
255  << ">>> " << distance << " " << hitlayer << " " << hitmap.at(it_haf.first)->energy() * it_haf.second
256  << std::endl;
257  showerProfile_->Fill(10. * distance, hitlayer, hitmap.at(it_haf.first)->energy() * it_haf.second);
258  }
259  } // end simHit
260  } // end simCluster
261  } // end caloparticle
262  }
263 }
264 
265 // ------------ method fills 'descriptions' with the allowed parameters for the
266 // module ------------
269  desc.add<int>("debug", 1);
270  desc.add<bool>("filterOnEnergyAndCaloP", false);
271  desc.add<edm::InputTag>("caloParticles", edm::InputTag("mix", "MergedCaloTruth"));
272  desc.add<edm::InputTag>("hitMapTag", edm::InputTag("hgcalRecHitMapProducer"));
273  descriptions.add("hgcalShowerSeparationDefault", desc);
274 }
275 
276 // define this as a plug-in
size
Write out results.
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
#define IfLogTrace(cond, cat)
const edm::ESGetToken< CaloGeometry, CaloGeometryRecord > tok_geom_
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
edm::EDGetTokenT< std::unordered_map< DetId, const HGCRecHit * > > hitMap_
T const * product() const
Definition: Handle.h:70
static constexpr int layers_
std::vector< MonitorElement * > globalProfileOnLayer_
~HGCalShowerSeparation() override=default
std::vector< MonitorElement * > idealDeltaXY_
std::vector< std::pair< uint32_t, float > > hits_and_fractions() const
Returns list of rechit IDs and fractions for this SimCluster.
Definition: SimCluster.h:184
float simEnergy() const
returns the accumulated sim energy in the cluster
Definition: SimCluster.h:213
static std::string to_string(const XMLCh *ch)
std::vector< MonitorElement * > profileOnLayer_
void Fill(long long x)
T x() const
Definition: PV3DBase.h:59
int iEvent
Definition: GenABIO.cc:224
void fillWithRecHits(std::unordered_map< DetId, const HGCRecHit *> &, DetId, unsigned int, float, int &, float &)
Monte Carlo truth information used for tracking validation.
Definition: SimCluster.h:29
GlobalPoint getPosition(const DetId &id) const
Definition: RecHitTools.cc:140
T sqrt(T t)
Definition: SSEVec.h:19
edm::EDGetTokenT< std::vector< CaloParticle > > caloParticles_
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
std::vector< MonitorElement * > distanceOnLayer_
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Definition: DetId.h:17
size_type size() const
Size of the RefVector.
Definition: RefVector.h:102
hgcal::RecHitTools recHitTools_
MonitorElement * layerDistance_
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:221
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void analyze(const edm::Event &, const edm::EventSetup &) override
void setGeometry(CaloGeometry const &)
Definition: RecHitTools.cc:79
float energy() const
Energy. Note this is taken from the first SimTrack only.
Definition: SimCluster.h:104
std::vector< MonitorElement * > centers_
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
std::vector< MonitorElement * > idealDistanceOnLayer_
MonitorElement * showerProfile_
Definition: Run.h:45
HGCalShowerSeparation(const edm::ParameterSet &)
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:376