File indexing completed on 2024-09-11 04:32:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013 #include "FWCore/Framework/interface/Event.h"
0014 #include "FWCore/Framework/interface/EventSetup.h"
0015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0016 #include "FWCore/Utilities/interface/ESGetToken.h"
0017 #include "FWCore/Utilities/interface/InputTag.h"
0018 #include "FWCore/Utilities/interface/Transition.h"
0019 #include "FWCore/Framework/interface/Run.h"
0020
0021 #include "DQMServices/Core/interface/DQMOneEDAnalyzer.h"
0022 #include "DQMServices/Core/interface/DQMStore.h"
0023
0024 #include "DataFormats/Provenance/interface/EventRange.h"
0025 #include "DataFormats/CTPPSDigi/interface/TotemVFATStatus.h"
0026 #include "DataFormats/CTPPSDigi/interface/TotemFEDInfo.h"
0027 #include "DataFormats/Common/interface/DetSetVector.h"
0028
0029 #include "DataFormats/CTPPSDetId/interface/CTPPSDiamondDetId.h"
0030 #include "DataFormats/CTPPSDigi/interface/CTPPSDiamondDigi.h"
0031
0032 #include "DataFormats/CTPPSReco/interface/CTPPSPixelLocalTrack.h"
0033 #include "DataFormats/CTPPSDetId/interface/CTPPSPixelDetId.h"
0034
0035 #include "DataFormats/CTPPSReco/interface/CTPPSDiamondRecHit.h"
0036 #include "DataFormats/CTPPSReco/interface/CTPPSDiamondLocalTrack.h"
0037 #include "Geometry/VeryForwardGeometryBuilder/interface/CTPPSGeometry.h"
0038 #include "Geometry/Records/interface/VeryForwardRealGeometryRecord.h"
0039
0040 #include <string>
0041
0042
0043
0044
0045 bool channelAlignedWithTrack(const CTPPSGeometry* geom,
0046 const CTPPSDiamondDetId& detid,
0047 const CTPPSDiamondLocalTrack& localTrack,
0048 const float tolerance = 1) {
0049 const DetGeomDesc* det = geom->sensor(detid);
0050 const float x_pos = det->translation().x(),
0051 x_width = 2.0 * det->getDiamondDimensions().xHalfWidth;
0052 return ((x_pos + 0.5 * x_width > localTrack.x0() - localTrack.x0Sigma() - tolerance &&
0053 x_pos + 0.5 * x_width < localTrack.x0() + localTrack.x0Sigma() + tolerance) ||
0054 (x_pos - 0.5 * x_width > localTrack.x0() - localTrack.x0Sigma() - tolerance &&
0055 x_pos - 0.5 * x_width < localTrack.x0() + localTrack.x0Sigma() + tolerance) ||
0056 (x_pos - 0.5 * x_width < localTrack.x0() - localTrack.x0Sigma() - tolerance &&
0057 x_pos + 0.5 * x_width > localTrack.x0() + localTrack.x0Sigma() + tolerance));
0058 }
0059
0060 namespace dds {
0061 struct Cache {
0062 std::unordered_map<unsigned int, std::unique_ptr<TH2F>> hitDistribution2dMap;
0063
0064 std::unordered_map<unsigned int, unsigned long> hitsCounterMap;
0065 };
0066 }
0067
0068 class CTPPSDiamondDQMSource : public DQMOneEDAnalyzer<edm::LuminosityBlockCache<dds::Cache>> {
0069 public:
0070 CTPPSDiamondDQMSource(const edm::ParameterSet&);
0071
0072 protected:
0073 void dqmBeginRun(const edm::Run&, const edm::EventSetup&) override;
0074 void dqmEndRun(edm::Run const&, edm::EventSetup const&) override;
0075 void bookHistograms(DQMStore::IBooker&, const edm::Run&, const edm::EventSetup&) override;
0076 void analyze(const edm::Event&, const edm::EventSetup&) override;
0077 std::shared_ptr<dds::Cache> globalBeginLuminosityBlock(const edm::LuminosityBlock&,
0078 const edm::EventSetup&) const override;
0079 void globalEndLuminosityBlock(const edm::LuminosityBlock&, const edm::EventSetup&) override;
0080
0081 private:
0082
0083
0084 static constexpr double SEC_PER_LUMI_SECTION = 23.31;
0085
0086 static constexpr unsigned short CHANNEL_OF_VFAT_CLOCK = 30;
0087
0088 static constexpr double DISPLAY_RESOLUTION_FOR_HITS_MM = 0.1;
0089 static constexpr double INV_DISPLAY_RESOLUTION_FOR_HITS_MM = 1. / DISPLAY_RESOLUTION_FOR_HITS_MM;
0090
0091 static constexpr double HPTDC_BIN_WIDTH_NS = 25. / 1024;
0092 static constexpr unsigned short CTPPS_PIXEL_STATION_ID = 2;
0093 static constexpr unsigned short CTPPS_PIXEL_FAR_RP_ID = 3;
0094 static constexpr unsigned short CTPPS_DIAMOND_CYL_STATION_ID = 1;
0095 static constexpr unsigned short CTPPS_DIAMOND_CYL_RP_ID = 6;
0096 static constexpr unsigned short CTPPS_DIAMOND_NUM_OF_CHANNELS = 12;
0097 static constexpr unsigned short CTPPS_FED_ID_45 = 583;
0098 static constexpr unsigned short CTPPS_FED_ID_56 = 582;
0099 static constexpr unsigned short HPTDC_0_CHANNEL = 6;
0100 static constexpr unsigned short HPTDC_1_CHANNEL = 7;
0101
0102 static constexpr unsigned int FIRST_RUN_W_PIXELS = 300000;
0103
0104 bool perLSsaving_;
0105
0106
0107 struct GlobalPlots {
0108 GlobalPlots() = default;
0109 GlobalPlots(DQMStore::IBooker& ibooker);
0110 };
0111
0112 struct SectorPlots {
0113
0114 MonitorElement* trackCorrelation = nullptr;
0115 MonitorElement* trackCorrelationLowMultiplicity = nullptr;
0116 MonitorElement* digiSentPercentage = nullptr;
0117 SectorPlots() {}
0118 SectorPlots(DQMStore::IBooker& ibooker, unsigned int id, bool plotOnline);
0119 };
0120
0121 struct PotPlots {
0122 std::unordered_map<unsigned int, MonitorElement*> activity_per_bx;
0123
0124 MonitorElement* hitDistribution2d = nullptr;
0125 MonitorElement* hitDistribution2d_lumisection = nullptr;
0126 MonitorElement* hitDistribution2dOOT = nullptr;
0127 MonitorElement* hitDistribution2dOOT_le = nullptr;
0128 MonitorElement *activePlanes = nullptr, *activePlanesInclusive = nullptr;
0129
0130 MonitorElement* trackDistribution = nullptr;
0131 MonitorElement* trackDistributionOOT = nullptr;
0132
0133 std::unordered_map<unsigned int, MonitorElement*> pixelTomographyAll;
0134
0135 MonitorElement *leadingEdgeCumulative_both = nullptr, *leadingEdgeCumulative_all = nullptr,
0136 *leadingEdgeCumulative_le = nullptr, *trailingEdgeCumulative_te = nullptr;
0137 MonitorElement* timeOverThresholdCumulativePot = nullptr;
0138 MonitorElement* leadingWithoutTrailingCumulativePot = nullptr;
0139
0140 MonitorElement* ECCheck = nullptr;
0141
0142 MonitorElement* HPTDCErrorFlags_2D = nullptr;
0143 MonitorElement* MHComprensive = nullptr;
0144
0145 MonitorElement* recHitTime = nullptr;
0146
0147
0148
0149
0150
0151
0152 unsigned int HitCounter, MHCounter, LeadingOnlyCounter, TrailingOnlyCounter, CompleteCounter;
0153
0154 std::map<int, int> effTriplecountingChMap;
0155 std::map<int, int> effDoublecountingChMap;
0156 MonitorElement* EfficiencyOfChannelsInPot = nullptr;
0157 TH2F pixelTracksMap;
0158
0159
0160
0161 MonitorElement* trackTimeVsBX = nullptr;
0162
0163
0164
0165
0166 MonitorElement* trackTimeVsBXProfile = nullptr;
0167
0168
0169 PotPlots() = default;
0170 PotPlots(DQMStore::IBooker& ibooker,
0171 unsigned int id,
0172 unsigned int windowsNum,
0173 bool plotOnline,
0174 bool plotOffline,
0175 bool perLSsaving);
0176 };
0177
0178 struct PlanePlots {
0179 MonitorElement* digiProfileCumulativePerPlane = nullptr;
0180 MonitorElement* hitProfile = nullptr;
0181 MonitorElement* hit_multiplicity = nullptr;
0182
0183 MonitorElement *leadingEdgeCumulativePerPlane_both = nullptr, *leadingEdgeCumulativePerPlane_le = nullptr,
0184 *trailingEdgeCumulativePerPlane_te = nullptr;
0185 MonitorElement* TimeOverThresholdCumulativePerPlane = nullptr;
0186 MonitorElement* pixelTomography_far = nullptr;
0187 MonitorElement* EfficiencyWRTPixelsInPlane = nullptr;
0188
0189 TH2F pixelTracksMapWithDiamonds;
0190
0191 PlanePlots() = default;
0192 PlanePlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum);
0193 };
0194
0195 struct ChannelPlots {
0196 std::unordered_map<unsigned int, MonitorElement*> activity_per_bx;
0197
0198 MonitorElement* HPTDCErrorFlags = nullptr;
0199 MonitorElement *leadingEdgeCumulative_both = nullptr, *leadingEdgeCumulative_le = nullptr,
0200 *trailingEdgeCumulative_te = nullptr;
0201 MonitorElement* TimeOverThresholdCumulativePerChannel = nullptr;
0202
0203 MonitorElement* leadingWithoutTrailing = nullptr;
0204 MonitorElement* pixelTomography_far = nullptr;
0205 MonitorElement* hit_rate = nullptr;
0206 MonitorElement* recHitTime = nullptr;
0207
0208 unsigned int HitCounter, MHCounter, LeadingOnlyCounter, TrailingOnlyCounter, CompleteCounter;
0209
0210 ChannelPlots() = default;
0211 ChannelPlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum);
0212 };
0213
0214 void checkEventNumber(const CTPPSDiamondDetId&, const TotemFEDInfo&, const TotemVFATStatus&, PotPlots&, int&) const;
0215
0216 edm::EDGetTokenT<edm::DetSetVector<TotemVFATStatus>> tokenStatus_;
0217 edm::EDGetTokenT<edm::DetSetVector<CTPPSPixelLocalTrack>> tokenPixelTrack_;
0218 edm::EDGetTokenT<edm::DetSetVector<CTPPSDiamondDigi>> tokenDigi_;
0219 edm::EDGetTokenT<edm::DetSetVector<CTPPSDiamondRecHit>> tokenDiamondHit_;
0220 edm::EDGetTokenT<edm::DetSetVector<CTPPSDiamondLocalTrack>> tokenDiamondTrack_;
0221 edm::EDGetTokenT<std::vector<TotemFEDInfo>> tokenFEDInfo_;
0222
0223 edm::ESGetToken<CTPPSGeometry, VeryForwardRealGeometryRecord> ctppsGeometryRunToken_;
0224 edm::ESGetToken<CTPPSGeometry, VeryForwardRealGeometryRecord> ctppsGeometryEventToken_;
0225
0226 bool excludeMultipleHits_;
0227 const bool extract_digi_info_;
0228 struct DiamondShifts {
0229 double global, withPixels;
0230 };
0231 std::unordered_map<CTPPSDetId, DiamondShifts> diamShifts_;
0232 std::vector<std::pair<edm::EventRange, int>> runParameters_;
0233 int centralOOT_;
0234 unsigned int verbosity_;
0235 const bool plotOnline_;
0236 const bool plotOffline_;
0237 unsigned int windowsNum_;
0238 unsigned int trackCorrelationThreshold_;
0239
0240 GlobalPlots globalPlot_;
0241 std::unordered_map<unsigned int, PotPlots> potPlots_;
0242 std::unordered_map<unsigned int, SectorPlots> sectorPlots_;
0243 std::unordered_map<unsigned int, PlanePlots> planePlots_;
0244 std::unordered_map<unsigned int, ChannelPlots> channelPlots_;
0245
0246 int EC_difference_56_, EC_difference_45_;
0247 };
0248
0249
0250
0251 CTPPSDiamondDQMSource::GlobalPlots::GlobalPlots(DQMStore::IBooker& ibooker) { ibooker.setCurrentFolder("CTPPS"); }
0252
0253
0254
0255 CTPPSDiamondDQMSource::SectorPlots::SectorPlots(DQMStore::IBooker& ibooker, unsigned int id, bool plotOnline) {
0256 std::string path, title;
0257 CTPPSDiamondDetId(id).armName(path, CTPPSDiamondDetId::nPath);
0258 ibooker.setCurrentFolder(path);
0259
0260 CTPPSDiamondDetId(id).armName(title, CTPPSDiamondDetId::nFull);
0261
0262 trackCorrelation = ibooker.book2D("tracks correlation near-far",
0263 title + " tracks correlation near-far;track x 220nr_hr (mm);track x 220cyl (mm)",
0264 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0265 -1,
0266 18,
0267 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0268 -1,
0269 18);
0270 trackCorrelationLowMultiplicity = ibooker.book2D(
0271 "tracks correlation with low multiplicity near-far",
0272 title + " tracks correlation with low multiplicity near-far;track x 220nr_hr (mm);track x 220cyl(mm)",
0273 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0274 -1,
0275 18,
0276 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0277 -1,
0278 18);
0279 }
0280
0281
0282 CTPPSDiamondDQMSource::PotPlots::PotPlots(DQMStore::IBooker& ibooker,
0283 unsigned int id,
0284 unsigned int windowsNum,
0285 bool plotOnline,
0286 bool plotOffline,
0287 bool perLSsaving)
0288 : HitCounter(0),
0289 MHCounter(0),
0290 LeadingOnlyCounter(0),
0291 TrailingOnlyCounter(0),
0292 CompleteCounter(0),
0293 pixelTracksMap("Pixel track maps for efficiency", "Pixel track maps for efficiency", 25, 0, 25, 16, -8, 8) {
0294 std::string path, title;
0295 CTPPSDiamondDetId(id).rpName(path, CTPPSDiamondDetId::nPath);
0296 ibooker.setCurrentFolder(path);
0297
0298 CTPPSDiamondDetId(id).rpName(title, CTPPSDiamondDetId::nFull);
0299
0300 if (plotOnline) {
0301 hitDistribution2d_lumisection =
0302 ibooker.book2D("hits in planes lumisection",
0303 title + " hits in planes in the last lumisection;plane number;x (mm)",
0304 10,
0305 -0.5,
0306 4.5,
0307 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0308 -0.5,
0309 18.5);
0310
0311 hitDistribution2dOOT_le =
0312 ibooker.book2D("hits with OOT in planes (le only)",
0313 title + " hits with OOT in planes (le only);plane number, OOT index;x (mm)",
0314 1 + windowsNum * 4,
0315 -1. / windowsNum,
0316 4,
0317 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0318 -0.5,
0319 18.5);
0320
0321 activePlanesInclusive =
0322 ibooker.book1D("active planes inclusive",
0323 title + " active planes, MH and le only included (per event);number of active planes",
0324 6,
0325 -0.5,
0326 5.5);
0327
0328 ECCheck = ibooker.book1D("optorxEC(8bit) - vfatEC", title + " EC Error;optorxEC-vfatEC", 50, -25, 25);
0329
0330 EfficiencyOfChannelsInPot =
0331 ibooker.book2D("Efficiency in channels",
0332 title + " Efficiency (%) in channels (diamonds only);plane number;ch number",
0333 10,
0334 -0.5,
0335 4.5,
0336 14,
0337 -1,
0338 13);
0339 }
0340
0341 if (plotOffline && !perLSsaving) {
0342 ibooker.setCurrentFolder(path + "/timing_profiles");
0343
0344
0345 trackTimeVsBX =
0346 ibooker.book2D("track time vs BX", title + " track time vs BX;BX;track_time(ns)", 4000, 0, 4000, 500, -25, 25);
0347
0348
0349
0350
0351
0352 trackTimeVsBXProfile = ibooker.bookProfile(
0353 "track time vs BX profile", title + " track time vs BX profile;BX;track_time(ns)", 500, -25, 25, 4000, 0, 4000);
0354
0355
0356
0357
0358
0359
0360
0361
0362 ibooker.setCurrentFolder(path);
0363 }
0364
0365 for (unsigned int i = 0; i < windowsNum; i++) {
0366 std::string window = std::to_string(i * 25) + "-" + std::to_string((i + 1) * 25);
0367 activity_per_bx[i] = ibooker.book1D(
0368 "activity per BX " + window, title + " Activity per BX " + window + " ns;Event.BX", 3600, -1.5, 3598. + 0.5);
0369 pixelTomographyAll[i] =
0370 ibooker.book2D("tomography pixel " + window,
0371 title + " tomography with pixel " + window + " ns (all planes);x + 25*plane(mm);y (mm)",
0372 100,
0373 0,
0374 100,
0375 10,
0376 -5,
0377 5);
0378 }
0379
0380 hitDistribution2d = ibooker.book2D("hits in planes",
0381 title + " hits in planes;plane number;x (mm)",
0382 10,
0383 -0.5,
0384 4.5,
0385 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0386 -0.5,
0387 18.5);
0388
0389 hitDistribution2dOOT = ibooker.book2D("hits with OOT in planes",
0390 title + " hits with OOT in planes;plane number, OOT index;x (mm)",
0391 1 + windowsNum * 4,
0392 -1. / windowsNum,
0393 4,
0394 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0395 -0.5,
0396 18.5);
0397
0398 {
0399 int idx = 2;
0400 for (int pl = 0; pl < 4; ++pl)
0401 for (unsigned int oot = 0; oot < windowsNum; ++oot) {
0402 const std::string bin_label =
0403 (oot == 0 ? "Plane " + std::to_string(pl) + ", " : "") + "OOT" + std::to_string(oot);
0404 hitDistribution2dOOT->setBinLabel(idx, bin_label);
0405 if (plotOnline)
0406 hitDistribution2dOOT_le->setBinLabel(idx, bin_label);
0407 ++idx;
0408 }
0409 }
0410
0411 recHitTime = ibooker.book1D("recHit time", title + " recHit time; t (ns)", 500, -25, 25);
0412
0413 activePlanes =
0414 ibooker.book1D("active planes", title + " active planes (per event);number of active planes", 6, -0.5, 5.5);
0415
0416 trackDistribution =
0417 ibooker.book1D("tracks", title + " tracks;x (mm)", 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5);
0418 trackDistributionOOT = ibooker.book2D("tracks with OOT",
0419 title + " tracks with OOT;plane number;x (mm)",
0420 9,
0421 -0.5,
0422 4,
0423 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0424 -0.5,
0425 18.5);
0426
0427 leadingEdgeCumulative_both = ibooker.book1D("leading edge (le and te)",
0428 title + " leading edge (le and te) (recHits); leading edge (ns)",
0429 25 * windowsNum,
0430 0,
0431 25 * windowsNum);
0432 leadingEdgeCumulative_all = ibooker.book1D("leading edge (all)",
0433 title + " leading edge (with or without te) (DIGIs); leading edge (ns)",
0434 25 * windowsNum,
0435 0,
0436 25 * windowsNum);
0437 leadingEdgeCumulative_le = ibooker.book1D("leading edge (le only)",
0438 title + " leading edge (le only) (DIGIs); leading edge (ns)",
0439 25 * windowsNum,
0440 0,
0441 25 * windowsNum);
0442 trailingEdgeCumulative_te = ibooker.book1D("trailing edge (te only)",
0443 title + " trailing edge (te only) (DIGIs); trailing edge (ns)",
0444 25 * windowsNum,
0445 0,
0446 25 * windowsNum);
0447 timeOverThresholdCumulativePot =
0448 ibooker.book1D("time over threshold", title + " time over threshold;time over threshold (ns)", 250, -25, 100);
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459 leadingWithoutTrailingCumulativePot =
0460 ibooker.book1D("event category", title + " leading edges without trailing;;%", 3, 0.5, 3.5);
0461 leadingWithoutTrailingCumulativePot->setBinLabel(1, "Leading only");
0462 leadingWithoutTrailingCumulativePot->setBinLabel(2, "Trailing only");
0463 leadingWithoutTrailingCumulativePot->setBinLabel(3, "Both");
0464
0465 HPTDCErrorFlags_2D = ibooker.book2D("HPTDC Errors", title + " HPTDC Errors", 16, -0.5, 16.5, 9, -0.5, 8.5);
0466 for (unsigned short error_index = 1; error_index < 16; ++error_index)
0467 HPTDCErrorFlags_2D->setBinLabel(error_index, HPTDCErrorFlags::hptdcErrorName(error_index - 1));
0468 HPTDCErrorFlags_2D->setBinLabel(16, "Wrong EC");
0469
0470 int tmpIndex = 0;
0471 HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 18", 2);
0472 HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 17", 2);
0473 HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 16", 2);
0474 HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 15", 2);
0475 HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 18", 2);
0476 HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 17", 2);
0477 HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 16", 2);
0478 HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 15", 2);
0479
0480 MHComprensive =
0481 ibooker.book2D("MH in channels", title + " MH (%) in channels;plane number;ch number", 10, -0.5, 4.5, 14, -1, 13);
0482
0483
0484
0485
0486
0487
0488 }
0489
0490
0491
0492 CTPPSDiamondDQMSource::PlanePlots::PlanePlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum)
0493 : pixelTracksMapWithDiamonds("Pixel track maps for efficiency with coincidence",
0494 "Pixel track maps for efficiency with coincidence",
0495 25,
0496 0,
0497 25,
0498 16,
0499 -8,
0500 8) {
0501 std::string path, title;
0502 CTPPSDiamondDetId(id).planeName(path, CTPPSDiamondDetId::nPath);
0503 ibooker.setCurrentFolder(path);
0504
0505 CTPPSDiamondDetId(id).planeName(title, CTPPSDiamondDetId::nFull);
0506
0507 digiProfileCumulativePerPlane = ibooker.book1D("digi profile",
0508 title + " digi profile; ch number",
0509 CTPPS_DIAMOND_NUM_OF_CHANNELS,
0510 -0.5,
0511 CTPPS_DIAMOND_NUM_OF_CHANNELS - 0.5);
0512 hitProfile = ibooker.book1D(
0513 "hit profile", title + " hit profile;x (mm)", 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5);
0514 hit_multiplicity = ibooker.book1D("channels per plane", title + " channels per plane; ch per plane", 13, -0.5, 12.5);
0515
0516 leadingEdgeCumulativePerPlane_both = ibooker.book1D("leading edge (le and te)",
0517 title + " leading edge (le and te) (recHits); leading edge (ns)",
0518 25 * windowsNum,
0519 0,
0520 25 * windowsNum);
0521 leadingEdgeCumulativePerPlane_le = ibooker.book1D("leading edge (le only)",
0522 title + " leading edge (le only) (DIGIs); leading edge (ns)",
0523 25 * windowsNum,
0524 0,
0525 25 * windowsNum);
0526 trailingEdgeCumulativePerPlane_te = ibooker.book1D("trailing edge (te only)",
0527 title + " trailing edge (te only) (DIGIs); trailing edge (ns)",
0528 25 * windowsNum,
0529 0,
0530 25 * windowsNum);
0531 TimeOverThresholdCumulativePerPlane =
0532 ibooker.book1D("time over threshold", title + " time over threshold;time over threshold (ns)", 75, -25, 50);
0533
0534 pixelTomography_far = ibooker.book2D("tomography pixel",
0535 title + " tomography with pixel;x + 25 OOT (mm);y (mm)",
0536 25 * windowsNum,
0537 0,
0538 25 * windowsNum,
0539 16,
0540 -8,
0541 8);
0542 EfficiencyWRTPixelsInPlane =
0543 ibooker.book2D("Efficiency wrt pixels", title + " Efficiency wrt pixels;x (mm);y (mm)", 25, 0, 25, 16, -8, 8);
0544 }
0545
0546
0547
0548 CTPPSDiamondDQMSource::ChannelPlots::ChannelPlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum)
0549 : HitCounter(0), MHCounter(0), LeadingOnlyCounter(0), TrailingOnlyCounter(0), CompleteCounter(0) {
0550 std::string path, title;
0551 CTPPSDiamondDetId(id).channelName(path, CTPPSDiamondDetId::nPath);
0552 ibooker.setCurrentFolder(path);
0553
0554 CTPPSDiamondDetId(id).channelName(title, CTPPSDiamondDetId::nFull);
0555
0556 leadingWithoutTrailing = ibooker.book1D("event category", title + " Event Category;;%", 3, 0.5, 3.5);
0557 leadingWithoutTrailing->setBinLabel(1, "Leading only");
0558 leadingWithoutTrailing->setBinLabel(2, "Trailing only");
0559 leadingWithoutTrailing->setBinLabel(3, "Full");
0560
0561 for (unsigned int i = 0; i < windowsNum; i++) {
0562 std::string window = std::to_string(i * 25) + "-" + std::to_string((i + 1) * 25);
0563 activity_per_bx[i] = ibooker.book1D(
0564 "activity per BX " + window, title + " Activity per BX " + window + " ns;Event.BX", 3600, -1.5, 3598. + 0.5);
0565 }
0566
0567 HPTDCErrorFlags = ibooker.book1D("hptdc_Errors", title + " HPTDC Errors", 16, -0.5, 16.5);
0568 for (unsigned short error_index = 1; error_index < 16; ++error_index)
0569 HPTDCErrorFlags->setBinLabel(error_index, HPTDCErrorFlags::hptdcErrorName(error_index - 1));
0570 HPTDCErrorFlags->setBinLabel(16, "MH (%)");
0571
0572 leadingEdgeCumulative_both = ibooker.book1D("leading edge (le and te)",
0573 title + " leading edge (le and te) (recHits); leading edge (ns)",
0574 25 * windowsNum,
0575 0,
0576 25 * windowsNum);
0577 leadingEdgeCumulative_le = ibooker.book1D("leading edge (le only)",
0578 title + " leading edge (le only) (DIGIs); leading edge (ns)",
0579 25 * windowsNum,
0580 0,
0581 25 * windowsNum);
0582 trailingEdgeCumulative_te = ibooker.book1D("trailing edge (te only)",
0583 title + " trailing edge (te only) (DIGIs); trailing edge (ns)",
0584 25 * windowsNum,
0585 0,
0586 25 * windowsNum);
0587 TimeOverThresholdCumulativePerChannel =
0588 ibooker.book1D("time over threshold", title + " time over threshold;time over threshold (ns)", 75, -25, 50);
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599 pixelTomography_far = ibooker.book2D("tomography pixel",
0600 "tomography with pixel;x + 25 OOT (mm);y (mm)",
0601 25 * windowsNum,
0602 0,
0603 25 * windowsNum,
0604 16,
0605 -8,
0606 8);
0607
0608 hit_rate = ibooker.book1D("hit rate", title + "hit rate;rate (Hz)", 40, 0, 20);
0609
0610 recHitTime = ibooker.book1D("recHit Time", title + " recHit Time; t (ns)", 500, -25, 25);
0611 }
0612
0613
0614
0615 CTPPSDiamondDQMSource::CTPPSDiamondDQMSource(const edm::ParameterSet& ps)
0616 : perLSsaving_(ps.getUntrackedParameter<bool>("perLSsaving", false)),
0617 tokenPixelTrack_(consumes<edm::DetSetVector<CTPPSPixelLocalTrack>>(
0618 ps.getUntrackedParameter<edm::InputTag>("tagPixelLocalTracks"))),
0619 tokenDiamondHit_(consumes<edm::DetSetVector<CTPPSDiamondRecHit>>(
0620 ps.getUntrackedParameter<edm::InputTag>("tagDiamondRecHits"))),
0621 tokenDiamondTrack_(consumes<edm::DetSetVector<CTPPSDiamondLocalTrack>>(
0622 ps.getUntrackedParameter<edm::InputTag>("tagDiamondLocalTracks"))),
0623 ctppsGeometryRunToken_(esConsumes<CTPPSGeometry, VeryForwardRealGeometryRecord, edm::Transition::BeginRun>()),
0624 ctppsGeometryEventToken_(esConsumes<CTPPSGeometry, VeryForwardRealGeometryRecord>()),
0625 excludeMultipleHits_(ps.getParameter<bool>("excludeMultipleHits")),
0626 extract_digi_info_(ps.getParameter<bool>("extractDigiInfo")),
0627 centralOOT_(-999),
0628 verbosity_(ps.getUntrackedParameter<unsigned int>("verbosity", 0)),
0629 plotOnline_(ps.getUntrackedParameter<bool>("plotOnline", true)),
0630 plotOffline_(ps.getUntrackedParameter<bool>("plotOffline", false)),
0631 windowsNum_(ps.getUntrackedParameter<unsigned int>("windowsNum", 3)),
0632 trackCorrelationThreshold_(ps.getUntrackedParameter<unsigned int>("trackCorrelationThreshold", 3)),
0633 EC_difference_56_(-500),
0634 EC_difference_45_(-500) {
0635 if (extract_digi_info_) {
0636 tokenStatus_ = consumes<edm::DetSetVector<TotemVFATStatus>>(ps.getUntrackedParameter<edm::InputTag>("tagStatus"));
0637 tokenFEDInfo_ = consumes<std::vector<TotemFEDInfo>>(ps.getUntrackedParameter<edm::InputTag>("tagFEDInfo"));
0638 tokenDigi_ = consumes<edm::DetSetVector<CTPPSDiamondDigi>>(ps.getUntrackedParameter<edm::InputTag>("tagDigi"));
0639 }
0640 for (const auto& pset : ps.getParameter<std::vector<edm::ParameterSet>>("offsetsOOT")) {
0641 runParameters_.emplace_back(
0642 std::make_pair(pset.getParameter<edm::EventRange>("validityRange"), pset.getParameter<int>("centralOOT")));
0643 }
0644 }
0645
0646
0647
0648 void CTPPSDiamondDQMSource::dqmBeginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
0649 centralOOT_ = -999;
0650 for (const auto& oot : runParameters_) {
0651 if (edm::contains(oot.first, edm::EventID(iRun.run(), 0, 1))) {
0652 centralOOT_ = oot.second;
0653 break;
0654 }
0655 }
0656
0657
0658 const CTPPSGeometry& geom = iSetup.getData(ctppsGeometryRunToken_);
0659 for (auto it = geom.beginRP(); it != geom.endRP(); ++it)
0660 if (CTPPSDiamondDetId::check(it->first)) {
0661 const CTPPSDiamondDetId diam_id(it->first);
0662 const auto diam = geom.sensor(it->first);
0663 diamShifts_[diam_id].global = diam->translation().x() - diam->getDiamondDimensions().xHalfWidth;
0664 if (iRun.run() > FIRST_RUN_W_PIXELS) {
0665 const CTPPSPixelDetId pixid(diam_id.arm(), CTPPS_PIXEL_STATION_ID, CTPPS_PIXEL_FAR_RP_ID);
0666 auto pix = geom.sensor(pixid);
0667
0668 diamShifts_[diam_id].withPixels =
0669 pix->translation().x() - pix->getDiamondDimensions().xHalfWidth - diamShifts_[diam_id].global - 1.;
0670 }
0671 }
0672 }
0673
0674
0675
0676 void CTPPSDiamondDQMSource::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, const edm::EventSetup& iSetup) {
0677 ibooker.cd();
0678 ibooker.setCurrentFolder("CTPPS");
0679
0680 globalPlot_ = GlobalPlots(ibooker);
0681
0682
0683 const CTPPSGeometry& geom = iSetup.getData(ctppsGeometryRunToken_);
0684 for (auto it = geom.beginSensor(); it != geom.endSensor(); ++it) {
0685 if (!CTPPSDiamondDetId::check(it->first))
0686 continue;
0687
0688 const CTPPSDiamondDetId chId(it->first);
0689 if (plotOnline_ && channelPlots_.count(chId) == 0)
0690 channelPlots_[chId] = ChannelPlots(ibooker, chId, windowsNum_);
0691
0692
0693 const CTPPSDiamondDetId plId(chId.planeId());
0694 if (planePlots_.count(plId) == 0)
0695 planePlots_[plId] = PlanePlots(ibooker, plId, windowsNum_);
0696
0697 const CTPPSDiamondDetId rpId(chId.rpId());
0698 if (potPlots_.count(rpId) == 0)
0699 potPlots_[rpId] = PotPlots(ibooker, rpId, windowsNum_, plotOnline_, plotOffline_, perLSsaving_);
0700
0701
0702 const CTPPSDiamondDetId secId(chId.armId());
0703 if (plotOffline_ && sectorPlots_.count(secId) == 0)
0704 sectorPlots_[secId] = SectorPlots(ibooker, secId, plotOnline_);
0705 }
0706 }
0707
0708
0709
0710 std::shared_ptr<dds::Cache> CTPPSDiamondDQMSource::globalBeginLuminosityBlock(const edm::LuminosityBlock&,
0711 const edm::EventSetup&) const {
0712 auto d = std::make_shared<dds::Cache>();
0713 d->hitDistribution2dMap.reserve(potPlots_.size());
0714 if (!perLSsaving_ && plotOnline_) {
0715 for (auto& plot : potPlots_) {
0716 d->hitDistribution2dMap[plot.first] = std::make_unique<TH2F>(
0717 "hits in planes lumisection",
0718 (std::string(plot.second.hitDistribution2d_lumisection->getTH2F()->GetTitle()) + ";plane number;x (mm)")
0719 .c_str(),
0720 10,
0721 -0.5,
0722 4.5,
0723 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM,
0724 -0.5,
0725 18.5);
0726 }
0727 }
0728 return d;
0729 }
0730
0731
0732
0733 void CTPPSDiamondDQMSource::analyze(const edm::Event& event, const edm::EventSetup& iSetup) {
0734
0735
0736 edm::Handle<edm::DetSetVector<TotemVFATStatus>> diamondVFATStatus;
0737 edm::Handle<edm::DetSetVector<CTPPSDiamondDigi>> diamondDigis;
0738 edm::Handle<std::vector<TotemFEDInfo>> fedInfo;
0739 if (extract_digi_info_) {
0740 event.getByToken(tokenStatus_, diamondVFATStatus);
0741 event.getByToken(tokenDigi_, diamondDigis);
0742 event.getByToken(tokenFEDInfo_, fedInfo);
0743 }
0744
0745 edm::Handle<edm::DetSetVector<CTPPSPixelLocalTrack>> pixelTracks;
0746 event.getByToken(tokenPixelTrack_, pixelTracks);
0747
0748 edm::Handle<edm::DetSetVector<CTPPSDiamondRecHit>> diamondRecHits;
0749 event.getByToken(tokenDiamondHit_, diamondRecHits);
0750
0751 edm::Handle<edm::DetSetVector<CTPPSDiamondLocalTrack>> diamondLocalTracks;
0752 event.getByToken(tokenDiamondTrack_, diamondLocalTracks);
0753
0754 const CTPPSGeometry* ctppsGeometry = &iSetup.getData(ctppsGeometryEventToken_);
0755
0756
0757 bool valid = true;
0758 if (extract_digi_info_) {
0759 valid &= diamondVFATStatus.isValid();
0760 valid &= diamondDigis.isValid();
0761 valid &= fedInfo.isValid();
0762 }
0763 valid &= pixelTracks.isValid();
0764 valid &= diamondRecHits.isValid();
0765 valid &= diamondLocalTracks.isValid();
0766
0767 if (!valid) {
0768 if (verbosity_)
0769 edm::LogProblem("CTPPSDiamondDQMSource")
0770 << "ERROR in CTPPSDiamondDQMSource::analyze > some of the required inputs are not valid. Skipping this "
0771 "event.\n"
0772 << " DIGI-level: (checked? " << std::boolalpha << extract_digi_info_ << ")\n"
0773 << " diamondVFATStatus.isValid = " << diamondVFATStatus.isValid() << "\n"
0774 << " diamondDigis.isValid = " << diamondDigis.isValid() << "\n"
0775 << " fedInfo.isValid = " << fedInfo.isValid() << "\n"
0776 << " RECO-level:\n"
0777 << " pixelTracks.isValid = " << pixelTracks.isValid() << "\n"
0778 << " diamondRecHits.isValid = " << diamondRecHits.isValid() << "\n"
0779 << " diamondLocalTracks.isValid = " << diamondLocalTracks.isValid();
0780 return;
0781 }
0782
0783
0784
0785
0786
0787 if (plotOffline_)
0788
0789
0790
0791
0792
0793 for (const auto& tracks_220nr_hr : *diamondLocalTracks) {
0794
0795 const CTPPSDiamondDetId detId_220nr_hr(tracks_220nr_hr.detId());
0796
0797
0798 if ((detId_220nr_hr.rp() == CTPPS_DIAMOND_CYL_RP_ID) &&
0799 (detId_220nr_hr.station() == CTPPS_DIAMOND_CYL_STATION_ID))
0800 continue;
0801
0802 if (potPlots_.count(detId_220nr_hr.rpId()) == 0)
0803 continue;
0804 TH1F* trackHistoInTimeTmp = potPlots_[detId_220nr_hr.rpId()].trackDistribution->getTH1F();
0805
0806 for (const auto& track_220nr_hr : tracks_220nr_hr) {
0807 if (!track_220nr_hr.isValid())
0808 continue;
0809
0810
0811 int startBin_220nr_hr = trackHistoInTimeTmp->FindBin(
0812 track_220nr_hr.x0() - diamShifts_[detId_220nr_hr.rpId()].global - track_220nr_hr.x0Sigma());
0813 int numOfBins_220nr_hr = 2 * track_220nr_hr.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
0814
0815 for (const auto& tracks_220cyl : *diamondLocalTracks) {
0816 CTPPSDiamondDetId detId_220cyl(tracks_220cyl.detId());
0817
0818
0819
0820
0821 if (detId_220nr_hr.arm() != detId_220cyl.arm() || detId_220nr_hr.station() == detId_220cyl.station())
0822 continue;
0823
0824 if (sectorPlots_.count(detId_220cyl.armId()) == 0)
0825 continue;
0826
0827 TH2F* trackHistoTmp = sectorPlots_[detId_220cyl.armId()].trackCorrelation->getTH2F();
0828 TAxis* trackHistoTmpXAxis = trackHistoTmp->GetXaxis();
0829 TAxis* trackHistoTmpYAxis = trackHistoTmp->GetYaxis();
0830
0831 for (const auto& track_220cyl : tracks_220cyl) {
0832 if (!track_220cyl.isValid())
0833 continue;
0834 int startBin_220cyl = trackHistoTmpYAxis->FindBin(
0835 track_220cyl.x0() - diamShifts_[detId_220cyl.rpId()].global - track_220cyl.x0Sigma());
0836 int numOfBins_220cyl = 2 * track_220cyl.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
0837
0838
0839 for (int i = 0; i < numOfBins_220nr_hr; ++i)
0840 for (int y = 0; y < numOfBins_220cyl; ++y) {
0841 float track_220nr_hr_x = trackHistoTmpXAxis->GetBinCenter(startBin_220nr_hr + i);
0842 float track_220cyl_x = trackHistoTmpYAxis->GetBinCenter(startBin_220cyl + y);
0843 trackHistoTmp->Fill(track_220nr_hr_x, track_220cyl_x);
0844
0845 if (tracks_220nr_hr.size() < 3 && tracks_220cyl.size() < trackCorrelationThreshold_)
0846 sectorPlots_[detId_220cyl.armId()].trackCorrelationLowMultiplicity->Fill(track_220nr_hr_x,
0847 track_220cyl_x);
0848 }
0849 }
0850 }
0851 }
0852 }
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862 if (extract_digi_info_) {
0863
0864 for (const auto& digis : *diamondDigis) {
0865 const CTPPSDiamondDetId detId(digis.detId()), detId_pot(detId.rpId());
0866 for (const auto& digi : digis) {
0867 if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
0868 continue;
0869 if (potPlots_.count(detId_pot) == 0)
0870 continue;
0871
0872 if (digi.leadingEdge() != 0 || digi.trailingEdge() != 0) {
0873 ++potPlots_[detId_pot].HitCounter;
0874 if (digi.leadingEdge() != 0) {
0875 potPlots_[detId_pot].leadingEdgeCumulative_all->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
0876 }
0877 if (digi.leadingEdge() != 0 && digi.trailingEdge() == 0) {
0878 ++potPlots_[detId_pot].LeadingOnlyCounter;
0879 potPlots_[detId_pot].leadingEdgeCumulative_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
0880 }
0881 if (digi.leadingEdge() == 0 && digi.trailingEdge() != 0) {
0882 ++potPlots_[detId_pot].TrailingOnlyCounter;
0883 potPlots_[detId_pot].trailingEdgeCumulative_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
0884 }
0885 if (digi.leadingEdge() != 0 && digi.trailingEdge() != 0) {
0886 ++potPlots_[detId_pot].CompleteCounter;
0887
0888
0889 }
0890 }
0891
0892
0893 const HPTDCErrorFlags hptdcErrors = digi.hptdcErrorFlags();
0894 if (detId.channel() == HPTDC_0_CHANNEL ||
0895 detId.channel() == HPTDC_1_CHANNEL) {
0896 int verticalIndex = 2 * detId.plane() + (detId.channel() - HPTDC_0_CHANNEL);
0897 for (unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex)
0898 if (hptdcErrors.errorId(hptdcErrorIndex - 1))
0899 potPlots_[detId_pot].HPTDCErrorFlags_2D->Fill(hptdcErrorIndex, verticalIndex);
0900 }
0901 if (digi.multipleHit())
0902 ++potPlots_[detId_pot].MHCounter;
0903 }
0904 }
0905 }
0906
0907
0908 if (extract_digi_info_) {
0909 for (const auto& vfat_status : *diamondVFATStatus) {
0910 const CTPPSDiamondDetId detId(vfat_status.detId());
0911 for (const auto& status : vfat_status) {
0912 if (!status.isOK())
0913 continue;
0914 if (potPlots_.count(detId.rpId()) == 0)
0915 continue;
0916 if (channelPlots_.count(detId) == 0)
0917 continue;
0918
0919
0920 for (const auto& optorx : *fedInfo) {
0921 if (detId.arm() == 1 && optorx.fedId() == CTPPS_FED_ID_56)
0922 checkEventNumber(detId, optorx, status, potPlots_[detId.rpId()], EC_difference_56_);
0923 else if (detId.arm() == 0 && optorx.fedId() == CTPPS_FED_ID_45)
0924 checkEventNumber(detId, optorx, status, potPlots_[detId.rpId()], EC_difference_45_);
0925 }
0926 }
0927 }
0928 }
0929
0930
0931 std::unordered_map<unsigned int, std::set<unsigned int>> planes;
0932 std::unordered_map<unsigned int, std::set<unsigned int>> planes_inclusive;
0933
0934 auto lumiCache = luminosityBlockCache(event.getLuminosityBlock().index());
0935 for (const auto& rechits : *diamondRecHits) {
0936 const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
0937 const auto& x_shift = diamShifts_.at(detId_pot);
0938
0939 for (const auto& rechit : rechits) {
0940 planes_inclusive[detId_pot].insert(detId.plane());
0941 if (excludeMultipleHits_ && rechit.multipleHits() > 0)
0942 continue;
0943 if (rechit.toT() != 0 && centralOOT_ != -999 && rechit.ootIndex() == centralOOT_)
0944 planes[detId_pot].insert(detId.plane());
0945
0946 if (potPlots_.count(detId_pot) == 0)
0947 continue;
0948
0949 potPlots_[detId_pot].recHitTime->Fill(rechit.time());
0950
0951 float UFSDShift = 0.0;
0952 if (rechit.yWidth() < 3)
0953 UFSDShift = 0.5;
0954
0955 if (rechit.toT() != 0 && centralOOT_ != -999 && rechit.ootIndex() == centralOOT_) {
0956 TH2F* hitHistoTmp = potPlots_[detId_pot].hitDistribution2d->getTH2F();
0957 TAxis* hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
0958 int startBin = hitHistoTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
0959 int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
0960 for (int i = 0; i < numOfBins; ++i)
0961 hitHistoTmp->Fill(detId.plane() + UFSDShift, hitHistoTmpYAxis->GetBinCenter(startBin + i));
0962
0963 if (!perLSsaving_ && plotOnline_) {
0964 hitHistoTmp = lumiCache->hitDistribution2dMap[detId_pot].get();
0965 hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
0966 startBin = hitHistoTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
0967 numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
0968 for (int i = 0; i < numOfBins; ++i)
0969 hitHistoTmp->Fill(detId.plane() + UFSDShift, hitHistoTmpYAxis->GetBinCenter(startBin + i));
0970 }
0971 }
0972
0973 if (rechit.toT() > 0) {
0974
0975 potPlots_[detId_pot].leadingEdgeCumulative_both->Fill(rechit.time() + 25 * rechit.ootIndex());
0976 potPlots_[detId_pot].timeOverThresholdCumulativePot->Fill(rechit.toT());
0977
0978 TH2F* hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT->getTH2F();
0979 TAxis* hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
0980 int startBin = hitHistoOOTTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
0981 int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
0982 for (int i = 0; i < numOfBins; ++i)
0983 hitHistoOOTTmp->Fill(detId.plane() + 1. / windowsNum_ * rechit.ootIndex(),
0984 hitHistoOOTTmpYAxis->GetBinCenter(startBin + i));
0985
0986 } else if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && plotOnline_) {
0987
0988 TH2F* hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT_le->getTH2F();
0989 TAxis* hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
0990 int startBin = hitHistoOOTTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
0991 int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
0992 for (int i = 0; i < numOfBins; ++i)
0993 hitHistoOOTTmp->Fill(detId.plane() + 1. / windowsNum_ * rechit.ootIndex(),
0994 hitHistoOOTTmpYAxis->GetBinCenter(startBin + i));
0995 }
0996 if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING &&
0997 potPlots_[detId_pot].activity_per_bx.count(rechit.ootIndex()) > 0)
0998 potPlots_[detId_pot].activity_per_bx.at(rechit.ootIndex())->Fill(event.bunchCrossing());
0999
1000
1001
1002 }
1003 }
1004
1005 for (const auto& plt : potPlots_) {
1006 plt.second.activePlanes->Fill(planes[plt.first].size());
1007 if (plotOnline_)
1008 plt.second.activePlanesInclusive->Fill(planes_inclusive[plt.first].size());
1009 }
1010
1011
1012 for (const auto& tracks : *diamondLocalTracks) {
1013 const CTPPSDiamondDetId detId(tracks.detId()), detId_pot(detId.rpId());
1014 const auto& x_shift = diamShifts_.at(detId_pot);
1015
1016 for (const auto& track : tracks) {
1017 if (!track.isValid())
1018 continue;
1019 if (track.ootIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING)
1020 continue;
1021 if (excludeMultipleHits_ && track.multipleHits() > 0)
1022 continue;
1023 if (potPlots_.count(detId_pot) == 0)
1024 continue;
1025
1026 TH2F* trackHistoOOTTmp = potPlots_[detId_pot].trackDistributionOOT->getTH2F();
1027 TAxis* trackHistoOOTTmpYAxis = trackHistoOOTTmp->GetYaxis();
1028 int startBin = trackHistoOOTTmpYAxis->FindBin(track.x0() - x_shift.global - track.x0Sigma());
1029 int numOfBins = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
1030 for (int i = 0; i < numOfBins; ++i)
1031 trackHistoOOTTmp->Fill(track.ootIndex(), trackHistoOOTTmpYAxis->GetBinCenter(startBin + i));
1032
1033 if (centralOOT_ != -999 && track.ootIndex() == centralOOT_) {
1034 TH1F* trackHistoInTimeTmp = potPlots_[detId_pot].trackDistribution->getTH1F();
1035 int startBin = trackHistoInTimeTmp->FindBin(track.x0() - x_shift.global - track.x0Sigma());
1036 int numOfBins = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
1037 for (int i = 0; i < numOfBins; ++i)
1038 trackHistoInTimeTmp->Fill(trackHistoInTimeTmp->GetBinCenter(startBin + i));
1039 }
1040 if (plotOffline_ && !perLSsaving_) {
1041
1042 potPlots_[detId_pot].trackTimeVsBX->Fill(event.bunchCrossing(), track.time());
1043 }
1044 }
1045 }
1046
1047
1048 for (const auto& tracks : *diamondLocalTracks) {
1049 const CTPPSDiamondDetId detId(tracks.detId()), detId_pot(detId.rpId());
1050 for (const auto& track : tracks) {
1051
1052 int numOfHits = 0;
1053 std::set<int> planesInTrackSet;
1054 for (const auto& vec : *diamondRecHits) {
1055 const CTPPSDiamondDetId detid(vec.detId());
1056 if (detid.arm() != detId_pot.arm())
1057 continue;
1058
1059 for (const auto& hit : vec) {
1060
1061 if (track.containsHit(hit)) {
1062 ++numOfHits;
1063 planesInTrackSet.insert(detid.plane());
1064 }
1065 }
1066 }
1067
1068 if (numOfHits > 0 && numOfHits <= 10 && planesInTrackSet.size() > 2) {
1069 for (const auto& plt_vs_ch : channelPlots_) {
1070 const CTPPSDiamondDetId detId(plt_vs_ch.first);
1071 if (detId.rpId() != detId_pot)
1072 continue;
1073 const unsigned short map_index = detId.plane() * 100 + detId.channel();
1074 if (potPlots_[detId_pot].effDoublecountingChMap.count(map_index) == 0) {
1075 potPlots_[detId_pot].effTriplecountingChMap[map_index] = 0;
1076 potPlots_[detId_pot].effDoublecountingChMap[map_index] = 0;
1077 }
1078 if (channelAlignedWithTrack(ctppsGeometry, detId, track, 0.2)) {
1079
1080 ++potPlots_[detId_pot].effDoublecountingChMap[map_index];
1081 for (const auto& rechits : *diamondRecHits) {
1082 const CTPPSDiamondDetId detId_hit(rechits.detId());
1083 if (detId_hit == detId)
1084 for (const auto& rechit : rechits)
1085 if (track.containsHit(rechit, 1))
1086 ++potPlots_[detId_pot].effTriplecountingChMap[map_index];
1087 }
1088 }
1089 }
1090 }
1091 }
1092 }
1093
1094
1095 for (const auto& rechits : *diamondRecHits) {
1096 const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
1097 const auto pix_shift = diamShifts_.at(detId_pot).withPixels;
1098 for (const auto& rechit : rechits) {
1099 if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1100 continue;
1101 if (rechit.toT() == 0)
1102 continue;
1103 if (!pixelTracks.isValid())
1104 continue;
1105 if (potPlots_.count(detId_pot) == 0)
1106 continue;
1107
1108 for (const auto& ds : *pixelTracks) {
1109 if (ds.size() > 1)
1110 continue;
1111 const CTPPSPixelDetId pixId(ds.detId());
1112 if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_PIXEL_FAR_RP_ID)
1113 continue;
1114 for (const auto& lt : ds) {
1115 if (lt.isValid() && pixId.arm() == detId_pot.arm()) {
1116 if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.ootIndex() >= 0 &&
1117 potPlots_[detId_pot].pixelTomographyAll.count(rechit.ootIndex()) > 0 && lt.x0() - pix_shift < 24)
1118 potPlots_[detId_pot]
1119 .pixelTomographyAll.at(rechit.ootIndex())
1120 ->Fill(lt.x0() - pix_shift + 25 * detId.plane(), lt.y0());
1121 }
1122 }
1123 }
1124 }
1125 }
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154 std::unordered_map<unsigned int, unsigned int> channelsPerPlane;
1155 if (extract_digi_info_) {
1156 for (const auto& digis : *diamondDigis) {
1157 const CTPPSDiamondDetId detId(digis.detId()), detId_plane(detId.planeId());
1158 for (const auto& digi : digis) {
1159 if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
1160 continue;
1161 if (planePlots_.count(detId_plane) == 0)
1162 continue;
1163
1164 if (digi.leadingEdge() != 0) {
1165 planePlots_[detId_plane].digiProfileCumulativePerPlane->Fill(detId.channel());
1166 channelsPerPlane[detId_plane]++;
1167 }
1168
1169
1170 if ((digi.trailingEdge() == 0) && (digi.leadingEdge() != 0)) {
1171 planePlots_[detId_plane].leadingEdgeCumulativePerPlane_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
1172 } else if ((digi.leadingEdge() == 0 && (digi.trailingEdge() != 0))) {
1173 planePlots_[detId_plane].trailingEdgeCumulativePerPlane_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
1174 }
1175 }
1176 }
1177 }
1178
1179 for (const auto& plt : channelsPerPlane)
1180 planePlots_[plt.first].hit_multiplicity->Fill(plt.second);
1181
1182
1183 for (const auto& rechits : *diamondRecHits) {
1184 const CTPPSDiamondDetId detId(rechits.detId()), detId_plane(detId.planeId()), detId_pot(detId.rpId());
1185 for (const auto& rechit : rechits) {
1186 if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1187 continue;
1188 if (rechit.toT() == 0)
1189 continue;
1190
1191 if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING) {
1192 planePlots_[detId_plane].leadingEdgeCumulativePerPlane_both->Fill(rechit.time() + 25 * rechit.ootIndex());
1193 planePlots_[detId_plane].TimeOverThresholdCumulativePerPlane->Fill(rechit.toT());
1194 }
1195 if (planePlots_.count(detId_plane) != 0) {
1196 if (centralOOT_ != -999 && rechit.ootIndex() == centralOOT_) {
1197 TH1F* hitHistoTmp = planePlots_[detId_plane].hitProfile->getTH1F();
1198 int startBin = hitHistoTmp->FindBin(rechit.x() - diamShifts_.at(detId_pot).global - 0.5 * rechit.xWidth());
1199 int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
1200 for (int i = 0; i < numOfBins; ++i)
1201 hitHistoTmp->Fill(hitHistoTmp->GetBinCenter(startBin + i));
1202 }
1203 }
1204 }
1205 }
1206
1207
1208 for (const auto& ds : *pixelTracks) {
1209 const CTPPSPixelDetId pixId(ds.detId());
1210 if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_PIXEL_FAR_RP_ID)
1211 continue;
1212 if (ds.size() > 1)
1213 continue;
1214 for (const auto& lt : ds) {
1215 if (lt.isValid()) {
1216 for (const auto& sh_vs_id : diamShifts_) {
1217 const CTPPSDiamondDetId& detId_pot = sh_vs_id.first;
1218 const auto& shift = sh_vs_id.second;
1219 if (detId_pot.arm() == pixId.arm())
1220
1221 potPlots_[detId_pot].pixelTracksMap.Fill(lt.x0() - shift.withPixels, lt.y0());
1222 }
1223
1224 std::set<CTPPSDiamondDetId> planesWitHits_set;
1225 for (const auto& rechits : *diamondRecHits) {
1226 const CTPPSDiamondDetId detId(rechits.detId()), detId_plane(detId.planeId()), detId_pot(detId.rpId());
1227 const auto pix_shift = diamShifts_.at(detId_pot).withPixels;
1228 for (const auto& rechit : rechits) {
1229 if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1230 continue;
1231 if (rechit.ootIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.toT() == 0)
1232 continue;
1233 if (planePlots_.count(detId_plane) == 0)
1234 continue;
1235 if (pixId.arm() == detId_plane.arm() && lt.x0() - pix_shift < 24) {
1236 planePlots_[detId_plane].pixelTomography_far->Fill(lt.x0() - pix_shift + 25 * rechit.ootIndex(), lt.y0());
1237 if (centralOOT_ != -999 && rechit.ootIndex() == centralOOT_)
1238 planesWitHits_set.insert(detId_plane);
1239 }
1240 }
1241 }
1242
1243 for (auto& planeId : planesWitHits_set)
1244 planePlots_[planeId].pixelTracksMapWithDiamonds.Fill(lt.x0() - diamShifts_.at(planeId.rpId()).withPixels,
1245 lt.y0());
1246 }
1247 }
1248 }
1249
1250
1251
1252
1253
1254
1255 if (extract_digi_info_) {
1256 for (const auto& digis : *diamondDigis) {
1257 const CTPPSDiamondDetId detId(digis.detId());
1258 for (const auto& digi : digis) {
1259 if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
1260 continue;
1261 if (channelPlots_.count(detId) != 0) {
1262
1263 const HPTDCErrorFlags hptdcErrors = digi.hptdcErrorFlags();
1264 for (unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex)
1265 if (hptdcErrors.errorId(hptdcErrorIndex - 1))
1266 channelPlots_[detId].HPTDCErrorFlags->Fill(hptdcErrorIndex);
1267 if (digi.multipleHit())
1268 ++channelPlots_[detId].MHCounter;
1269
1270
1271 if (digi.leadingEdge() != 0 || digi.trailingEdge() != 0) {
1272 ++channelPlots_[detId].HitCounter;
1273 if (digi.trailingEdge() == 0) {
1274 ++channelPlots_[detId].LeadingOnlyCounter;
1275 channelPlots_[detId].leadingEdgeCumulative_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
1276 } else if (digi.leadingEdge() == 0) {
1277 ++channelPlots_[detId].TrailingOnlyCounter;
1278 channelPlots_[detId].trailingEdgeCumulative_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
1279 } else {
1280 ++channelPlots_[detId].CompleteCounter;
1281
1282
1283 }
1284 }
1285 }
1286 }
1287 }
1288 }
1289
1290
1291
1292 for (const auto& rechits : *diamondRecHits) {
1293 CTPPSDiamondDetId detId(rechits.detId());
1294 for (const auto& rechit : rechits) {
1295 if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1296 continue;
1297 if (channelPlots_.count(detId) != 0) {
1298 channelPlots_[detId].recHitTime->Fill(rechit.time());
1299 if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.toT() != 0) {
1300 channelPlots_[detId].leadingEdgeCumulative_both->Fill(rechit.time() + 25 * rechit.ootIndex());
1301 channelPlots_[detId].TimeOverThresholdCumulativePerChannel->Fill(rechit.toT());
1302 }
1303 ++lumiCache->hitsCounterMap[detId];
1304
1305 if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING &&
1306 channelPlots_[detId].activity_per_bx.count(rechit.ootIndex()) > 0)
1307 channelPlots_[detId].activity_per_bx.at(rechit.ootIndex())->Fill(event.bunchCrossing());
1308 }
1309 }
1310 }
1311
1312
1313 for (const auto& rechits : *diamondRecHits) {
1314 const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
1315 const auto shift_pix = diamShifts_.at(detId_pot).withPixels;
1316 for (const auto& rechit : rechits) {
1317 if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1318 continue;
1319 if (rechit.ootIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.toT() == 0)
1320 continue;
1321 if (!pixelTracks.isValid())
1322 continue;
1323 if (channelPlots_.count(detId) == 0)
1324 continue;
1325
1326 for (const auto& ds : *pixelTracks) {
1327 const CTPPSPixelDetId pixId(ds.detId());
1328 if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_PIXEL_FAR_RP_ID)
1329 continue;
1330 if (ds.size() > 1)
1331 continue;
1332 for (const auto& lt : ds) {
1333 if (lt.isValid() && pixId.arm() == detId.arm() && lt.x0() - shift_pix < 24)
1334 channelPlots_[detId].pixelTomography_far->Fill(lt.x0() - shift_pix + 25 * rechit.ootIndex(), lt.y0());
1335 }
1336 }
1337 }
1338 }
1339 }
1340
1341
1342
1343 void CTPPSDiamondDQMSource::globalEndLuminosityBlock(const edm::LuminosityBlock& iLumi, const edm::EventSetup&) {
1344 auto lumiCache = luminosityBlockCache(iLumi.index());
1345 if (!perLSsaving_) {
1346 if (plotOnline_)
1347 for (auto& plot : potPlots_)
1348 *(plot.second.hitDistribution2d_lumisection->getTH2F()) = *(lumiCache->hitDistribution2dMap[plot.first]);
1349
1350 for (auto& plot : channelPlots_) {
1351 auto hitsCounterPerLumisection = lumiCache->hitsCounterMap[plot.first];
1352 if (hitsCounterPerLumisection != 0) {
1353 plot.second.hit_rate->Fill((double)hitsCounterPerLumisection / SEC_PER_LUMI_SECTION);
1354 }
1355
1356 double HundredOverHitCounter = .0;
1357 if (plot.second.HitCounter != 0)
1358 HundredOverHitCounter = 100. / plot.second.HitCounter;
1359 plot.second.HPTDCErrorFlags->setBinContent(16, HundredOverHitCounter * plot.second.MHCounter);
1360 plot.second.leadingWithoutTrailing->setBinContent(1, HundredOverHitCounter * plot.second.LeadingOnlyCounter);
1361 plot.second.leadingWithoutTrailing->setBinContent(2, HundredOverHitCounter * plot.second.TrailingOnlyCounter);
1362 plot.second.leadingWithoutTrailing->setBinContent(3, HundredOverHitCounter * plot.second.CompleteCounter);
1363 }
1364
1365 for (auto& plot : potPlots_) {
1366 double HundredOverHitCounterPot = 0.;
1367 if (plot.second.HitCounter != 0)
1368 HundredOverHitCounterPot = 100. / plot.second.HitCounter;
1369 plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1370 1, HundredOverHitCounterPot * plot.second.LeadingOnlyCounter);
1371 plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1372 2, HundredOverHitCounterPot * plot.second.TrailingOnlyCounter);
1373 plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1374 3, HundredOverHitCounterPot * plot.second.CompleteCounter);
1375
1376 plot.second.MHComprensive->Reset();
1377 const CTPPSDiamondDetId rpId(plot.first);
1378 for (auto& chPlot : channelPlots_) {
1379 const CTPPSDiamondDetId chId(chPlot.first);
1380 if (chId.arm() == rpId.arm() && chId.rp() == rpId.rp()) {
1381 plot.second.MHComprensive->Fill(
1382 chId.plane(), chId.channel(), chPlot.second.HPTDCErrorFlags->getBinContent(16));
1383 }
1384 }
1385 }
1386
1387 if (plotOnline_)
1388 for (auto& plot : potPlots_) {
1389 plot.second.EfficiencyOfChannelsInPot->Reset();
1390 for (auto& element : plot.second.effTriplecountingChMap) {
1391 if (plot.second.effDoublecountingChMap[element.first] > 0) {
1392 int plane = element.first / 100;
1393 int channel = element.first % 100;
1394 double counted = element.second;
1395 double total = plot.second.effDoublecountingChMap[element.first];
1396 double efficiency = counted / total;
1397
1398
1399 plot.second.EfficiencyOfChannelsInPot->Fill(plane, channel, 100 * efficiency);
1400 }
1401 }
1402 }
1403
1404
1405 for (auto& plot : planePlots_) {
1406 TH2F* hitHistoTmp = plot.second.EfficiencyWRTPixelsInPlane->getTH2F();
1407
1408 const CTPPSDiamondDetId detId(plot.first), detId_pot(detId.rpId());
1409 hitHistoTmp->Divide(&(plot.second.pixelTracksMapWithDiamonds), &(potPlots_[detId_pot].pixelTracksMap));
1410 }
1411 }
1412 }
1413
1414
1415
1416 void CTPPSDiamondDQMSource::checkEventNumber(const CTPPSDiamondDetId& detId,
1417 const TotemFEDInfo& optorx,
1418 const TotemVFATStatus& status,
1419 CTPPSDiamondDQMSource::PotPlots& plots,
1420 int& EC_difference) const {
1421 const CTPPSDiamondDetId detId_pot(detId.rpId());
1422 if (plotOnline_)
1423 plots.ECCheck->Fill((int)((optorx.lv1() & 0xFF) - ((unsigned int)status.ec() & 0xFF)) & 0xFF);
1424 if ((static_cast<int>((optorx.lv1() & 0xFF) - status.ec()) != EC_difference) &&
1425 (static_cast<uint8_t>((optorx.lv1() & 0xFF) - status.ec()) < 128))
1426 EC_difference = static_cast<int>(optorx.lv1() & 0xFF) - (static_cast<unsigned int>(status.ec()) & 0xFF);
1427 if (EC_difference != 1 && EC_difference != -500 && std::abs(EC_difference) < 127) {
1428 if (detId.channel() == HPTDC_0_CHANNEL || detId.channel() == HPTDC_1_CHANNEL)
1429 plots.HPTDCErrorFlags_2D->Fill(16, 2 * detId.plane() + (detId.channel() - HPTDC_0_CHANNEL));
1430 if (verbosity_)
1431 edm::LogProblem("CTPPSDiamondDQMSource")
1432 << "FED " << optorx.fedId() << ": ECError at EV: 0x" << std::hex << optorx.lv1() << "\t\tVFAT EC: 0x"
1433 << static_cast<unsigned int>(status.ec()) << "\twith ID: " << std::dec << detId
1434 << "\tdiff: " << EC_difference;
1435 }
1436 }
1437
1438
1439
1440 void CTPPSDiamondDQMSource::dqmEndRun(edm::Run const&, edm::EventSetup const&) {
1441 if (plotOffline_ && !perLSsaving_)
1442 for (const auto& rpPlots : potPlots_) {
1443 auto plots = rpPlots.second;
1444
1445
1446 *(plots.trackTimeVsBXProfile->getTProfile()) = *plots.trackTimeVsBX->getTH2F()->ProfileX();
1447
1448 }
1449 }
1450
1451
1452 DEFINE_FWK_MODULE(CTPPSDiamondDQMSource);