CMS 3D CMS Logo

DTOccupancyTestML.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author G. Cerminara - University and INFN Torino
5  *
6  * threadsafe version (//-) oct/nov 2014 - WATWanAbdullah -ncpp-um-my
7  *
8  */
9 
11 
20 
21 #include "TMath.h"
22 
24 #include <vector>
25 
26 using namespace edm;
27 using namespace std;
28 
30  : muonGeomToken_(esConsumes<edm::Transition::BeginRun>()) {
31  LogVerbatim("DTDQM|DTMonitorClient|DTOccupancyTestML") << "[DTOccupancyTestML]: Constructor";
32 
33  // Get the DQM service
34 
35  lsCounter = 0;
36 
37  writeRootFile = ps.getUntrackedParameter<bool>("writeRootFile", false);
38  if (writeRootFile) {
39  rootFile = new TFile("MLDTOccupancyTest.root", "RECREATE");
40  ntuple = new TNtuple("OccupancyNtuple",
41  "OccupancyNtuple",
42  "ls:wh:st:se:lay1MeanCell:lay1RMS:lay2MeanCell:lay2RMS:lay3MeanCell:lay3RMS:lay4MeanCell:"
43  "lay4RMS:lay5MeanCell:lay5RMS:lay6MeanCell:lay6RMS:lay7MeanCell:lay7RMS:lay8MeanCell:lay8RMS:"
44  "lay9MeanCell:lay9RMS:lay10MeanCell:lay10RMS:lay11MeanCell:lay11RMS:lay12MeanCell:lay12RMS");
45  }
46 
47  // switch on the mode for running on test pulses (different top folder)
48  tpMode = ps.getUntrackedParameter<bool>("testPulseMode", false);
49 
50  runOnAllHitsOccupancies = ps.getUntrackedParameter<bool>("runOnAllHitsOccupancies", true);
51  runOnNoiseOccupancies = ps.getUntrackedParameter<bool>("runOnNoiseOccupancies", false);
52  runOnInTimeOccupancies = ps.getUntrackedParameter<bool>("runOnInTimeOccupancies", false);
53  nMinEvts = ps.getUntrackedParameter<int>("nEventsCert", 5000);
54  nMinEvtsPC = ps.getUntrackedParameter<int>("nEventsMinPC", 2200);
55  nZeroEvtsPC = ps.getUntrackedParameter<int>("nEventsZeroPC", 30);
56 
57  bookingdone = false;
58 
59  // Event counter
60  nevents = 0;
61 }
62 
64  LogVerbatim("DTDQM|DTMonitorClient|MLDTOccupancyTest") << " destructor called" << endl;
65 }
66 
68  LogVerbatim("DTDQM|DTMonitorClient|DTOccupancyTestML") << "[DTOccupancyTestML]: BeginRun";
69 
70  // Get the geometry
71  muonGeom = &context.getData(muonGeomToken_);
72 }
73 
75  DQMStore::IGetter& igetter,
76  edm::LuminosityBlock const& lumiSeg,
77  edm::EventSetup const& context) {
78  if (!bookingdone) {
79  // Book the summary histos
80  // - one summary per wheel
81  for (int wh = -2; wh <= 2; ++wh) { // loop over wheels
82  bookHistos(ibooker, wh, string("MLDTOccupancies"), "MLOccupancySummary");
83  }
84 
85  ibooker.setCurrentFolder(topFolder(true));
86  string title = "Occupancy Summary";
87  if (tpMode) {
88  title = "Test Pulse Occupancy Summary";
89  }
90  // - global summary with alarms
91  summaryHisto = ibooker.book2D("MLOccupancySummary", title.c_str(), 12, 1, 13, 5, -2, 3);
92  summaryHisto->setAxisTitle("sector", 1);
93  summaryHisto->setAxisTitle("wheel", 2);
94 
95  // - global summary with percentages
96  glbSummaryHisto = ibooker.book2D("MLOccupancyGlbSummary", title.c_str(), 12, 1, 13, 5, -2, 3);
97  glbSummaryHisto->setAxisTitle("sector", 1);
98  glbSummaryHisto->setAxisTitle("wheel", 2);
99 
100  // assign the name of the input histogram
102  nameMonitoredHisto = "OccupancyAllHits_perCh";
103  } else if (runOnNoiseOccupancies) {
104  nameMonitoredHisto = "OccupancyNoise_perCh";
105  } else if (runOnInTimeOccupancies) {
106  nameMonitoredHisto = "OccupancyInTimeHits_perCh";
107  } else { // default is AllHits histo
108  nameMonitoredHisto = "OccupancyAllHits_perCh";
109  }
110  }
111  bookingdone = true;
112 
113  LogVerbatim("DTDQM|DTMonitorClient|DTOccupancyTestML")
114  << "[DTOccupancyTestML]: End of LS transition, performing the DQM client operation";
115  lsCounter++;
116 
117  // Reset the global summary
118  summaryHisto->Reset();
120 
121  nChannelTotal = 0;
122  nChannelDead = 0;
123 
124  // Get all the DT chambers
125  vector<const DTChamber*> chambers = muonGeom->chambers();
126 
127  // Load graph
128  edm::FileInPath modelFilePath("DQM/DTMonitorClient/data/occupancy_cnn_v1.pb");
129  tensorflow::GraphDef* graphDef = tensorflow::loadGraphDef(modelFilePath.fullPath());
130 
131  // Create session
132  tensorflow::Session* session = tensorflow::createSession(graphDef);
133 
134  for (vector<const DTChamber*>::const_iterator chamber = chambers.begin(); chamber != chambers.end();
135  ++chamber) { // Loop over all chambers
136  DTChamberId chId = (*chamber)->id();
137 
138  MonitorElement* chamberOccupancyHisto = igetter.get(getMEName(nameMonitoredHisto, chId));
139 
140  // Run the tests on the plot for the various granularities
141  if (chamberOccupancyHisto != nullptr) {
142  // Get the 2D histo
143  TH2F* histo = chamberOccupancyHisto->getTH2F();
144 
145  float chamberPercentage = 1.;
146  int result = runOccupancyTest(histo, chId, chamberPercentage, graphDef, session);
147  int sector = chId.sector();
148 
149  if (sector == 13) {
150  sector = 4;
151  float resultSect4 = wheelHistos[chId.wheel()]->getBinContent(sector, chId.station());
152  if (resultSect4 > result) {
153  result = (int)resultSect4;
154  }
155  } else if (sector == 14) {
156  sector = 10;
157  float resultSect10 = wheelHistos[chId.wheel()]->getBinContent(sector, chId.station());
158  if (resultSect10 > result) {
159  result = (int)resultSect10;
160  }
161  }
162 
163  // the 2 MB4 of Sect 4 and 10 count as half a chamber
164  if ((sector == 4 || sector == 10) && chId.station() == 4)
165  chamberPercentage = chamberPercentage / 2.;
166 
167  wheelHistos[chId.wheel()]->setBinContent(sector, chId.station(), result);
168  if (result > summaryHisto->getBinContent(sector, chId.wheel() + 3)) {
170  }
171  glbSummaryHisto->Fill(sector, chId.wheel(), chamberPercentage * 1. / 4.);
172  } else {
173  LogVerbatim("DTDQM|DTMonitorClient|DTOccupancyTestML")
174  << "[DTOccupancyTestML] ME: " << getMEName(nameMonitoredHisto, chId) << " not found!" << endl;
175  }
176  }
177 
178  // Clean up neural network graph
180  delete graphDef;
181 
182  string nEvtsName = "DT/EventInfo/Counters/nProcessedEventsDigi";
183 
184  MonitorElement* meProcEvts = igetter.get(nEvtsName);
185 
186  if (meProcEvts) {
187  int nProcEvts = meProcEvts->getFloatValue();
188  glbSummaryHisto->setEntries(nProcEvts < nMinEvts ? 10. : nProcEvts);
189  summaryHisto->setEntries(nProcEvts < nMinEvts ? 10. : nProcEvts);
190  } else {
193  LogVerbatim("DTDQM|DTMonitorClient|DTOccupancyTestML")
194  << "[DTOccupancyTestML] ME: " << nEvtsName << " not found!" << endl;
195  }
196 
197  // Fill the global summary
198  // Check for entire sectors off and report them on the global summary
199  //FIXME: TODO
200 
201  if (writeRootFile)
202  ntuple->AutoSave("SaveSelf");
203 }
204 
206  LogVerbatim("DTDQM|DTMonitorClient|DTOccupancyTestML") << "[DTOccupancyTestML] endjob called!";
207  if (writeRootFile) {
208  rootFile->cd();
209  ntuple->Write();
210  rootFile->Close();
211  }
212 }
213 
214 // --------------------------------------------------
215 
216 void DTOccupancyTestML::bookHistos(DQMStore::IBooker& ibooker, const int wheelId, string folder, string histoTag) {
217  // Set the current folder
218  stringstream wheel;
219  wheel << wheelId;
220 
221  ibooker.setCurrentFolder(topFolder(true));
222 
223  // build the histo name
224  string histoName = histoTag + "_W" + wheel.str();
225 
226  LogVerbatim("DTDQM|DTMonitorClient|DTOccupancyTestML")
227  << "[DTOccupancyTestML]: booking wheel histo:" << histoName << " (tag " << histoTag
228  << ") in: " << topFolder(true) + "Wheel" + wheel.str() + "/" + folder << endl;
229 
230  string histoTitle = "Occupancy summary WHEEL: " + wheel.str();
231  if (tpMode) {
232  histoTitle = "TP Occupancy summary WHEEL: " + wheel.str();
233  }
234 
235  wheelHistos[wheelId] = ibooker.book2D(histoName, histoTitle, 12, 1, 13, 4, 1, 5);
236  wheelHistos[wheelId]->setBinLabel(1, "MB1", 2);
237  wheelHistos[wheelId]->setBinLabel(2, "MB2", 2);
238  wheelHistos[wheelId]->setBinLabel(3, "MB3", 2);
239  wheelHistos[wheelId]->setBinLabel(4, "MB4", 2);
240  wheelHistos[wheelId]->setAxisTitle("sector", 1);
241 }
242 
243 string DTOccupancyTestML::getMEName(string histoTag, const DTChamberId& chId) {
244  stringstream wheel;
245  wheel << chId.wheel();
246  stringstream station;
247  station << chId.station();
248  stringstream sector;
249  sector << chId.sector();
250 
251  string folderRoot =
252  topFolder(false) + "Wheel" + wheel.str() + "/Sector" + sector.str() + "/Station" + station.str() + "/";
253 
254  // build the histo name
255  string histoName = histoTag + "_W" + wheel.str() + "_St" + station.str() + "_Sec" + sector.str();
256 
257  string histoname = folderRoot + histoName;
258 
259  return histoname;
260 }
261 
262 int DTOccupancyTestML::getIntegral(TH2F* histo, int firstBinX, int lastBinX, int firstBinY, int lastBinY, bool doall) {
263  int sum = 0;
264  for (Int_t i = firstBinX; i < lastBinX + 1; i++) {
265  for (Int_t j = firstBinY; j < lastBinY + 1; j++) {
266  if (histo->GetBinContent(i, j) > 0) {
267  if (!doall)
268  return 1;
269  sum += histo->GetBinContent(i, j);
270  }
271  }
272  }
273 
274  return sum;
275 }
276 
278  const DTChamberId& chId,
279  float& chamberPercentage,
280  tensorflow::GraphDef* graphDef,
281  tensorflow::Session* session) {
282  LogTrace("DTDQM|DTMonitorClient|DTOccupancyTestML") << "--- Occupancy test for chamber: " << chId << endl;
283 
284  // Initialize counters
285  int totalLayers = 0;
286  int badLayers = 0;
287 
288  // Loop over the super layers
289  for (int superLayer = 1; superLayer <= 3; superLayer++) {
290  int binYlow = ((superLayer - 1) * 4) + 1;
291 
292  // Skip for non-existent super layers
293  if (chId.station() == 4 && superLayer == 2)
294  continue;
295 
296  // Loop over layers
297  for (int layer = 1; layer <= 4; layer++) {
298  DTLayerId layID(chId, superLayer, layer);
299  int firstWire = muonGeom->layer(layID)->specificTopology().firstChannel();
300  int nWires = muonGeom->layer(layID)->specificTopology().channels();
301  int binY = binYlow + (layer - 1);
302  std::vector<float> layerOccupancy(nWires);
303  int channelId = 0;
304 
305  // Loop over cells within a layer
306  for (int cell = firstWire; cell != (nWires + firstWire); cell++) {
307  double cellOccupancy = histo->GetBinContent(cell, binY);
308  layerOccupancy.at(channelId) = cellOccupancy;
309  channelId++;
310  }
311 
312  int targetSize = 47;
313  std::vector<float> reshapedLayerOccupancy = interpolateLayers(layerOccupancy, nWires, targetSize);
314 
315  // Scale occupancy
316  float maxOccupancyInLayer = *std::max_element(reshapedLayerOccupancy.begin(), reshapedLayerOccupancy.end());
317 
318  if (maxOccupancyInLayer != 0) {
319  for (auto& val : reshapedLayerOccupancy)
320  val /= maxOccupancyInLayer;
321  }
322 
323  // Define input
324  tensorflow::Tensor input(tensorflow::DT_FLOAT, {1, targetSize});
325  for (int i = 0; i < targetSize; i++)
326  input.matrix<float>()(0, i) = reshapedLayerOccupancy[i];
327 
328  std::vector<tensorflow::Tensor> outputs;
329  tensorflow::run(session, {{"input_cnn_input", input}}, {"output_cnn/Softmax"}, &outputs);
330 
331  totalLayers++;
332  bool isBad = outputs[0].matrix<float>()(0, 1) > 0.95;
333  if (isBad)
334  badLayers++;
335  }
336  }
337 
338  // Calculate a fraction of good layers
339  chamberPercentage = 1.0 - static_cast<float>(badLayers) / totalLayers;
340 
341  if (badLayers > 8)
342  return 3; // 3 SL
343  if (badLayers > 4)
344  return 2; // 2 SL
345  if (badLayers > 0)
346  return 1; // 1 SL
347  return 0;
348 }
349 
350 std::vector<float> DTOccupancyTestML::interpolateLayers(std::vector<float> const& inputs, int size, int targetSize) {
351  // Reshape layers with linear interpolation
352  int interpolationFloor = 0;
353  float interpolationPoint = 0.;
354  float step = static_cast<float>(size) / targetSize;
355  std::vector<float> reshapedInput(targetSize);
356 
357  int limitInLoop = inputs.size();
358  limitInLoop = std::min(limitInLoop, targetSize) - 1;
359  for (int i = 0; i < limitInLoop; i++) {
360  interpolationFloor = static_cast<int>(std::floor(interpolationPoint));
361  // Interpolating here
362  reshapedInput.at(i) =
363  (interpolationPoint - interpolationFloor) * (inputs[interpolationFloor + 1] - inputs[interpolationFloor]) +
364  inputs[interpolationFloor];
365  interpolationPoint = step + interpolationPoint;
366  }
367  return reshapedInput;
368 }
369 
370 string DTOccupancyTestML::topFolder(bool isBooking) const {
371  if (tpMode)
372  return string("DT/10-TestPulses/");
373  if (isBooking)
374  return string("DT/01-Digi/ML");
375  return string("DT/01-Digi/");
376 }
size
Write out results.
Log< level::Info, true > LogVerbatim
int station() const
Return the station number.
Definition: DTChamberId.h:45
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override
Endjob.
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
int getIntegral(TH2F *histo, int, int, int, int, bool)
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
virtual void setEntries(double nentries)
set # of entries
GraphDef * loadGraphDef(const std::string &pbFile)
Definition: TensorFlow.cc:119
void bookHistos(DQMStore::IBooker &, const int wheelId, std::string folder, std::string histoTag)
book the summary histograms
std::vector< float > interpolateLayers(std::vector< float > const &inputs, int size, int targetSize)
MonitorElement * summaryHisto
Definition: ntuple.py:1
#define LogTrace(id)
static std::string const input
Definition: EdmProvDump.cc:50
void dqmEndLuminosityBlock(DQMStore::IBooker &, DQMStore::IGetter &, edm::LuminosityBlock const &, edm::EventSetup const &) override
DQM Client Diagnostic.
T getUntrackedParameter(std::string const &, T const &) const
int firstChannel() const
Returns the wire number of the first wire.
Definition: DTTopology.h:79
void Fill(long long x)
virtual TH2F * getTH2F() const
virtual void Reset()
Remove all data from the ME, keept the empty histogram with all its settings.
std::string getMEName(std::string histoTag, const DTChamberId &chId)
Get the ME name.
const DTGeometry * muonGeom
virtual double getFloatValue() const
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Definition: TensorFlow.cc:271
bool closeSession(Session *&session)
Definition: TensorFlow.cc:233
void beginRun(edm::Run const &run, edm::EventSetup const &context) override
BeginRun.
Transition
Definition: Transition.h:12
MonitorElement * glbSummaryHisto
const DTTopology & specificTopology() const
Definition: DTLayer.cc:37
int runOccupancyTest(TH2F *histo, const DTChamberId &chId, float &chamberPercentage, tensorflow::GraphDef *graphDef, tensorflow::Session *session)
Session * createSession()
Definition: TensorFlow.cc:136
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
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
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:712
~DTOccupancyTestML() override
Destructor.
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:42
HLT enums.
int sector() const
Definition: DTChamberId.h:52
edm::ESGetToken< DTGeometry, MuonGeometryRecord > muonGeomToken_
std::map< int, MonitorElement * > wheelHistos
std::string topFolder(bool isBooking) const
const std::string & fullPath() const
Definition: FileInPath.cc:144
const std::vector< const DTChamber * > & chambers() const
Return a vector of all Chamber.
Definition: DTGeometry.cc:84
step
Definition: StallMonitor.cc:83
static char chambers[264][20]
Definition: ReadPGInfo.cc:243
std::string nameMonitoredHisto
DTOccupancyTestML(const edm::ParameterSet &ps)
Constructor.
int channels() const
Returns the number of wires in the layer.
Definition: DTTopology.h:76
Definition: Run.h:45
virtual double getBinContent(int binx) const
get content of bin (1-D)
const DTLayer * layer(const DTLayerId &id) const
Return a layer given its id.
Definition: DTGeometry.cc:96
virtual void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)