CMS 3D CMS Logo

HGCalShowerSeparation.cc
Go to the documentation of this file.
1 // user include files
2 
6 
9 
11 
13 
16 
23 
28 
34 
36 
37 #include <map>
38 #include <array>
39 #include <string>
40 #include <numeric>
41 
43 public:
45  ~HGCalShowerSeparation() override;
46 
47  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
48 
49 private:
50  void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
51  void analyze(const edm::Event&, const edm::EventSetup&) override;
52 
53  void fillWithRecHits(std::unordered_map<DetId, const HGCRecHit*>&, DetId, unsigned int, float, int&, float&);
54 
58 
59  int debug_;
62 
74  std::vector<MonitorElement*> profileOnLayer_;
75  std::vector<MonitorElement*> globalProfileOnLayer_;
76  std::vector<MonitorElement*> distanceOnLayer_;
77  std::vector<MonitorElement*> idealDistanceOnLayer_;
78  std::vector<MonitorElement*> idealDeltaXY_;
79  std::vector<MonitorElement*> centers_;
80 
81  static constexpr int layers_ = 52;
82 };
83 
86  debug_(iConfig.getParameter<int>("debug")),
87  filterOnEnergyAndCaloP_(iConfig.getParameter<bool>("filterOnEnergyAndCaloP")) {
88  auto hitMapInputTag = iConfig.getParameter<edm::InputTag>("hitMapTag");
89  auto caloParticles = iConfig.getParameter<edm::InputTag>("caloParticles");
90  hitMap_ = consumes<std::unordered_map<DetId, const HGCRecHit*>>(hitMapInputTag);
91  caloParticles_ = consumes<std::vector<CaloParticle>>(caloParticles);
92 }
93 
95  // do anything here that needs to be done at desctruction time
96  // (e.g. close files, deallocate resources etc.)
97 }
98 
100  edm::Run const& iRun,
101  edm::EventSetup const& /* iSetup */) {
102  ibooker.cd();
103  ibooker.setCurrentFolder("HGCalShowerSeparation");
104  scEnergy_ = ibooker.book1D("SCEnergy", "SCEnergy", 240, 0., 120.);
105  eta1_ = ibooker.book1D("eta1", "eta1", 80, 0., 4.);
106  eta2_ = ibooker.book1D("eta2", "eta2", 80, 0., 4.);
107  energy1_ = ibooker.book1D("energy1", "energy1", 240, 0., 120.);
108  energy2_ = ibooker.book1D("energy2", "energy2", 240, 0., 120.);
109  energytot_ = ibooker.book1D("energytot", "energytot", 200, 100., 200.);
110  showerProfile_ = ibooker.book2D("ShowerProfile", "ShowerProfile", 800, -400., 400., layers_, 0., (float)layers_);
111  layerEnergy_ = ibooker.book2D("LayerEnergy", "LayerEnergy", 60, 0., 60., 50, 0., 0.1);
112  layerDistance_ = ibooker.book2D("LayerDistance", "LayerDistance", 60, 0., 60., 400, -400., 400.);
113  etaPhi_ = ibooker.book2D("EtaPhi", "EtaPhi", 800, -4., 4., 800, -4., 4.);
114  deltaEtaPhi_ = ibooker.book2D("DeltaEtaPhi", "DeltaEtaPhi", 100, -0.5, 0.5, 100, -0.5, 0.5);
115  for (int i = 0; i < layers_; ++i) {
116  profileOnLayer_.push_back(ibooker.book2D(std::string("ProfileOnLayer_") + std::to_string(i),
117  std::string("ProfileOnLayer_") + std::to_string(i),
118  120,
119  -600.,
120  600.,
121  120,
122  -600.,
123  600.));
124  globalProfileOnLayer_.push_back(ibooker.book2D(std::string("GlobalProfileOnLayer_") + std::to_string(i),
125  std::string("GlobalProfileOnLayer_") + std::to_string(i),
126  320,
127  -160.,
128  160.,
129  320,
130  -160.,
131  160.));
132  distanceOnLayer_.push_back(ibooker.book1D(std::string("DistanceOnLayer_") + std::to_string(i),
133  std::string("DistanceOnLayer_") + std::to_string(i),
134  120,
135  -600.,
136  600.));
137  idealDistanceOnLayer_.push_back(ibooker.book1D(std::string("IdealDistanceOnLayer_") + std::to_string(i),
138  std::string("IdealDistanceOnLayer_") + std::to_string(i),
139  120,
140  -600.,
141  600.));
142  idealDeltaXY_.push_back(ibooker.book2D(std::string("IdealDeltaXY_") + std::to_string(i),
143  std::string("IdealDeltaXY_") + std::to_string(i),
144  800,
145  -400.,
146  400.,
147  800,
148  -400.,
149  400.));
150  centers_.push_back(ibooker.book2D(std::string("Centers_") + std::to_string(i),
151  std::string("Centers_") + std::to_string(i),
152  320,
153  -1600.,
154  1600.,
155  320,
156  -1600.,
157  1600.));
158  }
159 }
160 
162  using namespace edm;
163 
165 
166  Handle<std::vector<CaloParticle>> caloParticleHandle;
167  iEvent.getByToken(caloParticles_, caloParticleHandle);
168  const std::vector<CaloParticle>& caloParticles = *caloParticleHandle;
169 
171  iEvent.getByToken(hitMap_, hitMapHandle);
172  const auto hitmap = *hitMapHandle;
173 
174  // loop over caloParticles
175  IfLogTrace(debug_ > 0, "HGCalShowerSeparation") << "Number of caloParticles: " << caloParticles.size() << std::endl;
176  if (caloParticles.size() == 2) {
177  auto eta1 = caloParticles[0].eta();
178  auto phi1 = caloParticles[0].phi();
179  auto theta1 = 2. * atan(exp(-eta1));
180  auto eta2 = caloParticles[1].eta();
181  auto phi2 = caloParticles[1].phi();
182  auto theta2 = 2. * atan(exp(-eta2));
183  eta1_->Fill(eta1);
184  eta2_->Fill(eta2);
185 
186  // Select event only if the sum of the energy of its recHits
187  // is close enough to the gen energy
188  int count = 0;
189  int size = 0;
190  float energy = 0.;
191  float energy_tmp = 0.;
192  for (const auto& it_caloPart : caloParticles) {
193  count++;
194  const SimClusterRefVector& simClusterRefVector = it_caloPart.simClusters();
195  size += simClusterRefVector.size();
196  for (const auto& it_sc : simClusterRefVector) {
197  const SimCluster& simCluster = (*(it_sc));
198  const std::vector<std::pair<uint32_t, float>>& hits_and_fractions = simCluster.hits_and_fractions();
199  for (const auto& it_haf : hits_and_fractions) {
200  if (hitmap.count(it_haf.first))
201  energy += hitmap.at(it_haf.first)->energy() * it_haf.second;
202  } //hits and fractions
203  } // simcluster
204  if (count == 1) {
205  energy1_->Fill(energy);
206  energy_tmp = energy;
207  } else {
208  energy2_->Fill(energy - energy_tmp);
209  }
210  } // caloParticle
212  if (filterOnEnergyAndCaloP_ && (energy < 2. * 0.8 * 80 or size != 2))
213  return;
214 
215  deltaEtaPhi_->Fill(eta1 - eta2, phi1 - phi2);
216 
217  for (const auto& it_caloPart : caloParticles) {
218  const SimClusterRefVector& simClusterRefVector = it_caloPart.simClusters();
219  IfLogTrace(debug_ > 0, "HGCalShowerSeparation") << ">>> " << simClusterRefVector.size() << std::endl;
220  for (const auto& it_sc : simClusterRefVector) {
221  const SimCluster& simCluster = (*(it_sc));
222  if (simCluster.energy() < 80 * 0.8)
223  continue;
224  scEnergy_->Fill(simCluster.energy());
225  IfLogTrace(debug_ > 1, "HGCalShowerSeparation")
226  << ">>> SC.energy(): " << simCluster.energy() << " SC.simEnergy(): " << simCluster.simEnergy() << std::endl;
227  const std::vector<std::pair<uint32_t, float>>& hits_and_fractions = simCluster.hits_and_fractions();
228 
229  for (const auto& it_haf : hits_and_fractions) {
230  if (!hitmap.count(it_haf.first))
231  continue;
232  unsigned int hitlayer = recHitTools_.getLayerWithOffset(it_haf.first);
233  auto global = recHitTools_.getPosition(it_haf.first);
234  float globalx = global.x();
235  float globaly = global.y();
236  float globalz = global.z();
237  if (globalz == 0)
238  continue;
239  auto rho1 = globalz * tan(theta1);
240  auto rho2 = globalz * tan(theta2);
241  auto x1 = rho1 * cos(phi1);
242  auto y1 = rho1 * sin(phi1);
243  auto x2 = rho2 * cos(phi2);
244  auto y2 = rho2 * sin(phi2);
245  auto half_point_x = (x1 + x2) / 2.;
246  auto half_point_y = (y1 + y2) / 2.;
247  auto half_point = sqrt((x1 - half_point_x) * (x1 - half_point_x) + (y1 - half_point_y) * (y1 - half_point_y));
248  auto d_len = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
249  auto dn_x = (x2 - x1) / d_len;
250  auto dn_y = (y2 - y1) / d_len;
251  auto distance = (globalx - x1) * dn_x + (globaly - y1) * dn_y;
252  distance -= half_point;
253  auto idealDistance = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
254  if (hitmap.count(it_haf.first)) {
255  profileOnLayer_[hitlayer]->Fill(10. * (globalx - half_point_x),
256  10. * (globaly - half_point_y),
257  hitmap.at(it_haf.first)->energy() * it_haf.second);
258  profileOnLayer_[55]->Fill(10. * (globalx - half_point_x),
259  10. * (globaly - half_point_y),
260  hitmap.at(it_haf.first)->energy() * it_haf.second);
261  globalProfileOnLayer_[hitlayer]->Fill(globalx, globaly, hitmap.at(it_haf.first)->energy() * it_haf.second);
262  globalProfileOnLayer_[55]->Fill(globalx, globaly, hitmap.at(it_haf.first)->energy() * it_haf.second);
263  layerEnergy_->Fill(hitlayer, hitmap.at(it_haf.first)->energy());
264  layerDistance_->Fill(hitlayer, std::abs(10. * distance), hitmap.at(it_haf.first)->energy() * it_haf.second);
265  etaPhi_->Fill(global.eta(), global.phi());
266  distanceOnLayer_[hitlayer]->Fill(10. * distance); //,
267  idealDistanceOnLayer_[hitlayer]->Fill(10. * idealDistance); //,
268  idealDeltaXY_[hitlayer]->Fill(10. * (x1 - x2), 10. * (y1 - y2)); //,
269  centers_[hitlayer]->Fill(10. * half_point_x, 10. * half_point_y); //,
270  IfLogTrace(debug_ > 0, "HGCalShowerSeparation")
271  << ">>> " << distance << " " << hitlayer << " " << hitmap.at(it_haf.first)->energy() * it_haf.second
272  << std::endl;
273  showerProfile_->Fill(10. * distance, hitlayer, hitmap.at(it_haf.first)->energy() * it_haf.second);
274  }
275  } // end simHit
276  } // end simCluster
277  } // end caloparticle
278  }
279 }
280 
281 // ------------ method fills 'descriptions' with the allowed parameters for the
282 // module ------------
285  desc.add<int>("debug", 1);
286  desc.add<bool>("filterOnEnergyAndCaloP", false);
287  desc.add<edm::InputTag>("caloParticles", edm::InputTag("mix", "MergedCaloTruth"));
288  desc.add<edm::InputTag>("hitMapTag", edm::InputTag("hgcalRecHitMapProducer"));
289  descriptions.add("hgcalShowerSeparationDefault", desc);
290 }
291 
292 // 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:303
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
#define IfLogTrace(cond, cat)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
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_
static constexpr int layers_
std::vector< MonitorElement * > globalProfileOnLayer_
std::string to_string(const V &value)
Definition: OMSAccess.h:71
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
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:129
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
bool getData(T &iHolder) const
Definition: EventSetup.h:122
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:212
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:68
float energy() const
Energy. Note this is taken from the first SimTrack only.
Definition: SimCluster.h:104
HLT enums.
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:365