CMS 3D CMS Logo

HcalRecHitsDQMClient.cc
Go to the documentation of this file.
3 
9 
11 
13  : conf_(iConfig),
14  hcalDDDRecConstantsToken_{esConsumes<HcalDDDRecConstants, HcalRecNumberingRecord, edm::Transition::BeginRun>()},
15  caloGeometryRunToken_{esConsumes<CaloGeometry, CaloGeometryRecord, edm::Transition::BeginRun>()} {
16  outputFile_ = iConfig.getUntrackedParameter<std::string>("outputFile", "myfile.root");
17  debug_ = false;
18  verbose_ = false;
19  dirName_ = iConfig.getParameter<std::string>("DQMDirName");
20 }
21 
23 
25 
28  maxDepthHB_ = hcons.getMaxDepth(0);
29  maxDepthHE_ = hcons.getMaxDepth(1);
30  maxDepthHF_ = std::max(hcons.getMaxDepth(2), 1);
31  maxDepthHO_ = hcons.getMaxDepth(3);
32 
34  const std::vector<DetId> &hbCells = geometry.getValidDetIds(DetId::Hcal, HcalBarrel);
35  const std::vector<DetId> &heCells = geometry.getValidDetIds(DetId::Hcal, HcalEndcap);
36  const std::vector<DetId> &hoCells = geometry.getValidDetIds(DetId::Hcal, HcalOuter);
37  const std::vector<DetId> &hfCells = geometry.getValidDetIds(DetId::Hcal, HcalForward);
38 
39  nChannels_[1] = hbCells.size();
40  nChannels_[2] = heCells.size();
41  nChannels_[3] = hoCells.size();
42  nChannels_[4] = hfCells.size();
43  nChannels_[0] = nChannels_[1] + nChannels_[2] + nChannels_[3] + nChannels_[4];
44  // avoid divide by zero
45  for (unsigned i = 0; i < 5; ++i) {
46  if (nChannels_[i] == 0)
47  nChannels_[i] = 1;
48  }
49 
50  // std::cout << "Channels HB:" << nChannels_[1] << " HE:" << nChannels_[2] <<
51  // " HO:" << nChannels_[3] << " HF:" << nChannels_[4] << std::endl;
52 
53  // We hardcode the HF depths because in the dual readout configuration,
54  // rechits are not defined for depths 3&4
55  maxDepthHF_ = (maxDepthHF_ > 2 ? 2 : maxDepthHF_); // We reatin the dynamic possibility
56  // that HF might have 0 or 1 depths
57 
60 }
61 
63  igetter.setCurrentFolder(dirName_);
64 
65  if (verbose_)
66  std::cout << "\nrunClient" << std::endl;
67 
68  std::vector<MonitorElement *> hcalMEs;
69 
70  // Since out folders are fixed to three, we can just go over these three
71  // folders i.e., CaloTowersD/CaloTowersTask, HcalRecHitsD/HcalRecHitTask,
72  // NoiseRatesV/NoiseRatesTask.
73  std::vector<std::string> fullPathHLTFolders = igetter.getSubdirs();
74  for (unsigned int i = 0; i < fullPathHLTFolders.size(); i++) {
75  if (verbose_)
76  std::cout << "\nfullPath: " << fullPathHLTFolders[i] << std::endl;
77  igetter.setCurrentFolder(fullPathHLTFolders[i]);
78 
79  std::vector<std::string> fullSubPathHLTFolders = igetter.getSubdirs();
80  for (unsigned int j = 0; j < fullSubPathHLTFolders.size(); j++) {
81  if (verbose_)
82  std::cout << "fullSub: " << fullSubPathHLTFolders[j] << std::endl;
83 
84  if (strcmp(fullSubPathHLTFolders[j].c_str(), "HcalRecHitsD/HcalRecHitTask") == 0) {
85  hcalMEs = igetter.getContents(fullSubPathHLTFolders[j]);
86  if (verbose_)
87  std::cout << "hltMES size : " << hcalMEs.size() << std::endl;
88  if (!HcalRecHitsEndjob(hcalMEs))
89  std::cout << "\nError in HcalRecHitsEndjob!" << std::endl << std::endl;
90  }
91  }
92  }
93 }
94 
95 // called after entering the HcalRecHitsD/HcalRecHitTask directory
96 // hcalMEs are within that directory
97 int HcalRecHitsDQMClient::HcalRecHitsEndjob(const std::vector<MonitorElement *> &hcalMEs) {
98  MonitorElement *Nhf = nullptr;
99 
100  // Search for emap histograms, and collect them into this vector
101  // All subdtectors are plotted together in these histograms. We only need to
102  // look for different depths
103  std::vector<MonitorElement *> emap_depths;
104 
105  // This vector is filled occupancy_maps identified by both subdetector and
106  // depth
107  std::vector<MonitorElement *> occupancy_maps;
108  std::vector<std::string> occupancyID;
109 
110  // This vector is filled with emean_vs_ieta histograms, they are divided by
111  // both subdetector and depth
112  std::vector<MonitorElement *> emean_vs_ieta;
113 
114  // These are the only histograms filled in this module; however, the
115  // histograms are created empty in HcalRecHitsAnalyzer occupancy_vs_ieta,
116  // divided by both subdetector and depth
117  std::vector<MonitorElement *> occupancy_vs_ieta;
118  std::vector<std::string> occupancy_vs_ietaID;
119 
120  // RecHit_StatusWord & RecHit_Aux_StatusWord
121  // Divided by subdectector
122  std::vector<MonitorElement *> RecHit_StatusWord;
123  std::vector<float> RecHit_StatusWord_Channels;
124  std::vector<MonitorElement *> RecHit_Aux_StatusWord;
125  std::vector<float> RecHit_Aux_StatusWord_Channels;
126 
127  for (unsigned int ih = 0; ih < hcalMEs.size(); ih++) {
128  // N_HF is not special, it is just convient to get the total number of
129  // events The number of entries in N_HF is equal to the number of events
130  if (hcalMEs[ih]->getName() == "N_HF") {
131  Nhf = hcalMEs[ih];
132  continue;
133  }
134 
135  // ***********************
136  // * We fill the various MonitorElement vectors by searching for a matching
137  // substring
138  // * The methods that are used are agnostic to the ordering of vectors
139  // ***********************
140 
141  if (hcalMEs[ih]->getName().find("emap_depth") != std::string::npos) {
142  emap_depths.push_back(hcalMEs[ih]);
143  continue;
144  }
145 
146  if (hcalMEs[ih]->getName().find("occupancy_map_H") != std::string::npos) {
147  occupancy_maps.push_back(hcalMEs[ih]);
148 
149  // Use occupancyID to save the subdetector and depth information
150  // This will help preserve both indifference to vector ordering and
151  // specific details of the detector topology The position in occupancyID
152  // must correspond to the histogram position in occupancy_maps
153 
154  // Save the string after "occupancy_map_"
155 
156  std::string prefix = "occupancy_map_";
157 
158  occupancyID.push_back(hcalMEs[ih]->getName().substr(prefix.size()));
159 
160  continue;
161  }
162 
163  if (hcalMEs[ih]->getName().find("emean_vs_ieta_H") != std::string::npos) {
164  emean_vs_ieta.push_back(hcalMEs[ih]);
165  continue;
166  }
167 
168  if (hcalMEs[ih]->getName().find("occupancy_vs_ieta_H") != std::string::npos) {
169  occupancy_vs_ieta.push_back(hcalMEs[ih]);
170 
171  // Use occupancy_vs_ietaID to save the subdetector and depth information
172  // This will help preserve both indifference to vector ordering and
173  // specific details of the detector topology The position in occupancyID
174  // must correspond to the histogram position in occupancy_vs_ieta
175 
176  // Save the string after "occupancy_vs_ieta_"
177 
178  std::string prefix = "occupancy_vs_ieta_";
179 
180  occupancy_vs_ietaID.push_back(hcalMEs[ih]->getName().substr(prefix.size()));
181 
182  continue;
183  }
184 
185  if (hcalMEs[ih]->getName().find("HcalRecHitTask_RecHit_StatusWord_H") != std::string::npos) {
186  RecHit_StatusWord.push_back(hcalMEs[ih]);
187 
188  if (hcalMEs[ih]->getName().find("HB") != std::string::npos) {
189  RecHit_StatusWord_Channels.push_back((float)nChannels_[1]);
190  } else if (hcalMEs[ih]->getName().find("HE") != std::string::npos) {
191  RecHit_StatusWord_Channels.push_back((float)nChannels_[2]);
192  } else if (hcalMEs[ih]->getName().find("H0") != std::string::npos) {
193  RecHit_StatusWord_Channels.push_back((float)nChannels_[3]);
194  } else if (hcalMEs[ih]->getName().find("HF") != std::string::npos) {
195  RecHit_StatusWord_Channels.push_back((float)nChannels_[4]);
196  } else {
197  RecHit_StatusWord_Channels.push_back(1.);
198  }
199 
200  continue;
201  }
202 
203  if (hcalMEs[ih]->getName().find("HcalRecHitTask_RecHit_Aux_StatusWord_H") != std::string::npos) {
204  RecHit_Aux_StatusWord.push_back(hcalMEs[ih]);
205 
206  if (hcalMEs[ih]->getName().find("HB") != std::string::npos) {
207  RecHit_Aux_StatusWord_Channels.push_back((float)nChannels_[1]);
208  } else if (hcalMEs[ih]->getName().find("HE") != std::string::npos) {
209  RecHit_Aux_StatusWord_Channels.push_back((float)nChannels_[2]);
210  } else if (hcalMEs[ih]->getName().find("H0") != std::string::npos) {
211  RecHit_Aux_StatusWord_Channels.push_back((float)nChannels_[3]);
212  } else if (hcalMEs[ih]->getName().find("HF") != std::string::npos) {
213  RecHit_Aux_StatusWord_Channels.push_back((float)nChannels_[4]);
214  } else {
215  RecHit_Aux_StatusWord_Channels.push_back(1.);
216  }
217 
218  continue;
219  }
220  }
221 
222  // mean energies and occupancies evaluation
223 
224  double nevtot = Nhf->getEntries(); // Use the number of entries in the Nhf histogram to
225  // give the total number of events
226 
227  if (verbose_)
228  std::cout << "nevtot : " << nevtot << std::endl;
229 
230  // emap histograms are scaled by the number of events
231  float fev = float(nevtot);
232  double scaleBynevtot = 1 / fev;
233 
234  // In this and the following histogram vectors, recognize that the for-loop
235  // index does not have to correspond to any particular depth
236  for (unsigned int depthIdx = 0; depthIdx < emap_depths.size(); depthIdx++) {
237  int nx = emap_depths[depthIdx]->getNbinsX();
238  int ny = emap_depths[depthIdx]->getNbinsY();
239 
240  float cnorm;
241  float enorm;
242 
243  for (int i = 1; i <= nx; i++) {
244  for (int j = 1; j <= ny; j++) {
245  cnorm = emap_depths[depthIdx]->getBinContent(i, j) * scaleBynevtot;
246  enorm = emap_depths[depthIdx]->getBinError(i, j) * scaleBynevtot;
247  emap_depths[depthIdx]->setBinContent(i, j, cnorm);
248  emap_depths[depthIdx]->setBinError(i, j, enorm);
249  }
250  }
251  }
252 
253  // occupancy_maps & matched occupancy_vs_ieta
254 
255  bool omatched = false;
256 
257  for (unsigned int occupancyIdx = 0; occupancyIdx < occupancy_maps.size(); occupancyIdx++) {
258  int nx = occupancy_maps[occupancyIdx]->getNbinsX();
259  int ny = occupancy_maps[occupancyIdx]->getNbinsY();
260 
261  float cnorm;
262  float enorm;
263 
264  unsigned int vsIetaIdx = occupancy_vs_ieta.size();
265  omatched = false;
266 
267  for (vsIetaIdx = 0; vsIetaIdx < occupancy_vs_ieta.size(); vsIetaIdx++) {
268  if (occupancyID[occupancyIdx] == occupancy_vs_ietaID[vsIetaIdx]) {
269  omatched = true;
270  break;
271  }
272  } // match occupancy_vs_ieta histogram
273 
274  for (int i = 1; i <= nx; i++) {
275  for (int j = 1; j <= ny; j++) {
276  cnorm = occupancy_maps[occupancyIdx]->getBinContent(i, j) * scaleBynevtot;
277  enorm = occupancy_maps[occupancyIdx]->getBinError(i, j) * scaleBynevtot;
278  occupancy_maps[occupancyIdx]->setBinContent(i, j, cnorm);
279  occupancy_maps[occupancyIdx]->setBinError(i, j, enorm);
280  }
281  }
282 
283  // Fill occupancy_vs_ieta
284 
285  if (omatched) {
286  // We run over all of the ieta values
287  for (int ieta = -41; ieta <= 41; ieta++) {
288  float phi_factor = 1.;
289  float sumphi = 0.;
290  float sumphie = 0.;
291 
292  if (ieta == 0)
293  continue; // ieta=0 is not defined
294 
295  phi_factor = phifactor(ieta);
296 
297  // the rechits occupancy map defines iphi as 0..71
298  for (int iphi = 0; iphi <= 71; iphi++) {
299  int binIeta = occupancy_maps[occupancyIdx]->getTH2F()->GetXaxis()->FindBin(float(ieta));
300  int binIphi = occupancy_maps[occupancyIdx]->getTH2F()->GetYaxis()->FindBin(float(iphi));
301 
302  float content = occupancy_maps[occupancyIdx]->getBinContent(binIeta, binIphi);
303  float econtent = occupancy_maps[occupancyIdx]->getBinError(binIeta, binIphi);
304 
305  sumphi += content;
306  sumphie += econtent * econtent;
307  } // for loop over phi
308 
309  int ietabin = occupancy_vs_ieta[vsIetaIdx]->getTH1F()->GetXaxis()->FindBin(float(ieta));
310 
311  // fill occupancies vs ieta
312  cnorm = sumphi / phi_factor;
313  enorm = sqrt(sumphie) / phi_factor;
314  occupancy_vs_ieta[vsIetaIdx]->setBinContent(ietabin, cnorm);
315  occupancy_vs_ieta[vsIetaIdx]->setBinError(ietabin, enorm);
316 
317  } // Fill occupancy_vs_ieta
318  } // if omatched
319  }
320 
321  // Status Word
322  // Normalized by number of events and by number of channels per subdetector as
323  // well
324 
325  for (unsigned int StatusWordIdx = 0; StatusWordIdx < RecHit_StatusWord.size(); StatusWordIdx++) {
326  int nx = RecHit_StatusWord[StatusWordIdx]->getNbinsX();
327 
328  float cnorm;
329  float enorm;
330 
331  for (int i = 1; i <= nx; i++) {
332  cnorm = RecHit_StatusWord[StatusWordIdx]->getBinContent(i) * scaleBynevtot /
333  RecHit_StatusWord_Channels[StatusWordIdx];
334  enorm =
335  RecHit_StatusWord[StatusWordIdx]->getBinError(i) * scaleBynevtot / RecHit_StatusWord_Channels[StatusWordIdx];
336  RecHit_StatusWord[StatusWordIdx]->setBinContent(i, cnorm);
337  RecHit_StatusWord[StatusWordIdx]->setBinError(i, enorm);
338  }
339  }
340 
341  for (unsigned int AuxStatusWordIdx = 0; AuxStatusWordIdx < RecHit_Aux_StatusWord.size(); AuxStatusWordIdx++) {
342  int nx = RecHit_Aux_StatusWord[AuxStatusWordIdx]->getNbinsX();
343 
344  float cnorm;
345  float enorm;
346 
347  for (int i = 1; i <= nx; i++) {
348  cnorm = RecHit_Aux_StatusWord[AuxStatusWordIdx]->getBinContent(i) * scaleBynevtot /
349  RecHit_Aux_StatusWord_Channels[AuxStatusWordIdx];
350  enorm = RecHit_Aux_StatusWord[AuxStatusWordIdx]->getBinError(i) * scaleBynevtot /
351  RecHit_Aux_StatusWord_Channels[AuxStatusWordIdx];
352  RecHit_Aux_StatusWord[AuxStatusWordIdx]->setBinContent(i, cnorm);
353  RecHit_Aux_StatusWord[AuxStatusWordIdx]->setBinError(i, enorm);
354  }
355  }
356 
357  return 1;
358 }
359 
361  float phi_factor_;
362 
363  if (ieta >= -20 && ieta <= 20) {
364  phi_factor_ = 72.;
365  } else {
366  if (ieta >= 40 || ieta <= -40) {
367  phi_factor_ = 18.;
368  } else {
369  phi_factor_ = 36.;
370  }
371  }
372 
373  return phi_factor_;
374 }
375 
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeometryRunToken_
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
void beginJob(void) override
T sqrt(T t)
Definition: SSEVec.h:19
edm::ESGetToken< HcalDDDRecConstants, HcalRecNumberingRecord > hcalDDDRecConstantsToken_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
virtual double getEntries() const
get # of entries
bool getData(T &iHolder) const
Definition: EventSetup.h:122
int getMaxDepth(const int &type) const
HcalRecHitsDQMClient(const edm::ParameterSet &)
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override
void beginRun(edm::Run const &, edm::EventSetup const &) override
std::string getName(const G4String &)
Definition: ForwardName.cc:3
Definition: Run.h:45
virtual std::vector< dqm::harvesting::MonitorElement * > getContents(std::string const &path) const
Definition: DQMStore.cc:610
int HcalRecHitsEndjob(const std::vector< MonitorElement *> &hcalMEs)
virtual DQM_DEPRECATED std::vector< std::string > getSubdirs() const
Definition: DQMStore.cc:717