CMS 3D CMS Logo

DTNoiseCalibration.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author G. Mila - INFN Torino
5  * A. Vilela Pereira - INFN Torino
6  */
7 
8 #include "DTNoiseCalibration.h"
9 
10 // Framework
16 
17 // Geometry
22 
23 // Digis
28 
29 // Database
32 
34 
35 #include "TH2F.h"
36 #include "TFile.h"
37 
38 using namespace edm;
39 using namespace std;
40 
42  : digiToken_(consumes<DTDigiCollection>(pset.getParameter<InputTag>("digiLabel"))),
43  useTimeWindow_(pset.getParameter<bool>("useTimeWindow")),
44  triggerWidth_(pset.getParameter<double>("triggerWidth")),
45  timeWindowOffset_(pset.getParameter<int>("timeWindowOffset")),
46  maximumNoiseRate_(pset.getParameter<double>("maximumNoiseRate")),
47  useAbsoluteRate_(pset.getParameter<bool>("useAbsoluteRate")),
48  readDB_(true),
49  defaultTtrig_(0),
50  //fastAnalysis_( pset.getParameter<bool>("fastAnalysis", true) ),
51  wireIdWithHisto_(std::vector<DTWireId>()),
52  lumiMax_(3000),
53  dtGeomToken_(esConsumes<edm::Transition::BeginRun>()),
54  ttrigToken_(
55  esConsumes<edm::Transition::BeginRun>(edm::ESInputTag("", pset.getUntrackedParameter<string>("dbLabel")))) {
56  // Get the debug parameter for verbose output
57  //debug = ps.getUntrackedParameter<bool>("debug");
58  /*// The analysis type
59  // The wheel & sector interested for the time-dependent analysis
60  wh = ps.getUntrackedParameter<int>("wheel", 0);
61  sect = ps.getUntrackedParameter<int>("sector", 6);*/
62 
63  if (pset.exists("defaultTtrig")) {
64  readDB_ = false;
65  defaultTtrig_ = pset.getParameter<int>("defaultTtrig");
66  }
67 
68  if (pset.exists("cellsWithHisto")) {
69  vector<string> cellsWithHisto = pset.getParameter<vector<string> >("cellsWithHisto");
70  for (vector<string>::const_iterator cell = cellsWithHisto.begin(); cell != cellsWithHisto.end(); ++cell) {
71  //FIXME: Use regex to check whether format is right
72  if ((!cell->empty()) && (*cell) != "None") {
73  stringstream linestr;
74  int wheel, station, sector, sl, layer, wire;
75  linestr << (*cell);
76  linestr >> wheel >> station >> sector >> sl >> layer >> wire;
77  wireIdWithHisto_.push_back(DTWireId(wheel, station, sector, sl, layer, wire));
78  }
79  }
80  }
81 
82  // The root file which will contain the histos
83  string rootFileName = pset.getUntrackedParameter<string>("rootFileName", "noise.root");
84  rootFile_ = new TFile(rootFileName.c_str(), "RECREATE");
85  rootFile_->cd();
86 }
87 
89  LogVerbatim("Calibration") << "[DTNoiseCalibration]: Begin job";
90 
91  nevents_ = 0;
92 
93  TH1::SetDefaultSumw2(true);
94  int numBin = (triggerWidth_ * 32 / 25) / 50;
95  hTDCTriggerWidth_ = new TH1F("TDC_Time_Distribution", "TDC_Time_Distribution", numBin, 0, triggerWidth_ * 32 / 25);
96 }
97 
99  // Get the DT Geometry
100  dtGeom_ = setup.getHandle(dtGeomToken_);
101  // tTrig
102  if (readDB_)
103  tTrigMap_ = &setup.getData(ttrigToken_);
104  runBeginTime_ = time_t(run.beginTime().value() >> 32);
105  runEndTime_ = time_t(run.endTime().value() >> 32);
106 }
107 
109  ++nevents_;
110 
111  // Get the digis from the event
112  const Handle<DTDigiCollection>& dtdigis = event.getHandle(digiToken_);
113 
114  time_t eventTime = time_t(event.time().value() >> 32);
115  unsigned int lumiSection = event.luminosityBlock();
116 
117  // Loop over digis
119  for (dtLayerId_It = dtdigis->begin(); dtLayerId_It != dtdigis->end(); ++dtLayerId_It) {
120  // Define time window
121  float upperLimit = 0.;
122  if (useTimeWindow_) {
123  if (readDB_) {
124  float tTrig, tTrigRMS, kFactor;
125  DTSuperLayerId slId = ((*dtLayerId_It).first).superlayerId();
126  int status = tTrigMap_->get(slId, tTrig, tTrigRMS, kFactor, DTTimeUnits::counts);
127  if (status != 0)
128  throw cms::Exception("DTNoiseCalibration") << "Could not find tTrig entry in DB for" << slId << endl;
129  upperLimit = tTrig - timeWindowOffset_;
130  } else {
131  upperLimit = defaultTtrig_ - timeWindowOffset_;
132  }
133  }
134 
135  double triggerWidth_s = 0.;
136  if (useTimeWindow_)
137  triggerWidth_s = ((upperLimit * 25) / 32) / 1e9;
138  else
139  triggerWidth_s = double(triggerWidth_ / 1e9);
140  LogTrace("Calibration") << ((*dtLayerId_It).first).superlayerId() << " Trigger width (s): " << triggerWidth_s;
141 
142  for (DTDigiCollection::const_iterator digiIt = ((*dtLayerId_It).second).first;
143  digiIt != ((*dtLayerId_It).second).second;
144  ++digiIt) {
145  //Check the TDC trigger width
146  int tdcTime = (*digiIt).countsTDC();
147  if (!useTimeWindow_) {
148  if ((((float)tdcTime * 25) / 32) > triggerWidth_) {
149  LogError("Calibration") << "Digi has a TDC time (ns) higher than the pre-defined TDC trigger width: "
150  << ((float)tdcTime * 25) / 32;
151  continue;
152  }
153  }
154 
155  hTDCTriggerWidth_->Fill(tdcTime);
156 
157  if (useTimeWindow_ && tdcTime > upperLimit)
158  continue;
159 
160  const DTLayerId dtLId = (*dtLayerId_It).first;
161  const DTTopology& dtTopo = dtGeom_->layer(dtLId)->specificTopology();
162  const int firstWire = dtTopo.firstChannel();
163  const int lastWire = dtTopo.lastChannel();
164  const int nWires = lastWire - firstWire + 1;
165 
166  // Book the occupancy histos
167  if (theHistoOccupancyMap_.find(dtLId) == theHistoOccupancyMap_.end()) {
168  string histoName = "DigiOccupancy_" + getLayerName(dtLId);
169  rootFile_->cd();
170  TH1F* hOccupancyHisto = new TH1F(histoName.c_str(), histoName.c_str(), nWires, firstWire, lastWire + 1);
171  LogTrace("Calibration") << " Created occupancy Histo: " << hOccupancyHisto->GetName();
172  theHistoOccupancyMap_[dtLId] = hOccupancyHisto;
173  }
174  theHistoOccupancyMap_[dtLId]->Fill((*digiIt).wire(), 1. / triggerWidth_s);
175 
176  // Histos vs lumi section
177  const DTChamberId dtChId = dtLId.chamberId();
178  if (chamberOccupancyVsLumiMap_.find(dtChId) == chamberOccupancyVsLumiMap_.end()) {
179  string histoName = "OccupancyVsLumi_" + getChamberName(dtChId);
180  rootFile_->cd();
181  TH1F* hOccupancyVsLumiHisto = new TH1F(histoName.c_str(), histoName.c_str(), lumiMax_, 0, lumiMax_);
182  LogTrace("Calibration") << " Created occupancy histo: " << hOccupancyVsLumiHisto->GetName();
183  chamberOccupancyVsLumiMap_[dtChId] = hOccupancyVsLumiHisto;
184  }
185  chamberOccupancyVsLumiMap_[dtChId]->Fill(lumiSection, 1. / triggerWidth_s);
186 
187  const DTWireId wireId(dtLId, (*digiIt).wire());
188  if (find(wireIdWithHisto_.begin(), wireIdWithHisto_.end(), wireId) != wireIdWithHisto_.end()) {
189  if (theHistoOccupancyVsLumiMap_.find(wireId) == theHistoOccupancyVsLumiMap_.end()) {
190  string histoName = "OccupancyVsLumi_" + getChannelName(wireId);
191  rootFile_->cd();
192  TH1F* hOccupancyVsLumiHisto = new TH1F(histoName.c_str(), histoName.c_str(), lumiMax_, 0, lumiMax_);
193  LogTrace("Calibration") << " Created occupancy histo: " << hOccupancyVsLumiHisto->GetName();
194  theHistoOccupancyVsLumiMap_[wireId] = hOccupancyVsLumiHisto;
195  }
196  theHistoOccupancyVsLumiMap_[wireId]->Fill(lumiSection, 1. / triggerWidth_s);
197  }
198 
199  // Histos vs time
200  if (chamberOccupancyVsTimeMap_.find(dtChId) == chamberOccupancyVsTimeMap_.end()) {
201  string histoName = "OccupancyVsTime_" + getChamberName(dtChId);
202  float secPerBin = 20.0;
203  unsigned int nBins = ((unsigned int)(runEndTime_ - runBeginTime_)) / secPerBin;
204  rootFile_->cd();
205  TH1F* hOccupancyVsTimeHisto = new TH1F(
206  histoName.c_str(), histoName.c_str(), nBins, (unsigned int)runBeginTime_, (unsigned int)runEndTime_);
207  for (int k = 0; k < hOccupancyVsTimeHisto->GetNbinsX(); ++k) {
208  if (k % 10 == 0) {
209  unsigned int binLowEdge = hOccupancyVsTimeHisto->GetBinLowEdge(k + 1);
210  time_t timeValue = time_t(binLowEdge);
211  hOccupancyVsTimeHisto->GetXaxis()->SetBinLabel((k + 1), ctime(&timeValue));
212  }
213  }
214  size_t lastBin = hOccupancyVsTimeHisto->GetNbinsX();
215  unsigned int binUpperEdge =
216  hOccupancyVsTimeHisto->GetBinLowEdge(lastBin) + hOccupancyVsTimeHisto->GetBinWidth(lastBin);
217  time_t timeValue = time_t(binUpperEdge);
218  hOccupancyVsTimeHisto->GetXaxis()->SetBinLabel((lastBin), ctime(&timeValue));
219 
220  LogTrace("Calibration") << " Created occupancy histo: " << hOccupancyVsTimeHisto->GetName();
221  chamberOccupancyVsTimeMap_[dtChId] = hOccupancyVsTimeHisto;
222  }
223  chamberOccupancyVsTimeMap_[dtChId]->Fill((unsigned int)eventTime, 1. / triggerWidth_s);
224  }
225  }
226 }
227 
229  LogVerbatim("Calibration") << "[DTNoiseCalibration] Total number of events analyzed: " << nevents_;
230 
231  // Save the TDC digi plot
232  rootFile_->cd();
233  hTDCTriggerWidth_->Write();
234 
235  double normalization = 1. / double(nevents_);
236 
237  for (map<DTWireId, TH1F*>::const_iterator wHisto = theHistoOccupancyVsLumiMap_.begin();
238  wHisto != theHistoOccupancyVsLumiMap_.end();
239  ++wHisto) {
240  (*wHisto).second->Scale(normalization);
241  (*wHisto).second->Write();
242  }
243 
244  for (map<DTChamberId, TH1F*>::const_iterator chHisto = chamberOccupancyVsLumiMap_.begin();
245  chHisto != chamberOccupancyVsLumiMap_.end();
246  ++chHisto) {
247  (*chHisto).second->Scale(normalization);
248  (*chHisto).second->Write();
249  }
250 
251  for (map<DTChamberId, TH1F*>::const_iterator chHisto = chamberOccupancyVsTimeMap_.begin();
252  chHisto != chamberOccupancyVsTimeMap_.end();
253  ++chHisto) {
254  (*chHisto).second->Scale(normalization);
255  (*chHisto).second->Write();
256  }
257 
258  // Save on file the occupancy histos and write the list of noisy cells
259  DTStatusFlag statusMap;
260  for (map<DTLayerId, TH1F*>::const_iterator lHisto = theHistoOccupancyMap_.begin();
261  lHisto != theHistoOccupancyMap_.end();
262  ++lHisto) {
263  if ((*lHisto).second) {
264  (*lHisto).second->Scale(normalization);
265  rootFile_->cd();
266  (*lHisto).second->Write();
267  const DTTopology& dtTopo = dtGeom_->layer((*lHisto).first)->specificTopology();
268  const int firstWire = dtTopo.firstChannel();
269  const int lastWire = dtTopo.lastChannel();
270  const int nWires = lastWire - firstWire + 1;
271  // Find average in layer
272  double averageRate = 0.;
273  for (int bin = 1; bin <= (*lHisto).second->GetNbinsX(); ++bin)
274  averageRate += (*lHisto).second->GetBinContent(bin);
275 
276  if (nWires)
277  averageRate /= nWires;
278  LogTrace("Calibration") << " Average rate = " << averageRate;
279 
280  for (int i_wire = firstWire; i_wire <= lastWire; ++i_wire) {
281  // From definition of "noisy cell"
282  int bin = i_wire - firstWire + 1;
283  double channelRate = (*lHisto).second->GetBinContent(bin);
284  double rateOffset = (useAbsoluteRate_) ? 0. : averageRate;
285  if ((channelRate - rateOffset) > maximumNoiseRate_) {
286  DTWireId wireID((*lHisto).first, i_wire);
287  statusMap.setCellNoise(wireID, true);
288  LogVerbatim("Calibration") << ">>> Channel noisy: " << wireID;
289  }
290  }
291  }
292  }
293  LogVerbatim("Calibration") << "Writing noise map object to DB";
294  string record = "DTStatusFlagRcd";
295  DTCalibDBUtils::writeToDB<DTStatusFlag>(record, statusMap);
296 }
297 
299 
301  string channelName = "Wh" + std::to_string(wId.wheel()) + "_St" + std::to_string(wId.station()) + "_Sec" +
302  std::to_string(wId.sector()) + "_SL" + std::to_string(wId.superlayer()) + "_L" +
303  std::to_string(wId.layer()) + "_W" + std::to_string(wId.wire());
304  return channelName;
305 }
306 
307 string DTNoiseCalibration::getLayerName(const DTLayerId& lId) const {
308  const DTSuperLayerId dtSLId = lId.superlayerId();
309  const DTChamberId dtChId = dtSLId.chamberId();
310  string layerName = "W" + std::to_string(dtChId.wheel()) + "_St" + std::to_string(dtChId.station()) + "_Sec" +
311  std::to_string(dtChId.sector()) + "_SL" + std::to_string(dtSLId.superlayer()) + "_L" +
312  std::to_string(lId.layer());
313 
314  return layerName;
315 }
316 
318  const DTChamberId dtChId = dtSLId.chamberId();
319 
320  string superLayerName = "W" + std::to_string(dtChId.wheel()) + "_St" + std::to_string(dtChId.station()) + "_Sec" +
321  std::to_string(dtChId.sector()) + "_SL" + std::to_string(dtSLId.superlayer());
322 
323  return superLayerName;
324 }
325 
326 string DTNoiseCalibration::getChamberName(const DTChamberId& dtChId) const {
327  string chamberName = "W" + std::to_string(dtChId.wheel()) + "_St" + std::to_string(dtChId.station()) + "_Sec" +
328  std::to_string(dtChId.sector());
329 
330  return chamberName;
331 }
Log< level::Info, true > LogVerbatim
int station() const
Return the station number.
Definition: DTChamberId.h:42
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
const double triggerWidth_
int wire() const
Return the wire number.
Definition: DTWireId.h:42
void analyze(const edm::Event &e, const edm::EventSetup &c) override
edm::ESHandle< DTGeometry > dtGeom_
std::vector< DTWireId > wireIdWithHisto_
std::map< DTLayerId, TH1F * > theHistoOccupancyMap_
void beginJob() override
std::string to_string(const V &value)
Definition: OMSAccess.h:77
void beginRun(const edm::Run &run, const edm::EventSetup &setup) override
Log< level::Error, false > LogError
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
std::map< DTChamberId, TH1F * > chamberOccupancyVsTimeMap_
std::map< DTChamberId, TH1F * > chamberOccupancyVsLumiMap_
~DTNoiseCalibration() override
Destructor.
#define LogTrace(id)
std::string getChamberName(const DTChamberId &) const
std::map< DTWireId, TH1F * > theHistoOccupancyVsLumiMap_
DTNoiseCalibration(const edm::ParameterSet &ps)
Constructor.
int firstChannel() const
Returns the wire number of the first wire.
Definition: DTTopology.h:79
constexpr std::array< uint8_t, layerIndexSize< TrackerTraits > > layer
std::string getSuperLayerName(const DTSuperLayerId &) const
U second(std::pair< T, U > const &p)
const double maximumNoiseRate_
DTChamberId chamberId() const
Return the corresponding ChamberId.
int setCellNoise(int wheelId, int stationId, int sectorId, int slId, int layerId, int cellId, bool flag)
Transition
Definition: Transition.h:12
const DTTopology & specificTopology() const
Definition: DTLayer.cc:37
int superlayer() const
Return the superlayer number (deprecated method name)
const edm::ESGetToken< DTTtrig, DTTtrigRcd > ttrigToken_
std::vector< DigiType >::const_iterator const_iterator
int layer() const
Return the layer number.
Definition: DTLayerId.h:42
int get(int wheelId, int stationId, int sectorId, int slId, float &tTrig, float &tTrms, float &kFact, DTTimeUnits::type unit) const
get content
Definition: DTTtrig.cc:59
const edm::ESGetToken< DTGeometry, MuonGeometryRecord > dtGeomToken_
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:39
HLT enums.
int sector() const
Definition: DTChamberId.h:49
int lastChannel() const
Returns the wire number of the last wire.
Definition: DTTopology.h:81
std::string channelName(EcalElectronicsMapping const *, uint32_t, BinningType _btype=kDCC)
DTSuperLayerId superlayerId() const
Return the corresponding SuperLayerId.
Definition: DTLayerId.h:45
void endJob() override
const edm::EDGetTokenT< DTDigiCollection > digiToken_
edm::ESHandle< DTTtrig > tTrigMap_
Definition: event.py:1
Definition: Run.h:45
std::string getChannelName(const DTWireId &) const
const DTLayer * layer(const DTLayerId &id) const
Return a layer given its id.
Definition: DTGeometry.cc:96
std::string getLayerName(const DTLayerId &) const