File indexing completed on 2024-09-11 04:32:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "FWCore/Framework/interface/ESHandle.h"
0011 #include "FWCore/Framework/interface/Event.h"
0012 #include "FWCore/Framework/interface/EventSetup.h"
0013 #include "FWCore/Framework/interface/MakerMacros.h"
0014 #include "FWCore/Framework/interface/Run.h"
0015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0016 #include "FWCore/Utilities/interface/InputTag.h"
0017
0018 #include "DQMServices/Core/interface/DQMOneEDAnalyzer.h"
0019 #include "DQMServices/Core/interface/DQMStore.h"
0020
0021 #include "DataFormats/CTPPSDigi/interface/TotemFEDInfo.h"
0022 #include "DataFormats/CTPPSDigi/interface/TotemVFATStatus.h"
0023 #include "DataFormats/CTPPSReco/interface/TotemRPLocalTrack.h"
0024 #include "DataFormats/Common/interface/DetSetVector.h"
0025 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0026 #include "DataFormats/Provenance/interface/EventRange.h"
0027
0028 #include "DataFormats/CTPPSDetId/interface/TotemTimingDetId.h"
0029 #include "DataFormats/CTPPSDigi/interface/TotemTimingDigi.h"
0030 #include "DataFormats/CTPPSReco/interface/TotemTimingRecHit.h"
0031
0032 #include "DataFormats/CTPPSDetId/interface/TotemRPDetId.h"
0033 #include "DataFormats/CTPPSReco/interface/TotemRPLocalTrack.h"
0034 #include "Geometry/Records/interface/VeryForwardRealGeometryRecord.h"
0035 #include "Geometry/VeryForwardGeometryBuilder/interface/CTPPSGeometry.h"
0036
0037 #include <string>
0038
0039
0040
0041 namespace totemds {
0042 struct Cache {
0043 std::unordered_map<unsigned int, std::unique_ptr<TH2F>> hitDistribution2dMap;
0044
0045 std::unordered_map<unsigned int, unsigned long> hitsCounterMap;
0046 };
0047 }
0048
0049 class TotemTimingDQMSource : public DQMOneEDAnalyzer<edm::LuminosityBlockCache<totemds::Cache>> {
0050 public:
0051 TotemTimingDQMSource(const edm::ParameterSet &);
0052 ~TotemTimingDQMSource() override;
0053
0054 protected:
0055 void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override;
0056 void bookHistograms(DQMStore::IBooker &, const edm::Run &, const edm::EventSetup &) override;
0057 void analyze(const edm::Event &, const edm::EventSetup &) override;
0058 std::shared_ptr<totemds::Cache> globalBeginLuminosityBlock(const edm::LuminosityBlock &,
0059 const edm::EventSetup &) const override;
0060 void globalEndLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) override;
0061
0062 private:
0063
0064 static const double SEC_PER_LUMI_SECTION;
0065
0066
0067 static const double LHC_CLOCK_PERIOD_NS;
0068 static const double DQM_FRACTION_OF_EVENTS;
0069
0070 static const double HIT_RATE_FACTOR;
0071 static const double DISPLAY_RESOLUTION_FOR_HITS_MM;
0072
0073
0074 static const double INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
0075 static const double TOMOGRAPHY_RESOLUTION_MM;
0076 static const double SAMPIC_SAMPLING_PERIOD_NS;
0077 static const double SAMPIC_MAX_NUMBER_OF_SAMPLES;
0078 static const double SAMPIC_ADC_V;
0079 static const int CTPPS_NUM_OF_ARMS;
0080 static const int TOTEM_TIMING_STATION_ID;
0081 static const int TOTEM_STATION_210;
0082 static const int TOTEM_STATION_220;
0083 static const int TOTEM_TIMING_TOP_RP_ID;
0084 static const int TOTEM_TIMING_BOT_RP_ID;
0085 static const int TOTEM_STRIP_MIN_RP_ID;
0086 static const int TOTEM_STRIP_MAX_RP_ID;
0087 static const int CTPPS_NEAR_RP_ID;
0088 static const int CTPPS_FAR_RP_ID;
0089 static const int TOTEM_TIMING_NUM_OF_PLANES;
0090 static const int TOTEM_TIMING_NUM_OF_CHANNELS;
0091 static const int TOTEM_TIMING_FED_ID_45;
0092 static const int TOTEM_TIMING_FED_ID_56;
0093 static const float COS_8_DEG;
0094 static const float SIN_8_DEG;
0095
0096 edm::EDGetTokenT<edm::DetSetVector<TotemRPLocalTrack>> tokenLocalTrack_;
0097 edm::EDGetTokenT<edm::DetSetVector<TotemTimingDigi>> tokenDigi_;
0098 edm::EDGetTokenT<edm::DetSetVector<TotemTimingRecHit>> tokenRecHit_;
0099 edm::EDGetTokenT<std::vector<TotemFEDInfo>> tokenFEDInfo_;
0100
0101 edm::ESGetToken<CTPPSGeometry, VeryForwardRealGeometryRecord> geometryToken_;
0102 edm::ESGetToken<CTPPSGeometry, VeryForwardRealGeometryRecord> geometryTokenBeginRun_;
0103
0104 double minimumStripAngleForTomography_;
0105 double maximumStripAngleForTomography_;
0106 unsigned int samplesForNoise_;
0107 bool perLSsaving_;
0108 unsigned int verbosity_;
0109 edm::TimeValue_t timeOfPreviousEvent_;
0110
0111 float verticalShiftBot_, verticalShiftTop_;
0112
0113
0114 struct GlobalPlots {
0115 MonitorElement *digiSentPercentage = nullptr;
0116
0117 GlobalPlots() {}
0118 GlobalPlots(DQMStore::IBooker &ibooker);
0119 };
0120
0121 GlobalPlots globalPlot_;
0122
0123
0124 struct PotPlots {
0125
0126 MonitorElement *activityPerBX = nullptr;
0127 MonitorElement *digiDistribution = nullptr;
0128 MonitorElement *dataSamplesRaw = nullptr;
0129 MonitorElement *baseline = nullptr;
0130 MonitorElement *noiseRMS = nullptr;
0131
0132 MonitorElement *digiSent = nullptr;
0133 MonitorElement *digiAll = nullptr;
0134 MonitorElement *digiSentPercentage = nullptr;
0135
0136
0137 MonitorElement *hitDistribution2d = nullptr;
0138 MonitorElement *hitDistribution2dWithTime = nullptr;
0139 MonitorElement *hitDistribution2d_lumisection = nullptr;
0140
0141 MonitorElement *recHitTime = nullptr;
0142 MonitorElement *amplitude = nullptr;
0143 MonitorElement *baselineRMS = nullptr;
0144 MonitorElement *tirggerCellTime = nullptr;
0145 MonitorElement *meanAmplitude = nullptr;
0146 MonitorElement *cellOfMax = nullptr;
0147
0148 MonitorElement *hitRate = nullptr;
0149
0150 MonitorElement *planesWithDigis = nullptr;
0151 MonitorElement *planesWithTime = nullptr;
0152
0153
0154
0155 MonitorElement *stripTomography210 = nullptr;
0156 MonitorElement *stripTomography220 = nullptr;
0157
0158 std::set<unsigned int> planesWithDigisSet;
0159 std::set<unsigned int> planesWithTimeSet;
0160
0161 PotPlots() {}
0162 PotPlots(DQMStore::IBooker &ibooker, unsigned int id);
0163 };
0164
0165 std::unordered_map<unsigned int, PotPlots> potPlots_;
0166
0167
0168 struct PlanePlots {
0169 MonitorElement *digiDistribution = nullptr;
0170
0171 MonitorElement *hitProfile = nullptr;
0172 MonitorElement *hitMultiplicity = nullptr;
0173 MonitorElement *hitMultiplicityWithTime = nullptr;
0174
0175 PlanePlots() {}
0176 PlanePlots(DQMStore::IBooker &ibooker, unsigned int id);
0177 };
0178
0179 std::unordered_map<unsigned int, PlanePlots> planePlots_;
0180
0181
0182 struct ChannelPlots {
0183
0184 MonitorElement *activityPerBX = nullptr;
0185 MonitorElement *dataSamplesRaw = nullptr;
0186 MonitorElement *cellOfMax = nullptr;
0187 MonitorElement *maxTimeAfterTrigger = nullptr;
0188
0189
0190 MonitorElement *tirggerCellTime = nullptr;
0191 MonitorElement *recHitTime = nullptr;
0192 MonitorElement *amplitude = nullptr;
0193 MonitorElement *noiseSamples = nullptr;
0194
0195 MonitorElement *hitTime = nullptr;
0196 MonitorElement *hitRate = nullptr;
0197
0198 MonitorElement *stripTomography210 = nullptr;
0199 MonitorElement *stripTomography220 = nullptr;
0200
0201 ChannelPlots() {}
0202 ChannelPlots(DQMStore::IBooker &ibooker, unsigned int id);
0203 };
0204
0205 std::unordered_map<unsigned int, ChannelPlots> channelPlots_;
0206 };
0207
0208
0209
0210
0211 const double TotemTimingDQMSource::SEC_PER_LUMI_SECTION = 23.31;
0212 const double TotemTimingDQMSource::LHC_CLOCK_PERIOD_NS = 24.95;
0213 const double TotemTimingDQMSource::DQM_FRACTION_OF_EVENTS = 1.;
0214 const double TotemTimingDQMSource::HIT_RATE_FACTOR = DQM_FRACTION_OF_EVENTS / SEC_PER_LUMI_SECTION;
0215 const double TotemTimingDQMSource::DISPLAY_RESOLUTION_FOR_HITS_MM = 0.1;
0216 const double TotemTimingDQMSource::INV_DISPLAY_RESOLUTION_FOR_HITS_MM = 1. / DISPLAY_RESOLUTION_FOR_HITS_MM;
0217 const double TotemTimingDQMSource::TOMOGRAPHY_RESOLUTION_MM = 1;
0218 const double TotemTimingDQMSource::SAMPIC_SAMPLING_PERIOD_NS = 1. / 7.8e9;
0219 const double TotemTimingDQMSource::SAMPIC_MAX_NUMBER_OF_SAMPLES = 64;
0220 const double TotemTimingDQMSource::SAMPIC_ADC_V = 1. / 256;
0221 const int TotemTimingDQMSource::CTPPS_NUM_OF_ARMS = 2;
0222 const int TotemTimingDQMSource::TOTEM_TIMING_STATION_ID = 2;
0223 const int TotemTimingDQMSource::TOTEM_STATION_210 = 0;
0224 const int TotemTimingDQMSource::TOTEM_STATION_220 = 2;
0225 const int TotemTimingDQMSource::TOTEM_TIMING_TOP_RP_ID = 0;
0226 const int TotemTimingDQMSource::TOTEM_TIMING_BOT_RP_ID = 1;
0227 const int TotemTimingDQMSource::TOTEM_STRIP_MIN_RP_ID = 4;
0228 const int TotemTimingDQMSource::TOTEM_STRIP_MAX_RP_ID = 5;
0229 const int TotemTimingDQMSource::CTPPS_NEAR_RP_ID = 2;
0230 const int TotemTimingDQMSource::CTPPS_FAR_RP_ID = 3;
0231 const int TotemTimingDQMSource::TOTEM_TIMING_NUM_OF_PLANES = 4;
0232 const int TotemTimingDQMSource::TOTEM_TIMING_NUM_OF_CHANNELS = 12;
0233 const int TotemTimingDQMSource::TOTEM_TIMING_FED_ID_45 = FEDNumbering::MAXTotemRPTimingVerticalFEDID;
0234 const int TotemTimingDQMSource::TOTEM_TIMING_FED_ID_56 = FEDNumbering::MINTotemRPTimingVerticalFEDID;
0235 const float TotemTimingDQMSource::COS_8_DEG = 0.990268;
0236 const float TotemTimingDQMSource::SIN_8_DEG = -0.139173;
0237
0238
0239
0240 TotemTimingDQMSource::GlobalPlots::GlobalPlots(DQMStore::IBooker &ibooker) {
0241 ibooker.setCurrentFolder("CTPPS/TimingFastSilicon");
0242
0243 digiSentPercentage = ibooker.book2D(
0244 "sent digis percentage", "sent digis percentage (sampic);board + 0.5 sampic;channel", 14, -0.5, 6.5, 16, 0, 16);
0245 }
0246
0247
0248
0249 TotemTimingDQMSource::PotPlots::PotPlots(DQMStore::IBooker &ibooker, unsigned int id) {
0250 std::string path, title;
0251 TotemTimingDetId(id).rpName(path, TotemTimingDetId::nPath);
0252 ibooker.setCurrentFolder(path);
0253
0254 TotemTimingDetId(id).rpName(title, TotemTimingDetId::nFull);
0255
0256 activityPerBX = ibooker.book1D("activity per BX CMS", title + " Activity per BX;Event.BX", 3600, -1.5, 3598. + 0.5);
0257
0258 digiDistribution =
0259 ibooker.book2D("digi distribution", title + " digi distribution;plane;channel", 10, -0.5, 4.5, 12, 0, 12);
0260
0261 dataSamplesRaw = ibooker.book1D("raw Samples", title + " Raw Samples; ADC", 256, 0, 256);
0262
0263 baseline = ibooker.book2D("baseline", title + " baseline (V);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
0264 noiseRMS = ibooker.book2D("noise RMS", title + " noise RMS (V);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
0265
0266 digiSent =
0267 ibooker.book2D("digis sent", title + " digi sent (sampic);board + 0.5 sampic;channel", 14, -0.5, 6.5, 16, 0, 16);
0268 digiAll =
0269 ibooker.book2D("all digis", title + " all digis(sampic);board + 0.5 sampic;channel", 14, -0.5, 6.5, 16, 0, 16);
0270 digiSentPercentage = ibooker.book2D("sent digis percentage",
0271 title + " sent digis percentage (sampic);board + 0.5 sampic;channel",
0272 14,
0273 -0.5,
0274 6.5,
0275 16,
0276 0,
0277 16);
0278
0279 hitDistribution2d = ibooker.book2D("hits in planes",
0280 title + " hits in planes;plane number;x (mm)",
0281 18,
0282 -0.5,
0283 4,
0284 15. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0285 0,
0286 15);
0287 hitDistribution2dWithTime = ibooker.book2D("hits in planes with time",
0288 title + " hits in planes with time;plane number;x (mm)",
0289 18,
0290 -0.5,
0291 4,
0292 15. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0293 0,
0294 15);
0295 hitDistribution2d_lumisection = ibooker.book2D("hits in planes lumisection",
0296 title + " hits in planes in the last lumisection;plane number;x (mm)",
0297 18,
0298 -0.5,
0299 4,
0300 15. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0301 0,
0302 15);
0303
0304 recHitTime = ibooker.book1D("recHit time", title + " time in the recHits; t (ns)", 500, -25, 25);
0305 amplitude = ibooker.book1D("amplitude", title + " amplitude above baseline; amplitude (V)", 50, 0, 1);
0306 tirggerCellTime = ibooker.book1D("trigger cell time", title + " Trigger Cell Time; t (ns)", 390, -25, 25);
0307 baselineRMS = ibooker.book2D("noise RMS", title + " noise RMS (V);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
0308 meanAmplitude =
0309 ibooker.book2D("mean amplitude", title + " Mean Amplitude (V);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
0310 cellOfMax = ibooker.book2D("cell of max", title + " cell of max (0-23);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
0311
0312 hitRate = ibooker.book2D("hit rate", title + " hit rate (Hz);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
0313
0314 planesWithDigis = ibooker.book1D(
0315 "active planes digis", title + " active planes with digis sent (per event);number of active planes", 6, -0.5, 5.5);
0316 planesWithTime = ibooker.book1D(
0317 "active planes with time", title + " active planes with time (per event);number of active planes", 6, -0.5, 5.5);
0318
0319
0320
0321
0322 stripTomography210 =
0323 ibooker.book2D("tomography 210",
0324 title + " tomography (only with time) with strips 210 (all planes);x + 50*plane(mm);y (mm)",
0325 190 / TOMOGRAPHY_RESOLUTION_MM,
0326 -20,
0327 170,
0328 25 / TOMOGRAPHY_RESOLUTION_MM,
0329 0,
0330 25);
0331 stripTomography220 =
0332 ibooker.book2D("tomography 220",
0333 title + " tomography (only with time) with strips 220 (all planes);x + 50*plane(mm);y (mm)",
0334 190 / TOMOGRAPHY_RESOLUTION_MM,
0335 -20,
0336 170,
0337 25 / TOMOGRAPHY_RESOLUTION_MM,
0338 0,
0339 25);
0340 }
0341
0342
0343
0344 TotemTimingDQMSource::PlanePlots::PlanePlots(DQMStore::IBooker &ibooker, unsigned int id) {
0345 std::string path, title;
0346 TotemTimingDetId(id).planeName(path, TotemTimingDetId::nPath);
0347 ibooker.setCurrentFolder(path);
0348
0349 TotemTimingDetId(id).planeName(title, TotemTimingDetId::nFull);
0350
0351 digiDistribution = ibooker.book1D("digi distribution", title + " digi distribution;channel", 12, 0, 12);
0352
0353 hitProfile = ibooker.book1D("hit distribution with time",
0354 title + " hit distribution (with time);y (+ 15 for x>3) (mm)",
0355 30. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0356 0,
0357 30);
0358
0359 hitMultiplicity = ibooker.book1D("channels per plane", title + " channels per plane; ch per plane", 13, -0.5, 12.5);
0360
0361 hitMultiplicityWithTime = ibooker.book1D(
0362 "channels per plane with time", title + " channels per plane with time; ch per plane", 13, -0.5, 12.5);
0363 }
0364
0365
0366
0367 TotemTimingDQMSource::ChannelPlots::ChannelPlots(DQMStore::IBooker &ibooker, unsigned int id) {
0368 std::string path, title;
0369 TotemTimingDetId(id).channelName(path, TotemTimingDetId::nPath);
0370 ibooker.setCurrentFolder(path);
0371
0372 TotemTimingDetId(id).channelName(title, TotemTimingDetId::nFull);
0373
0374 activityPerBX = ibooker.book1D("activity per BX", title + " Activity per BX;Event.BX", 1000, -1.5, 998. + 0.5);
0375 dataSamplesRaw = ibooker.book1D("raw samples", title + " Raw Samples; ADC", 256, 0, 256);
0376 cellOfMax = ibooker.book1D("cell of max", title + " cell of max; cell", 24, 0, 24);
0377
0378 tirggerCellTime = ibooker.book1D("sampic trigger time", title + " Sampic Trigger Time; t (ns)", 100, -25, 25);
0379 recHitTime = ibooker.book1D("recHit Time", title + " recHit Time; t (ns)", 500, -25, 25);
0380 amplitude = ibooker.book1D("amplitude", title + " amplitude above baseline; amplitude (V)", 50, 0, 1);
0381 noiseSamples = ibooker.book1D("noise samples", title + " noise samples; V", 50, 0, 1);
0382
0383 hitTime = ibooker.book1D("hit time", title + "hit time;t - t_previous (us)", 100, 0, 10000);
0384 hitRate = ibooker.book1D("hit rate", title + "hit rate;rate (Hz)", 100, 0, 10000);
0385
0386 stripTomography210 = ibooker.book2D("tomography 210",
0387 title + " tomography with strips 210;x (mm);y (mm)",
0388 20 / TOMOGRAPHY_RESOLUTION_MM,
0389 -20,
0390 20,
0391 25 / TOMOGRAPHY_RESOLUTION_MM,
0392 0,
0393 25);
0394 stripTomography220 = ibooker.book2D("tomography 220",
0395 title + " tomography with strips 220;x (mm);y (mm)",
0396 20 / TOMOGRAPHY_RESOLUTION_MM,
0397 -20,
0398 20,
0399 25 / TOMOGRAPHY_RESOLUTION_MM,
0400 0,
0401 25);
0402 }
0403
0404
0405
0406 TotemTimingDQMSource::TotemTimingDQMSource(const edm::ParameterSet &ps)
0407 : tokenLocalTrack_(
0408 consumes<edm::DetSetVector<TotemRPLocalTrack>>(ps.getUntrackedParameter<edm::InputTag>("tagLocalTrack"))),
0409 tokenDigi_(consumes<edm::DetSetVector<TotemTimingDigi>>(ps.getUntrackedParameter<edm::InputTag>("tagDigi"))),
0410 tokenRecHit_(
0411 consumes<edm::DetSetVector<TotemTimingRecHit>>(ps.getUntrackedParameter<edm::InputTag>("tagRecHits"))),
0412
0413
0414 tokenFEDInfo_(consumes<std::vector<TotemFEDInfo>>(ps.getUntrackedParameter<edm::InputTag>("tagFEDInfo"))),
0415 geometryToken_(esConsumes()),
0416 geometryTokenBeginRun_(esConsumes<edm::Transition::BeginRun>()),
0417 minimumStripAngleForTomography_(ps.getParameter<double>("minimumStripAngleForTomography")),
0418 maximumStripAngleForTomography_(ps.getParameter<double>("maximumStripAngleForTomography")),
0419 samplesForNoise_(ps.getUntrackedParameter<unsigned int>("samplesForNoise", 5)),
0420 perLSsaving_(ps.getUntrackedParameter<bool>("perLSsaving", false)),
0421 verbosity_(ps.getUntrackedParameter<unsigned int>("verbosity", 0)),
0422 timeOfPreviousEvent_(0) {}
0423
0424
0425
0426 TotemTimingDQMSource::~TotemTimingDQMSource() {}
0427
0428
0429
0430 void TotemTimingDQMSource::dqmBeginRun(const edm::Run &iRun, const edm::EventSetup &iSetup) {
0431
0432 auto const &geom = iSetup.getData(geometryTokenBeginRun_);
0433
0434 const TotemTimingDetId detid_top(0, TOTEM_TIMING_STATION_ID, TOTEM_TIMING_BOT_RP_ID, 0, 0);
0435 const TotemTimingDetId detid_bot(0, TOTEM_TIMING_STATION_ID, TOTEM_TIMING_TOP_RP_ID, 0, 7);
0436 verticalShiftTop_ = 0;
0437 verticalShiftBot_ = 0;
0438 {
0439 const DetGeomDesc *det_top = geom.sensorNoThrow(detid_top);
0440 if (det_top) {
0441 verticalShiftTop_ = det_top->translation().y() + det_top->getDiamondDimensions().yHalfWidth;
0442 }
0443 const DetGeomDesc *det_bot = geom.sensorNoThrow(detid_bot);
0444 if (det_bot)
0445 verticalShiftBot_ = det_bot->translation().y() + det_bot->getDiamondDimensions().yHalfWidth;
0446 }
0447 }
0448
0449
0450
0451 void TotemTimingDQMSource::bookHistograms(DQMStore::IBooker &ibooker, const edm::Run &, const edm::EventSetup &) {
0452 ibooker.cd();
0453 ibooker.setCurrentFolder("CTPPS");
0454
0455 globalPlot_ = GlobalPlots(ibooker);
0456
0457 for (unsigned short arm = 0; arm < CTPPS_NUM_OF_ARMS; ++arm) {
0458 for (unsigned short rp = TOTEM_TIMING_TOP_RP_ID; rp <= TOTEM_TIMING_BOT_RP_ID; ++rp) {
0459 const TotemTimingDetId rpId(arm, TOTEM_TIMING_STATION_ID, rp);
0460 potPlots_[rpId] = PotPlots(ibooker, rpId);
0461 for (unsigned short pl = 0; pl < TOTEM_TIMING_NUM_OF_PLANES; ++pl) {
0462 const TotemTimingDetId plId(arm, TOTEM_TIMING_STATION_ID, rp, pl);
0463 planePlots_[plId] = PlanePlots(ibooker, plId);
0464 for (unsigned short ch = 0; ch < TOTEM_TIMING_NUM_OF_CHANNELS; ++ch) {
0465 const TotemTimingDetId chId(arm, TOTEM_TIMING_STATION_ID, rp, pl, ch);
0466 channelPlots_[chId] = ChannelPlots(ibooker, chId);
0467 }
0468 }
0469 }
0470 }
0471 }
0472
0473
0474
0475 std::shared_ptr<totemds::Cache> TotemTimingDQMSource::globalBeginLuminosityBlock(const edm::LuminosityBlock &,
0476 const edm::EventSetup &) const {
0477 auto d = std::make_shared<totemds::Cache>();
0478 d->hitDistribution2dMap.reserve(potPlots_.size());
0479 if (!perLSsaving_) {
0480 for (auto &plot : potPlots_)
0481 d->hitDistribution2dMap[plot.first] =
0482 std::unique_ptr<TH2F>(static_cast<TH2F *>(plot.second.hitDistribution2d_lumisection->getTH2F()->Clone()));
0483 }
0484 return d;
0485 }
0486
0487
0488
0489 void TotemTimingDQMSource::analyze(const edm::Event &event, const edm::EventSetup &eventSetup) {
0490
0491 auto const &geometry = eventSetup.getData(geometryToken_);
0492
0493
0494 edm::Handle<edm::DetSetVector<TotemRPLocalTrack>> stripTracks;
0495 event.getByToken(tokenLocalTrack_, stripTracks);
0496
0497 edm::Handle<edm::DetSetVector<TotemTimingDigi>> timingDigis;
0498 event.getByToken(tokenDigi_, timingDigis);
0499
0500 edm::Handle<std::vector<TotemFEDInfo>> fedInfo;
0501 event.getByToken(tokenFEDInfo_, fedInfo);
0502
0503 edm::Handle<edm::DetSetVector<TotemTimingRecHit>> timingRecHits;
0504 event.getByToken(tokenRecHit_, timingRecHits);
0505
0506
0507 bool valid = true;
0508 valid &= timingDigis.isValid();
0509 valid &= fedInfo.isValid();
0510
0511 if (!valid) {
0512 if (verbosity_) {
0513 edm::LogProblem("TotemTimingDQMSource") << "ERROR in TotemTimingDQMSource::analyze > some of the required inputs "
0514 "are not valid. Skipping this event.\n"
0515 << " timingDigis.isValid = " << timingDigis.isValid() << "\n"
0516 << " fedInfo.isValid = " << fedInfo.isValid();
0517 }
0518
0519 return;
0520 }
0521
0522
0523 std::set<uint8_t> boardSet;
0524 std::unordered_map<unsigned int, unsigned int> channelsPerPlane;
0525 std::unordered_map<unsigned int, unsigned int> channelsPerPlaneWithTime;
0526
0527 auto lumiCache = luminosityBlockCache(event.getLuminosityBlock().index());
0528 for (const auto &digis : *timingDigis) {
0529 const TotemTimingDetId detId(digis.detId());
0530 TotemTimingDetId detId_pot(digis.detId());
0531 detId_pot.setPlane(0);
0532 detId_pot.setChannel(0);
0533 TotemTimingDetId detId_plane(digis.detId());
0534 detId_plane.setChannel(0);
0535
0536 for (const auto &digi : digis) {
0537
0538 if (potPlots_.find(detId_pot) != potPlots_.end()) {
0539 potPlots_[detId_pot].activityPerBX->Fill(event.bunchCrossing());
0540
0541 potPlots_[detId_pot].digiDistribution->Fill(detId.plane(), detId.channel());
0542
0543 for (auto it = digi.samplesBegin(); it != digi.samplesEnd(); ++it)
0544 potPlots_[detId_pot].dataSamplesRaw->Fill(*it);
0545
0546 float boardId = digi.eventInfo().hardwareBoardId() + 0.5 * digi.eventInfo().hardwareSampicId();
0547 potPlots_[detId_pot].digiSent->Fill(boardId, digi.hardwareChannelId());
0548 if (boardSet.find(digi.eventInfo().hardwareId()) == boardSet.end()) {
0549
0550 boardSet.insert(digi.eventInfo().hardwareId());
0551 std::bitset<16> chMap(digi.eventInfo().channelMap());
0552 for (int i = 0; i < 16; ++i) {
0553 if (chMap.test(i)) {
0554 potPlots_[detId_pot].digiAll->Fill(boardId, i);
0555 }
0556 }
0557 }
0558
0559 potPlots_[detId_pot].planesWithDigisSet.insert(detId.plane());
0560 }
0561
0562
0563 if (planePlots_.find(detId_plane) != planePlots_.end()) {
0564 planePlots_[detId_plane].digiDistribution->Fill(detId.channel());
0565
0566 if (channelsPerPlane.find(detId_plane) != channelsPerPlane.end())
0567 channelsPerPlane[detId_plane]++;
0568 else
0569 channelsPerPlane[detId_plane] = 0;
0570 }
0571
0572
0573 if (channelPlots_.find(detId) != channelPlots_.end()) {
0574 channelPlots_[detId].activityPerBX->Fill(event.bunchCrossing());
0575
0576 for (auto it = digi.samplesBegin(); it != digi.samplesEnd(); ++it)
0577 channelPlots_[detId].dataSamplesRaw->Fill(*it);
0578 for (unsigned short i = 0; i < samplesForNoise_; ++i)
0579 channelPlots_[detId].noiseSamples->Fill(SAMPIC_ADC_V * digi.sampleAt(i));
0580
0581 unsigned int cellOfMax = std::max_element(digi.samplesBegin(), digi.samplesEnd()) - digi.samplesBegin();
0582 channelPlots_[detId].cellOfMax->Fill((int)cellOfMax);
0583
0584 if (timeOfPreviousEvent_ != 0)
0585 channelPlots_[detId].hitTime->Fill(1e-3 * LHC_CLOCK_PERIOD_NS *
0586 (event.time().value() - timeOfPreviousEvent_));
0587 ++(lumiCache->hitsCounterMap[detId]);
0588 }
0589 }
0590 }
0591
0592
0593 for (const auto &rechits : *timingRecHits) {
0594 const TotemTimingDetId detId(rechits.detId());
0595 TotemTimingDetId detId_pot(rechits.detId());
0596 detId_pot.setPlane(0);
0597 detId_pot.setChannel(0);
0598 TotemTimingDetId detId_plane(rechits.detId());
0599 detId_plane.setChannel(0);
0600
0601 for (const auto &rechit : rechits) {
0602 if (potPlots_.find(detId_pot) != potPlots_.end()) {
0603 potPlots_[detId_pot].amplitude->Fill(rechit.amplitude());
0604
0605 TH2F *hitHistoTmp = potPlots_[detId_pot].hitDistribution2d->getTH2F();
0606 TAxis *hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
0607 float yCorrected = rechit.y();
0608 yCorrected += (detId.rp() == TOTEM_TIMING_TOP_RP_ID) ? verticalShiftTop_ : verticalShiftBot_;
0609 float x_shift = detId.plane();
0610 x_shift += (rechit.x() > 2) ? 0.25 : 0;
0611 int startBin = hitHistoTmpYAxis->FindBin(yCorrected - 0.5 * rechit.yWidth());
0612 int numOfBins = rechit.yWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
0613 for (int i = 0; i < numOfBins; ++i) {
0614 potPlots_[detId_pot].hitDistribution2d->Fill(detId.plane() + 0.25 * (rechit.x() > 2),
0615 hitHistoTmpYAxis->GetBinCenter(startBin + i));
0616 if (!perLSsaving_)
0617 potPlots_[detId_pot].hitDistribution2d_lumisection->Fill(x_shift,
0618 hitHistoTmpYAxis->GetBinCenter(startBin + i));
0619 }
0620
0621
0622 if (rechit.time() != TotemTimingRecHit::NO_T_AVAILABLE) {
0623 for (int i = 0; i < numOfBins; ++i)
0624 potPlots_[detId_pot].hitDistribution2dWithTime->Fill(detId.plane() + 0.25 * (rechit.x() > 2),
0625 hitHistoTmpYAxis->GetBinCenter(startBin + i));
0626
0627 potPlots_[detId_pot].recHitTime->Fill(rechit.time());
0628 potPlots_[detId_pot].planesWithTimeSet.insert(detId.plane());
0629
0630
0631 if (planePlots_.find(detId_plane) != planePlots_.end()) {
0632
0633 float x_shift = (rechit.x() > 2) ? 15 : 0;
0634 TH1F *hitProfileHistoTmp = planePlots_[detId_plane].hitProfile->getTH1F();
0635 int numOfBins = rechit.yWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
0636 if (detId.rp() == TOTEM_TIMING_TOP_RP_ID) {
0637 float yCorrected = rechit.y() + verticalShiftTop_ - 0.5 * rechit.yWidth() + x_shift;
0638 int startBin = hitProfileHistoTmp->FindBin(yCorrected);
0639 for (int i = 0; i < numOfBins; ++i)
0640 hitProfileHistoTmp->Fill(hitProfileHistoTmp->GetBinCenter(startBin + i));
0641 } else {
0642 float yCorrected = rechit.y() + verticalShiftBot_ + 0.5 * rechit.yWidth() + (15 - x_shift);
0643 int startBin = hitProfileHistoTmp->FindBin(yCorrected);
0644 int totBins = hitProfileHistoTmp->GetNbinsX();
0645 for (int i = 0; i < numOfBins; ++i)
0646 hitProfileHistoTmp->Fill(hitProfileHistoTmp->GetBinCenter(totBins - startBin + i));
0647 }
0648
0649 if (channelsPerPlaneWithTime.find(detId_plane) != channelsPerPlaneWithTime.end())
0650 channelsPerPlaneWithTime[detId_plane]++;
0651 else
0652 channelsPerPlaneWithTime[detId_plane] = 0;
0653 }
0654
0655 if (channelPlots_.find(detId) != channelPlots_.end()) {
0656 potPlots_[detId_pot].tirggerCellTime->Fill(rechit.sampicThresholdTime());
0657 channelPlots_[detId].tirggerCellTime->Fill(rechit.sampicThresholdTime());
0658 channelPlots_[detId].recHitTime->Fill(rechit.time());
0659 channelPlots_[detId].amplitude->Fill(rechit.amplitude());
0660 }
0661 }
0662 }
0663 }
0664 }
0665
0666
0667
0668 for (const auto &rechits : *timingRecHits) {
0669 const TotemTimingDetId detId(rechits.detId());
0670 TotemTimingDetId detId_pot(rechits.detId());
0671 detId_pot.setPlane(0);
0672 detId_pot.setChannel(0);
0673 TotemTimingDetId detId_plane(rechits.detId());
0674 detId_plane.setChannel(0);
0675
0676 float y_shift = (detId.rp() == TOTEM_TIMING_TOP_RP_ID) ? 20 : 5;
0677
0678 for (const auto &rechit : rechits) {
0679 if (rechit.time() != TotemTimingRecHit::NO_T_AVAILABLE && potPlots_.find(detId_pot) != potPlots_.end() &&
0680 planePlots_.find(detId_plane) != planePlots_.end() && channelPlots_.find(detId) != channelPlots_.end()) {
0681 if (stripTracks.isValid()) {
0682 for (const auto &ds : *stripTracks) {
0683 const CTPPSDetId stripId(ds.detId());
0684
0685 TotemRPDetId plId_V(stripId);
0686 plId_V.setPlane(0);
0687 TotemRPDetId plId_U(stripId);
0688 plId_U.setPlane(1);
0689
0690 double rp_x = 0;
0691 double rp_y = 0;
0692 try {
0693 rp_x = (geometry.sensor(plId_V)->translation().x() + geometry.sensor(plId_U)->translation().x()) / 2;
0694 rp_y = (geometry.sensor(plId_V)->translation().y() + geometry.sensor(plId_U)->translation().y()) / 2;
0695 } catch (const cms::Exception &) {
0696 continue;
0697 }
0698
0699 for (const auto &striplt : ds) {
0700 if (striplt.isValid() && stripId.arm() == detId.arm()) {
0701 if (striplt.tx() > maximumStripAngleForTomography_ || striplt.ty() > maximumStripAngleForTomography_)
0702 continue;
0703 if (striplt.tx() < minimumStripAngleForTomography_ || striplt.ty() < minimumStripAngleForTomography_)
0704 continue;
0705 if (stripId.rp() - detId.rp() == (TOTEM_STRIP_MAX_RP_ID - TOTEM_TIMING_BOT_RP_ID)) {
0706 double x = striplt.x0() - rp_x;
0707 double y = striplt.y0() - rp_y;
0708 if (stripId.station() == TOTEM_STATION_210) {
0709 potPlots_[detId_pot].stripTomography210->Fill(x + detId.plane() * 50, y + y_shift);
0710 channelPlots_[detId].stripTomography210->Fill(x, y + y_shift);
0711 } else if (stripId.station() == TOTEM_STATION_220) {
0712 potPlots_[detId_pot].stripTomography220->Fill(x + detId.plane() * 50, y + y_shift);
0713 channelPlots_[detId].stripTomography220->Fill(x, y + y_shift);
0714 }
0715 }
0716 }
0717 }
0718 }
0719 }
0720 }
0721 }
0722 }
0723
0724 for (auto &plt : potPlots_) {
0725 plt.second.planesWithDigis->Fill(plt.second.planesWithDigisSet.size());
0726 plt.second.planesWithDigisSet.clear();
0727 plt.second.planesWithTime->Fill(plt.second.planesWithTimeSet.size());
0728 plt.second.planesWithTimeSet.clear();
0729 }
0730
0731 for (const auto &plt : channelsPerPlane) {
0732 planePlots_[plt.first].hitMultiplicity->Fill(plt.second);
0733 }
0734 for (const auto &plt : channelsPerPlaneWithTime) {
0735 planePlots_[plt.first].hitMultiplicityWithTime->Fill(plt.second);
0736 }
0737
0738 timeOfPreviousEvent_ = event.time().value();
0739 }
0740
0741
0742
0743 void TotemTimingDQMSource::globalEndLuminosityBlock(const edm::LuminosityBlock &iLumi, const edm::EventSetup &) {
0744 auto lumiCache = luminosityBlockCache(iLumi.index());
0745 if (!perLSsaving_) {
0746 for (auto &plot : potPlots_) {
0747 *(plot.second.hitDistribution2d_lumisection->getTH2F()) = *(lumiCache->hitDistribution2dMap[plot.first]);
0748 }
0749
0750 globalPlot_.digiSentPercentage->Reset();
0751 TH2F *hitHistoGlobalTmp = globalPlot_.digiSentPercentage->getTH2F();
0752 for (auto &plot : potPlots_) {
0753 TH2F *hitHistoTmp = plot.second.digiSentPercentage->getTH2F();
0754 TH2F *histoSent = plot.second.digiSent->getTH2F();
0755 TH2F *histoAll = plot.second.digiAll->getTH2F();
0756
0757 hitHistoTmp->Divide(histoSent, histoAll);
0758 hitHistoTmp->Scale(100);
0759 hitHistoGlobalTmp->Add(hitHistoTmp, 1);
0760
0761 plot.second.baseline->Reset();
0762 plot.second.noiseRMS->Reset();
0763 plot.second.meanAmplitude->Reset();
0764 plot.second.cellOfMax->Reset();
0765 plot.second.hitRate->Reset();
0766 TotemTimingDetId rpId(plot.first);
0767 for (auto &chPlot : channelPlots_) {
0768 TotemTimingDetId chId(chPlot.first);
0769 if (chId.arm() == rpId.arm() && chId.rp() == rpId.rp()) {
0770 plot.second.baseline->Fill(chId.plane(), chId.channel(), chPlot.second.noiseSamples->getTH1F()->GetMean());
0771 plot.second.noiseRMS->Fill(chId.plane(), chId.channel(), chPlot.second.noiseSamples->getTH1F()->GetRMS());
0772 plot.second.meanAmplitude->Fill(chId.plane(), chId.channel(), chPlot.second.amplitude->getTH1F()->GetMean());
0773 plot.second.cellOfMax->Fill(chId.plane(), chId.channel(), chPlot.second.cellOfMax->getTH1F()->GetMean());
0774 auto hitsCounterPerLumisection = lumiCache->hitsCounterMap[chPlot.first];
0775 plot.second.hitRate->Fill(chId.plane(), chId.channel(), (double)hitsCounterPerLumisection * HIT_RATE_FACTOR);
0776 }
0777 }
0778 }
0779
0780 for (auto &plot : channelPlots_) {
0781 auto hitsCounterPerLumisection = lumiCache->hitsCounterMap[plot.first];
0782 if (hitsCounterPerLumisection != 0) {
0783 plot.second.hitRate->Fill((double)hitsCounterPerLumisection * HIT_RATE_FACTOR);
0784 }
0785 }
0786 }
0787 }
0788
0789 DEFINE_FWK_MODULE(TotemTimingDQMSource);