CMS 3D CMS Logo

CTPPSDiamondDQMSource.cc
Go to the documentation of this file.
1 /****************************************************************************
2 *
3 * This is a part of CTPPS offline software.
4 * Authors:
5 * Jan Kašpar (jan.kaspar@gmail.com)
6 * Nicola Minafra
7 * Laurent Forthomme
8 *
9 ****************************************************************************/
10 
18 
22 
27 
30 
33 
38 
39 #include <string>
40 
41 //----------------------------------------------------------------------------------------------------
42 
43 
44 // Utility for efficiency computations
45 bool channelAlignedWithTrack( const CTPPSGeometry* geom, const CTPPSDiamondDetId& detid, const CTPPSDiamondLocalTrack& localTrack, const float tolerance=1) {
46  const DetGeomDesc* det = geom->getSensor( detid );
47  const float x_pos = det->translation().x(),
48  x_width = 2.0 * det->params().at( 0 ); // parameters stand for half the size
49  return
50  ( ( x_pos + 0.5 * x_width > localTrack.getX0() - localTrack.getX0Sigma() - tolerance
51  && x_pos + 0.5 * x_width < localTrack.getX0() + localTrack.getX0Sigma() + tolerance )
52  || ( x_pos - 0.5 * x_width > localTrack.getX0() - localTrack.getX0Sigma() - tolerance
53  && x_pos - 0.5 * x_width < localTrack.getX0() + localTrack.getX0Sigma() + tolerance )
54  || ( x_pos - 0.5 * x_width < localTrack.getX0() - localTrack.getX0Sigma() - tolerance
55  && x_pos + 0.5 * x_width > localTrack.getX0() + localTrack.getX0Sigma() + tolerance ) );
56 }
57 
58 
59 namespace dds {
60  struct Cache {
61  std::unordered_map<unsigned int, std::unique_ptr<TH2F>> hitDistribution2dMap;
62 
63  std::unordered_map<unsigned int, unsigned long> hitsCounterMap;
64  };
65 }
66 
67 class CTPPSDiamondDQMSource : public one::DQMEDAnalyzer<edm::LuminosityBlockCache<dds::Cache>>
68 {
69  public:
71  ~CTPPSDiamondDQMSource() override;
72 
73  protected:
74  void dqmBeginRun( const edm::Run&, const edm::EventSetup& ) override;
75  void bookHistograms( DQMStore::IBooker&, const edm::Run&, const edm::EventSetup& ) override;
76  void analyze( const edm::Event&, const edm::EventSetup& ) override;
77  std::shared_ptr<dds::Cache> globalBeginLuminosityBlock( const edm::LuminosityBlock&, const edm::EventSetup& ) const override;
78  void globalEndLuminosityBlock( const edm::LuminosityBlock&, const edm::EventSetup& ) override;
79  void endRun( const edm::Run&, const edm::EventSetup& ) override;
80 
81  private:
82  // Constants
83  static const double SEC_PER_LUMI_SECTION; // Number of seconds per lumisection: used to compute hit rates in Hz
84  static const int CHANNEL_OF_VFAT_CLOCK; // Channel ID of the VFAT that contains clock data
85  static const double DISPLAY_RESOLUTION_FOR_HITS_MM; // Bin width of histograms showing hits and tracks (in mm)
87  static const double HPTDC_BIN_WIDTH_NS; // ns per HPTDC bin
88  static const int CTPPS_NUM_OF_ARMS;
89  static const int CTPPS_DIAMOND_STATION_ID;
90  static const int CTPPS_DIAMOND_RP_ID;
91  static const int CTPPS_PIXEL_STATION_ID;
92  static const int CTPPS_NEAR_RP_ID;
93  static const int CTPPS_FAR_RP_ID;
94  static const int CTPPS_DIAMOND_NUM_OF_PLANES;
96  static const int CTPPS_FED_ID_45;
97  static const int CTPPS_FED_ID_56;
98 
105 
109  std::vector< std::pair<edm::EventRange, int> > runParameters_;
111  unsigned int verbosity_;
112 
114  struct GlobalPlots
115  {
117  GlobalPlots( DQMStore::IBooker& ibooker );
118  };
119 
121 
123  struct PotPlots
124  {
125  MonitorElement* activity_per_bx_0_25 = nullptr;
126  MonitorElement* activity_per_bx_25_50 = nullptr;
127  MonitorElement* activity_per_bx_50_75 = nullptr;
128  std::vector< MonitorElement* > activity_per_bx;
129 
130  MonitorElement* hitDistribution2d = nullptr;
131  MonitorElement* hitDistribution2d_lumisection = nullptr;
132  MonitorElement* hitDistribution2dOOT = nullptr;
133  MonitorElement* hitDistribution2dOOT_le = nullptr;
134  MonitorElement* activePlanes = nullptr, *activePlanesInclusive = nullptr;
135 
136  MonitorElement* trackDistribution = nullptr;
137  MonitorElement* trackDistributionOOT = nullptr;
138 
139  MonitorElement* pixelTomographyAll_0_25 = nullptr;
140  MonitorElement* pixelTomographyAll_25_50 = nullptr;
141  MonitorElement* pixelTomographyAll_50_75 = nullptr;
142  std::vector< MonitorElement* > pixelTomographyAll;
143 
144  MonitorElement* leadingEdgeCumulative_both = nullptr, *leadingEdgeCumulative_all = nullptr, *leadingEdgeCumulative_le = nullptr, *trailingEdgeCumulative_te = nullptr;
145  MonitorElement* timeOverThresholdCumulativePot = nullptr, *leadingTrailingCorrelationPot = nullptr;
146  MonitorElement* leadingWithoutTrailingCumulativePot = nullptr;
147 
148  MonitorElement* ECCheck = nullptr;
149 
150  MonitorElement* HPTDCErrorFlags_2D = nullptr;
151  MonitorElement* MHComprensive = nullptr;
152 
153  // MonitorElement* clock_Digi1_le = nullptr;
154  // MonitorElement* clock_Digi1_te = nullptr;
155  // MonitorElement* clock_Digi3_le = nullptr;
156  // MonitorElement* clock_Digi3_te = nullptr;
157 
158  unsigned int HitCounter, MHCounter, LeadingOnlyCounter, TrailingOnlyCounter, CompleteCounter;
159 
160  std::map<int, int> effTriplecountingChMap;
161  std::map<int, int> effDoublecountingChMap;
162  MonitorElement* EfficiencyOfChannelsInPot = nullptr;
164 
165  PotPlots() {}
166  PotPlots( DQMStore::IBooker& ibooker, unsigned int id );
167  };
168 
169  std::unordered_map<unsigned int, PotPlots> potPlots_;
170  int EC_difference_56_, EC_difference_45_;
171 
173  struct PlanePlots
174  {
175  MonitorElement* digiProfileCumulativePerPlane = nullptr;
176  MonitorElement* hitProfile = nullptr;
177  MonitorElement* hit_multiplicity = nullptr;
178 
179  MonitorElement* pixelTomography_far = nullptr;
180  MonitorElement* EfficiencyWRTPixelsInPlane = nullptr;
181 
183 
185  PlanePlots( DQMStore::IBooker& ibooker, unsigned int id );
186  };
187 
188  std::unordered_map<unsigned int, PlanePlots> planePlots_;
189 
192  {
193  MonitorElement* activity_per_bx_0_25 = nullptr;
194  MonitorElement* activity_per_bx_25_50 = nullptr;
195  MonitorElement* activity_per_bx_50_75 = nullptr;
196  std::vector< MonitorElement* > activity_per_bx;
197 
199  MonitorElement* leadingEdgeCumulative_both = nullptr, *leadingEdgeCumulative_le = nullptr, *trailingEdgeCumulative_te = nullptr;
200  MonitorElement* TimeOverThresholdCumulativePerChannel = nullptr;
201  MonitorElement* LeadingTrailingCorrelationPerChannel = nullptr;
202  MonitorElement* leadingWithoutTrailing = nullptr;
203  MonitorElement* pixelTomography_far = nullptr;
204  MonitorElement* hit_rate = nullptr;
205 
206  unsigned int HitCounter, MHCounter, LeadingOnlyCounter, TrailingOnlyCounter, CompleteCounter;
207 
209  ChannelPlots( DQMStore::IBooker &ibooker, unsigned int id );
210  };
211 
212  std::unordered_map<unsigned int, ChannelPlots> channelPlots_;
213 };
214 
215 //----------------------------------------------------------------------------------------------------
216 
217 // Values for all constants
221 const double CTPPSDiamondDQMSource::INV_DISPLAY_RESOLUTION_FOR_HITS_MM = 1./DISPLAY_RESOLUTION_FOR_HITS_MM;
222 const double CTPPSDiamondDQMSource::HPTDC_BIN_WIDTH_NS = 25./1024;
233 
234 //----------------------------------------------------------------------------------------------------
235 
237 {
238  ibooker.setCurrentFolder( "CTPPS" );
239 }
240 
241 //----------------------------------------------------------------------------------------------------
242 
243 
244 CTPPSDiamondDQMSource::PotPlots::PotPlots( DQMStore::IBooker& ibooker, unsigned int id ): HitCounter(0), MHCounter(0), LeadingOnlyCounter(0), TrailingOnlyCounter(0), CompleteCounter(0), pixelTracksMap("Pixel track maps for efficiency", "Pixel track maps for efficiency", 25, 0, 25, 12, -2, 10 )
245 {
248  ibooker.setCurrentFolder( path );
249 
251 
252  activity_per_bx_0_25 = ibooker.book1D( "activity per BX 0 25", title+" Activity per BX 0 - 25 ns;Event.BX", 3600, -1.5, 3598. + 0.5 );
254  activity_per_bx_25_50 = ibooker.book1D( "activity per BX 25 50", title+" Activity per BX 25 - 50 ns;Event.BX", 3600, -1.5, 3598. + 0.5 );
256  activity_per_bx_50_75 = ibooker.book1D( "activity per BX 50 75", title+" Activity per BX 50 - 75 ns;Event.BX", 3600, -1.5, 3598. + 0.5 );
258 
259  hitDistribution2d = ibooker.book2D( "hits in planes", title+" hits in planes;plane number;x (mm)", 10, -0.5, 4.5, 19.*INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5 );
260  hitDistribution2d_lumisection = ibooker.book2D( "hits in planes lumisection", title+" hits in planes in the last lumisection;plane number;x (mm)", 10, -0.5, 4.5, 19.*INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5 );
261  hitDistribution2dOOT= ibooker.book2D( "hits with OOT in planes", title+" hits with OOT in planes;plane number + 0.25 OOT;x (mm)", 17, -0.25, 4, 19.*INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5 );
262  hitDistribution2dOOT_le= ibooker.book2D( "hits with OOT in planes (le only)", title+" hits with OOT in planes (le only);plane number + 0.25 OOT;x (mm)", 17, -0.25, 4, 19.*INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5 );
263  activePlanes = ibooker.book1D( "active planes", title+" active planes (per event);number of active planes", 6, -0.5, 5.5 );
264  activePlanesInclusive = ibooker.book1D( "active planes inclusive", title+" active planes, MH and le only included (per event);number of active planes", 6, -0.5, 5.5 );
265 
266  trackDistribution = ibooker.book1D( "tracks", title+" tracks;x (mm)", 19.*INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5 );
267  trackDistributionOOT = ibooker.book2D( "tracks with OOT", title+" tracks with OOT;plane number;x (mm)", 9, -0.5, 4, 19.*INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5 );
268 
269  pixelTomographyAll_0_25 = ibooker.book2D( "tomography pixel 0 25", title+" tomography with pixel 0 - 25 ns (all planes);x + 25*plane(mm);y (mm)", 100, 0, 100, 8, 0, 8 );
271  pixelTomographyAll_25_50 = ibooker.book2D( "tomography pixel 25 50", title+" tomography with pixel 25 - 50 ns (all planes);x + 25*plane(mm);y (mm)", 100, 0, 100, 8, 0, 8 );
273  pixelTomographyAll_50_75 = ibooker.book2D( "tomography pixel 50 75", title+" tomography with pixel 50 - 75 ns (all planes);x + 25*plane(mm);y (mm)", 100, 0, 100, 8, 0, 8 );
275 
276  leadingEdgeCumulative_both = ibooker.book1D( "leading edge (le and te)", title+" leading edge (le and te) (recHits); leading edge (ns)", 75, 0, 75 );
277  leadingEdgeCumulative_all = ibooker.book1D( "leading edge (all)", title+" leading edge (with or without te) (DIGIs); leading edge (ns)", 75, 0, 75 );
278  leadingEdgeCumulative_le = ibooker.book1D( "leading edge (le only)", title+" leading edge (le only) (DIGIs); leading edge (ns)", 75, 0, 75 );
279  trailingEdgeCumulative_te = ibooker.book1D( "trailing edge (te only)", title+" trailing edge (te only) (DIGIs); trailing edge (ns)", 75, 0, 75 );
280  timeOverThresholdCumulativePot = ibooker.book1D( "time over threshold", title+" time over threshold;time over threshold (ns)", 250, -25, 100 );
281  leadingTrailingCorrelationPot = ibooker.book2D( "leading trailing correlation", title+" leading trailing correlation;leading edge (ns);trailing edge (ns)", 75, 0, 75, 75, 0, 75 );
282 
283  leadingWithoutTrailingCumulativePot = ibooker.book1D( "event category", title+" leading edges without trailing;;%", 3, 0.5, 3.5 );
284  leadingWithoutTrailingCumulativePot->getTH1F()->GetXaxis()->SetBinLabel( 1, "Leading only" );
285  leadingWithoutTrailingCumulativePot->getTH1F()->GetXaxis()->SetBinLabel( 2, "Trailing only" );
286  leadingWithoutTrailingCumulativePot->getTH1F()->GetXaxis()->SetBinLabel( 3, "Both" );
287 
288  ECCheck = ibooker.book1D( "optorxEC(8bit) - vfatEC", title+" EC Error;optorxEC-vfatEC", 50,-25, 25 );
289 
290  HPTDCErrorFlags_2D = ibooker.book2D( "HPTDC Errors", title+" HPTDC Errors", 16, -0.5, 16.5, 9, -0.5, 8.5 );
291  for ( unsigned short error_index=1; error_index<16; ++error_index )
292  HPTDCErrorFlags_2D->getTH2F()->GetXaxis()->SetBinLabel( error_index, HPTDCErrorFlags::getHPTDCErrorName( error_index-1 ).c_str() );
293  HPTDCErrorFlags_2D->getTH2F()->GetXaxis()->SetBinLabel( 16, "Wrong EC" );
294 
295  int tmpIndex=0;
296  HPTDCErrorFlags_2D->getTH2F()->GetYaxis()->SetBinLabel( ++tmpIndex, "DB 0 TDC 18" );
297  HPTDCErrorFlags_2D->getTH2F()->GetYaxis()->SetBinLabel( ++tmpIndex, "DB 0 TDC 17" );
298  HPTDCErrorFlags_2D->getTH2F()->GetYaxis()->SetBinLabel( ++tmpIndex, "DB 0 TDC 16" );
299  HPTDCErrorFlags_2D->getTH2F()->GetYaxis()->SetBinLabel( ++tmpIndex, "DB 0 TDC 15" );
300  HPTDCErrorFlags_2D->getTH2F()->GetYaxis()->SetBinLabel( ++tmpIndex, "DB 1 TDC 18" );
301  HPTDCErrorFlags_2D->getTH2F()->GetYaxis()->SetBinLabel( ++tmpIndex, "DB 1 TDC 17" );
302  HPTDCErrorFlags_2D->getTH2F()->GetYaxis()->SetBinLabel( ++tmpIndex, "DB 1 TDC 16" );
303  HPTDCErrorFlags_2D->getTH2F()->GetYaxis()->SetBinLabel( ++tmpIndex, "DB 1 TDC 15" );
304 
305  MHComprensive = ibooker.book2D( "MH in channels", title+" MH (%) in channels;plane number;ch number", 10, -0.5, 4.5, 14, -1, 13 );
306 
307  EfficiencyOfChannelsInPot = ibooker.book2D( "Efficiency in channels", title+" Efficiency (%) in channels (diamonds only);plane number;ch number", 10, -0.5, 4.5, 14, -1, 13 );
308 
309  // ibooker.setCurrentFolder( path+"/clock/" );
310  // clock_Digi1_le = ibooker.book1D( "clock1 leading edge", title+" clock1;leading edge (ns)", 250, 0, 25 );
311  // clock_Digi1_te = ibooker.book1D( "clock1 trailing edge", title+" clock1;trailing edge (ns)", 75, 0, 75 );
312  // clock_Digi3_le = ibooker.book1D( "clock3 leading edge", title+" clock3;leading edge (ns)", 250, 0, 25 );
313  // clock_Digi3_te = ibooker.book1D( "clock3 trailing edge", title+" clock3;trailing edge (ns)", 75, 0, 75 );
314 
315 }
316 
317 //----------------------------------------------------------------------------------------------------
318 
319 CTPPSDiamondDQMSource::PlanePlots::PlanePlots( DQMStore::IBooker& ibooker, unsigned int id ) : pixelTracksMapWithDiamonds("Pixel track maps for efficiency with coincidence", "Pixel track maps for efficiency with coincidence", 25, 0, 25, 12, -2, 10 )
320 {
323  ibooker.setCurrentFolder( path );
324 
326 
327  digiProfileCumulativePerPlane = ibooker.book1D( "digi profile", title+" digi profile; ch number", 12, -0.5, 11.5 );
328  hitProfile = ibooker.book1D( "hit profile", title+" hit profile;x (mm)", 19.*INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5 );
329  hit_multiplicity = ibooker.book1D( "channels per plane", title+" channels per plane; ch per plane", 13, -0.5, 12.5 );
330 
331  pixelTomography_far = ibooker.book2D( "tomography pixel", title+" tomography with pixel;x + 25 OOT (mm);y (mm)", 75, 0, 75, 8, 0, 8 );
332  EfficiencyWRTPixelsInPlane = ibooker.book2D( "Efficiency wrt pixels", title+" Efficiency wrt pixels;x (mm);y (mm)", 25, 0, 25, 12, -2, 10 );
333 
334 }
335 
336 //----------------------------------------------------------------------------------------------------
337 
338 CTPPSDiamondDQMSource::ChannelPlots::ChannelPlots( DQMStore::IBooker& ibooker, unsigned int id ) : HitCounter(0), MHCounter(0), LeadingOnlyCounter(0), TrailingOnlyCounter(0), CompleteCounter(0)
339 {
342  ibooker.setCurrentFolder( path );
343 
345 
346  leadingWithoutTrailing = ibooker.book1D( "event category", title+" Event Category;;%", 3, 0.5, 3.5 );
347  leadingWithoutTrailing->getTH1F()->GetXaxis()->SetBinLabel( 1, "Leading only" );
348  leadingWithoutTrailing->getTH1F()->GetXaxis()->SetBinLabel( 2, "Trailing only" );
349  leadingWithoutTrailing->getTH1F()->GetXaxis()->SetBinLabel( 3, "Full" );
350 
351  activity_per_bx_0_25 = ibooker.book1D( "activity per BX 0 25", title+" Activity per BX 0 - 25 ns;Event.BX", 500, -1.5, 498. + 0.5 );
353  activity_per_bx_25_50 = ibooker.book1D( "activity per BX 25 50", title+" Activity per BX 25 - 50 ns;Event.BX", 500, -1.5, 498. + 0.5 );
355  activity_per_bx_50_75 = ibooker.book1D( "activity per BX 50 75", title+" Activity per BX 50 - 75 ns;Event.BX", 500, -1.5, 498. + 0.5 );
357 
358  HPTDCErrorFlags = ibooker.book1D( "hptdc_Errors", title+" HPTDC Errors", 16, -0.5, 16.5 );
359  for ( unsigned short error_index=1; error_index<16; ++error_index )
360  HPTDCErrorFlags->getTH1F()->GetXaxis()->SetBinLabel( error_index, HPTDCErrorFlags::getHPTDCErrorName( error_index-1 ).c_str() );
361  HPTDCErrorFlags->getTH1F()->GetXaxis()->SetBinLabel( 16, "MH (%)" );
362 
363  leadingEdgeCumulative_both = ibooker.book1D( "leading edge (le and te)", title+" leading edge (recHits); leading edge (ns)", 75, 0, 75 );
364  leadingEdgeCumulative_le = ibooker.book1D( "leading edge (le only)", title+" leading edge (DIGIs); leading edge (ns)", 75, 0, 75 );
365  trailingEdgeCumulative_te = ibooker.book1D( "trailing edge (te only)", title+" trailing edge (te only) (DIGIs); trailing edge (ns)", 75, 0, 75 );
366  TimeOverThresholdCumulativePerChannel = ibooker.book1D( "time over threshold", title+" time over threshold;time over threshold (ns)", 75, -25, 50 );
367  LeadingTrailingCorrelationPerChannel = ibooker.book2D( "leading trailing correlation", title+" leading trailing correlation;leading edge (ns);trailing edge (ns)", 75, 0, 75, 75, 0, 75 );
368 
369  pixelTomography_far = ibooker.book2D( "tomography pixel", "tomography with pixel;x + 25 OOT (mm);y (mm)", 75, 0, 75, 8, 0, 8 );
370 
371  hit_rate = ibooker.book1D( "hit rate", title+"hit rate;rate (Hz)", 40, 0, 20);
372 }
373 
374 //----------------------------------------------------------------------------------------------------
375 
377  tokenStatus_ ( consumes< edm::DetSetVector<TotemVFATStatus> > ( ps.getParameter<edm::InputTag>( "tagStatus" ) ) ),
378  tokenPixelTrack_ ( consumes< edm::DetSetVector<CTPPSPixelLocalTrack> > ( ps.getParameter<edm::InputTag>( "tagPixelLocalTracks" ) ) ),
379  tokenDigi_ ( consumes< edm::DetSetVector<CTPPSDiamondDigi> > ( ps.getParameter<edm::InputTag>( "tagDigi" ) ) ),
380  tokenDiamondHit_ ( consumes< edm::DetSetVector<CTPPSDiamondRecHit> > ( ps.getParameter<edm::InputTag>( "tagDiamondRecHits" ) ) ),
381  tokenDiamondTrack_( consumes< edm::DetSetVector<CTPPSDiamondLocalTrack> >( ps.getParameter<edm::InputTag>( "tagDiamondLocalTracks" ) ) ),
382  tokenFEDInfo_ ( consumes< std::vector<TotemFEDInfo> > ( ps.getParameter<edm::InputTag>( "tagFEDInfo" ) ) ),
383  excludeMultipleHits_ ( ps.getParameter<bool>( "excludeMultipleHits" ) ),
384  centralOOT_( -999 ),
385  verbosity_ ( ps.getUntrackedParameter<unsigned int>( "verbosity", 0 ) ),
386  EC_difference_56_( -500 ), EC_difference_45_( -500 )
387 {
388  for ( const auto& pset : ps.getParameter< std::vector<edm::ParameterSet> >( "offsetsOOT" ) ) {
389  runParameters_.emplace_back( std::make_pair( pset.getParameter<edm::EventRange>( "validityRange" ), pset.getParameter<int>( "centralOOT" ) ) );
390  }
391 }
392 
393 //----------------------------------------------------------------------------------------------------
394 
396 {}
397 
398 //----------------------------------------------------------------------------------------------------
399 
400 void
402 {
403  centralOOT_ = -999;
404  for ( const auto& oot : runParameters_ ) {
405  if ( edm::contains( oot.first, edm::EventID( iRun.run(), 0, 1 ) ) ) {
406  centralOOT_ = oot.second; break;
407  }
408  }
409 
410  // Get detector shifts from the geometry
412  iSetup.get<VeryForwardRealGeometryRecord>().get( geometry_ );
413  const CTPPSGeometry *geom = geometry_.product();
415  const DetGeomDesc* det = geom->getSensor( detid );
416  horizontalShiftOfDiamond_ = det->translation().x() - det->params().at( 0 );
417 
418  // Rough alignement of pixel detector for diamond thomography
420  if ( iRun.run()>300000 ) { //Pixel installed
421  det = geom->getSensor( pixid );
423  }
424 }
425 
426 
427 //----------------------------------------------------------------------------------------------------
428 
429 void
431 {
432  ibooker.cd();
433  ibooker.setCurrentFolder( "CTPPS" );
434 
435  globalPlot_= GlobalPlots( ibooker );
436 
437  for ( unsigned short arm = 0; arm < CTPPS_NUM_OF_ARMS; ++arm ) {
439  potPlots_[rpId] = PotPlots( ibooker, rpId );
440  for ( unsigned short pl = 0; pl < CTPPS_DIAMOND_NUM_OF_PLANES; ++pl ) {
442  planePlots_[plId] = PlanePlots( ibooker, plId);
443  for ( unsigned short ch = 0; ch < CTPPS_DIAMOND_NUM_OF_CHANNELS; ++ch ) {
445  channelPlots_[chId] = ChannelPlots( ibooker, chId );
446  }
447  }
448  }
449 }
450 
451 
452 //----------------------------------------------------------------------------------------------------
453 
454 std::shared_ptr<dds::Cache>
456 {
457  auto d = std::make_shared<dds::Cache>();
458  d->hitDistribution2dMap.reserve(potPlots_.size());
459  for ( auto& plot : potPlots_ )
460  d->hitDistribution2dMap[plot.first] = std::unique_ptr<TH2F>(static_cast<TH2F*>(plot.second.hitDistribution2d_lumisection->getTH2F()->Clone()));
461  return d;
462 }
463 
464 //----------------------------------------------------------------------------------------------------
465 
466 void
468 {
469  // get event data
471  event.getByToken( tokenStatus_, diamondVFATStatus );
472 
474  event.getByToken( tokenPixelTrack_, pixelTracks );
475 
477  event.getByToken( tokenDigi_, diamondDigis );
478 
480  event.getByToken( tokenFEDInfo_, fedInfo );
481 
483  event.getByToken( tokenDiamondHit_, diamondRecHits );
484 
486  event.getByToken( tokenDiamondTrack_, diamondLocalTracks );
487 
489  iSetup.get<VeryForwardRealGeometryRecord>().get( geometry_ );
490 
491  // check validity
492  bool valid = true;
493  valid &= diamondVFATStatus.isValid();
494  valid &= pixelTracks.isValid();
495  valid &= diamondDigis.isValid();
496  valid &= fedInfo.isValid();
497  valid &= diamondRecHits.isValid();
498  valid &= diamondLocalTracks.isValid();
499 
500  if ( !valid ) {
501  if ( verbosity_ ) {
502  edm::LogProblem("CTPPSDiamondDQMSource")
503  << "ERROR in CTPPSDiamondDQMSource::analyze > some of the required inputs are not valid. Skipping this event.\n"
504  << " diamondVFATStatus.isValid = " << diamondVFATStatus.isValid() << "\n"
505  << " pixelTracks.isValid = " << pixelTracks.isValid() << "\n"
506  << " diamondDigis.isValid = " << diamondDigis.isValid() << "\n"
507  << " fedInfo.isValid = " << fedInfo.isValid() << "\n"
508  << " diamondRecHits.isValid = " << diamondRecHits.isValid() << "\n"
509  << " diamondLocalTracks.isValid = " << diamondLocalTracks.isValid();
510  }
511 
512  return;
513  }
514 
515  //------------------------------
516  // RP Plots
517  //------------------------------
518 
519  //------------------------------
520  // Correlation Plots
521  //------------------------------
522 
523  // Using CTPPSDiamondDigi
524  for ( const auto& digis : *diamondDigis ) {
525  const CTPPSDiamondDetId detId( digis.detId() );
526  CTPPSDiamondDetId detId_pot( digis.detId() );
527 
528  for ( const auto& digi : digis ) {
529  detId_pot.setPlane( 0 );
530  detId_pot.setChannel( 0 );
531  if ( detId.channel() == CHANNEL_OF_VFAT_CLOCK ) continue;
532  if ( potPlots_.find( detId_pot ) == potPlots_.end() ) continue;
533  //Leading without trailing investigation
534  if ( digi.getLeadingEdge() != 0 || digi.getTrailingEdge() != 0 ) {
535  ++(potPlots_[detId_pot].HitCounter);
536  if ( digi.getLeadingEdge() != 0 ) {
537  potPlots_[detId_pot].leadingEdgeCumulative_all->Fill( HPTDC_BIN_WIDTH_NS * digi.getLeadingEdge() );
538  }
539  if ( digi.getLeadingEdge() != 0 && digi.getTrailingEdge() == 0 ) {
540  ++(potPlots_[detId_pot].LeadingOnlyCounter);
541  potPlots_[detId_pot].leadingEdgeCumulative_le->Fill( HPTDC_BIN_WIDTH_NS * digi.getLeadingEdge() );
542  }
543  if ( digi.getLeadingEdge() == 0 && digi.getTrailingEdge() != 0 ) {
544  ++(potPlots_[detId_pot].TrailingOnlyCounter);
545  potPlots_[detId_pot].trailingEdgeCumulative_te->Fill( HPTDC_BIN_WIDTH_NS * digi.getTrailingEdge() );
546  }
547  if ( digi.getLeadingEdge() != 0 && digi.getTrailingEdge() != 0 ) {
548  ++(potPlots_[detId_pot].CompleteCounter);
549  potPlots_[detId_pot].leadingTrailingCorrelationPot->Fill( HPTDC_BIN_WIDTH_NS * digi.getLeadingEdge(), HPTDC_BIN_WIDTH_NS * digi.getTrailingEdge() );
550  }
551  }
552 
553  // HPTDC Errors
554  const HPTDCErrorFlags hptdcErrors = digi.getHPTDCErrorFlags();
555  if ( detId.channel() == 6 || detId.channel() == 7 ) // ch6 for HPTDC 0 and ch7 for HPTDC 1
556  {
557  int verticalIndex = 2*detId.plane() + (detId.channel() - 6);
558  for ( unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex )
559  if ( hptdcErrors.getErrorId( hptdcErrorIndex-1 ) ) potPlots_[detId_pot].HPTDCErrorFlags_2D->Fill( hptdcErrorIndex, verticalIndex );
560  }
561  if ( digi.getMultipleHit() ) ++(potPlots_[detId_pot].MHCounter);
562  }
563  }
564 
565  // EC Errors
566  for ( const auto& vfat_status : *diamondVFATStatus ) {
567  const CTPPSDiamondDetId detId( vfat_status.detId() );
568  CTPPSDiamondDetId detId_pot( vfat_status.detId() );
569  detId_pot.setPlane( 0 );
570  detId_pot.setChannel( 0 );
571  for ( const auto& status : vfat_status ) {
572  if ( !status.isOK() ) continue;
573  if ( potPlots_.find(detId_pot) == potPlots_.end() ) continue;
574  if ( channelPlots_.find(detId) == channelPlots_.end() ) continue;
575 
576  // Check Event Number
577  for ( const auto& optorx : *fedInfo ) {
578  if ( detId.arm() == 1 && optorx.getFEDId() == CTPPS_FED_ID_56 ) {
579  potPlots_[detId_pot].ECCheck->Fill((int)((optorx.getLV1()& 0xFF)-((unsigned int) status.getEC() & 0xFF)) & 0xFF);
580  if ( ( static_cast<int>( ( optorx.getLV1() & 0xFF )-status.getEC() ) != EC_difference_56_ ) && ( static_cast<uint8_t>( ( optorx.getLV1() & 0xFF )-status.getEC() ) < 128 ) )
581  EC_difference_56_ = static_cast<int>( optorx.getLV1() & 0xFF )-( static_cast<unsigned int>( status.getEC() ) & 0xFF );
582  if ( EC_difference_56_ != 1 && EC_difference_56_ != -500 && std::abs(EC_difference_56_) < 127 )
583  {
584  if ( detId.channel() == 6 || detId.channel() == 7 ) potPlots_[detId_pot].HPTDCErrorFlags_2D->Fill( 16, 2*detId.plane() + (detId.channel() - 6) );
585  if (verbosity_)
586  edm::LogProblem("CTPPSDiamondDQMSource") << "FED " << CTPPS_FED_ID_56 << ": ECError at EV: 0x"<< std::hex << optorx.getLV1()
587  << "\t\tVFAT EC: 0x"<< static_cast<unsigned int>( status.getEC() )
588  << "\twith ID: " << std::dec << detId
589  << "\tdiff: " << EC_difference_56_;
590  }
591  }
592  else if ( detId.arm() == 0 && optorx.getFEDId()== CTPPS_FED_ID_45 ) {
593  potPlots_[detId_pot].ECCheck->Fill((int)((optorx.getLV1()& 0xFF)-status.getEC()) & 0xFF);
594  if ( ( static_cast<int>( ( optorx.getLV1() & 0xFF )-status.getEC() ) != EC_difference_45_ ) && ( static_cast<uint8_t>( ( optorx.getLV1() & 0xFF )-status.getEC() ) < 128 ) )
595  EC_difference_45_ = static_cast<int>( optorx.getLV1() & 0xFF )-( static_cast<unsigned int>( status.getEC() ) & 0xFF );
596  if ( EC_difference_45_ != 1 && EC_difference_45_ != -500 && std::abs(EC_difference_45_) < 127 )
597  {
598  if ( detId.channel() == 6 || detId.channel() == 7 ) potPlots_[detId_pot].HPTDCErrorFlags_2D->Fill( 16, 2*detId.plane() + (detId.channel() - 6) );
599  if (verbosity_)
600  edm::LogProblem("CTPPSDiamondDQMSource") << "FED " << CTPPS_FED_ID_45 << ": ECError at EV: 0x"<< std::hex << optorx.getLV1()
601  << "\t\tVFAT EC: 0x"<< static_cast<unsigned int>( status.getEC() )
602  << "\twith ID: " << std::dec << detId
603  << "\tdiff: " << EC_difference_45_;
604  }
605  }
606  }
607  }
608  }
609 
610  // Using CTPPSDiamondRecHit
611  std::unordered_map<unsigned int, std::set<unsigned int> > planes;
612  std::unordered_map<unsigned int, std::set<unsigned int> > planes_inclusive;
613 
614 
615  auto lumiCache = luminosityBlockCache(event.getLuminosityBlock().index());
616  for ( const auto& rechits : *diamondRecHits ) {
617  CTPPSDiamondDetId detId_pot( rechits.detId() );
618  detId_pot.setPlane( 0 );
619  detId_pot.setChannel( 0 );
620  const CTPPSDiamondDetId detId( rechits.detId() );
621 
622  for ( const auto& rechit : rechits ) {
623  planes_inclusive[detId_pot].insert( detId.plane() );
624  if ( excludeMultipleHits_ && rechit.getMultipleHits() > 0 ) continue;
625  if ( rechit.getToT() != 0 && centralOOT_ != -999 && rechit.getOOTIndex() == centralOOT_ )
626  planes[detId_pot].insert( detId.plane() );
627 
628  if ( potPlots_.find( detId_pot ) == potPlots_.end() ) continue;
629 
630  float UFSDShift = 0.0;
631  if ( rechit.getYWidth() < 3 ) UFSDShift = 0.5; // Display trick for UFSD that have 2 pixels with same X
632 
633  if ( rechit.getToT() != 0 && centralOOT_ != -999 && rechit.getOOTIndex() == centralOOT_ ) {
634  TH2F *hitHistoTmp = potPlots_[detId_pot].hitDistribution2d->getTH2F();
635  TAxis *hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
636  int startBin = hitHistoTmpYAxis->FindBin( rechit.getX() - horizontalShiftOfDiamond_ - 0.5*rechit.getXWidth() );
637  int numOfBins = rechit.getXWidth()*INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
638  for ( int i=0; i<numOfBins; ++i) {
639  hitHistoTmp->Fill( detId.plane() + UFSDShift, hitHistoTmpYAxis->GetBinCenter(startBin+i) );
640  }
641 
642  hitHistoTmp = lumiCache->hitDistribution2dMap[detId_pot].get();
643  hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
644  startBin = hitHistoTmpYAxis->FindBin( rechit.getX() - horizontalShiftOfDiamond_ - 0.5*rechit.getXWidth() );
645  numOfBins = rechit.getXWidth()*INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
646  for ( int i=0; i<numOfBins; ++i) {
647  hitHistoTmp->Fill( detId.plane() + UFSDShift, hitHistoTmpYAxis->GetBinCenter(startBin+i) );
648  }
649 
650  }
651 
652  if ( rechit.getToT() != 0 ) {
653  // Both
654  potPlots_[detId_pot].leadingEdgeCumulative_both->Fill( rechit.getT() + 25*rechit.getOOTIndex() );
655  potPlots_[detId_pot].timeOverThresholdCumulativePot->Fill( rechit.getToT() );
656 
657  TH2F *hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT->getTH2F();
658  TAxis *hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
659  int startBin = hitHistoOOTTmpYAxis->FindBin( rechit.getX() - horizontalShiftOfDiamond_ - 0.5*rechit.getXWidth() );
660  int numOfBins = rechit.getXWidth()*INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
661  for ( int i=0; i<numOfBins; ++i) {
662  hitHistoOOTTmp->Fill( detId.plane() + 0.25 * rechit.getOOTIndex(), hitHistoOOTTmpYAxis->GetBinCenter(startBin+i) );
663  }
664  }
665  else {
666  if ( rechit.getOOTIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING ) {
667  // Only leading
668  TH2F *hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT_le->getTH2F();
669  TAxis *hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
670  int startBin = hitHistoOOTTmpYAxis->FindBin( rechit.getX() - horizontalShiftOfDiamond_ - 0.5*rechit.getXWidth() );
671  int numOfBins = rechit.getXWidth()*INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
672  for ( int i=0; i<numOfBins; ++i) {
673  hitHistoOOTTmp->Fill( detId.plane() + 0.25 * rechit.getOOTIndex(), hitHistoOOTTmpYAxis->GetBinCenter(startBin+i) );
674  }
675  }
676  }
677  if ( rechit.getOOTIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.getOOTIndex() < (int) potPlots_[detId_pot].activity_per_bx.size() )
678  potPlots_[detId_pot].activity_per_bx.at( rechit.getOOTIndex() )->Fill( event.bunchCrossing() );
679  }
680  }
681 
682  for ( const auto& plt : potPlots_ ) {
683  plt.second.activePlanes->Fill( planes[plt.first].size() );
684  plt.second.activePlanesInclusive->Fill( planes_inclusive[plt.first].size() );
685  }
686 
687  // Using CTPPSDiamondLocalTrack
688  for ( const auto& tracks : *diamondLocalTracks ) {
689  CTPPSDiamondDetId detId_pot( tracks.detId() );
690  detId_pot.setPlane( 0 );
691  detId_pot.setChannel( 0 );
692  const CTPPSDiamondDetId detId( tracks.detId() );
693 
694  for ( const auto& track : tracks ) {
695  if ( ! track.isValid() ) continue;
696  if ( track.getOOTIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING ) continue;
697  if ( excludeMultipleHits_ && track.getMultipleHits() > 0 ) continue;
698  if ( potPlots_.find( detId_pot ) == potPlots_.end() ) continue;
699 
700  TH2F *trackHistoOOTTmp = potPlots_[detId_pot].trackDistributionOOT->getTH2F();
701  TAxis *trackHistoOOTTmpYAxis = trackHistoOOTTmp->GetYaxis();
702  int startBin = trackHistoOOTTmpYAxis->FindBin( track.getX0() - horizontalShiftOfDiamond_ - track.getX0Sigma() );
703  int numOfBins = 2*track.getX0Sigma()*INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
704  for ( int i=0; i<numOfBins; ++i) {
705  trackHistoOOTTmp->Fill( track.getOOTIndex(), trackHistoOOTTmpYAxis->GetBinCenter(startBin+i) );
706  }
707 
708  if ( centralOOT_ != -999 && track.getOOTIndex() == centralOOT_ ) {
709  TH1F *trackHistoInTimeTmp = potPlots_[detId_pot].trackDistribution->getTH1F();
710  int startBin = trackHistoInTimeTmp->FindBin( track.getX0() - horizontalShiftOfDiamond_ - track.getX0Sigma() );
711  int numOfBins = 2*track.getX0Sigma()*INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
712  for ( int i=0; i<numOfBins; ++i) {
713  trackHistoInTimeTmp->Fill( trackHistoInTimeTmp->GetBinCenter(startBin+i) );
714  }
715  }
716  }
717  }
718 
719  // Channel efficiency using CTPPSDiamondLocalTrack
720  for ( const auto& tracks : *diamondLocalTracks ) {
721  CTPPSDiamondDetId detId_pot( tracks.detId() );
722  detId_pot.setPlane( 0 );
723  detId_pot.setChannel( 0 );
724  for ( const auto& track : tracks ) {
725  // Find hits and planes in the track
726  int numOfHits = 0;
727  std::set<int> planesInTrackSet;
728  for ( const auto& vec : *diamondRecHits ) {
729  const CTPPSDiamondDetId detid( vec.detId() );
730  if ( detid.arm() != detId_pot.arm() ) continue;
731 
732  for ( const auto& hit : vec ) {
733  // first check if the hit contributes to the track
734  if ( track.containsHit(hit) ) {
735  ++numOfHits;
736  planesInTrackSet.insert(detid.plane());
737  }
738  }
739  }
740 
741  if ( numOfHits > 0 && numOfHits <= 10 && planesInTrackSet.size() > 2 ) {
742  for ( int plane=0; plane<4; ++plane ) {
743  for ( int channel=0; channel<12; ++channel ) {
744  int map_index = plane*100 + channel;
745  if ( potPlots_[detId_pot].effDoublecountingChMap.find( map_index ) == potPlots_[detId_pot].effDoublecountingChMap.end() ) {
746  potPlots_[detId_pot].effTriplecountingChMap[map_index] = 0;
747  potPlots_[detId_pot].effDoublecountingChMap[map_index] = 0;
748  }
749  CTPPSDiamondDetId detId( detId_pot.arm(), CTPPS_DIAMOND_STATION_ID, CTPPS_DIAMOND_RP_ID, plane, channel);
750  if ( channelAlignedWithTrack( geometry_.product(), detId, track, 0.2) ) {
751  // Channel should fire
752  ++(potPlots_[detId_pot].effDoublecountingChMap[map_index]);
753  for ( const auto& rechits : *diamondRecHits ) {
754  CTPPSDiamondDetId detId_hit( rechits.detId() );
755  if ( detId_hit == detId ) {
756  for ( const auto& rechit : rechits ) {
757  if ( track.containsHit( rechit, 1 ) ) {
758  // Channel fired
759  ++(potPlots_[detId_pot].effTriplecountingChMap[map_index]);
760  }
761  }
762  }
763  }
764  }
765  }
766  }
767  }
768  }
769  }
770 
771  // Tomography of diamonds using pixel
772  for ( const auto& rechits : *diamondRecHits ) {
773  CTPPSDiamondDetId detId_pot( rechits.detId() );
774  detId_pot.setPlane( 0 );
775  detId_pot.setChannel( 0 );
776  const CTPPSDiamondDetId detId( rechits.detId() );
777  for ( const auto& rechit : rechits ) {
778  if ( excludeMultipleHits_ && rechit.getMultipleHits() > 0 ) continue;
779  if ( rechit.getToT() == 0 ) continue;
780  if ( !pixelTracks.isValid() ) continue;
781  if ( potPlots_.find( detId_pot ) == potPlots_.end() ) continue;
782 
783  for ( const auto& ds : *pixelTracks ) {
784  if ( ds.size() > 1 ) continue;
785  const CTPPSPixelDetId pixId( ds.detId() );
786  if ( pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_FAR_RP_ID ) continue;
787  for ( const auto& lt : ds ) {
788  if ( lt.isValid() && pixId.arm() == detId_pot.arm() ) {
789  if ( rechit.getOOTIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.getOOTIndex() < (int) potPlots_[detId_pot].pixelTomographyAll.size() && rechit.getOOTIndex() >= 0 && lt.getX0() - horizontalShiftBwDiamondPixels_ < 24 )
790  potPlots_[detId_pot].pixelTomographyAll.at( rechit.getOOTIndex() )->Fill( lt.getX0() - horizontalShiftBwDiamondPixels_ + 25*detId.plane(), lt.getY0() );
791  }
792  }
793  }
794  }
795  }
796 
797  //------------------------------
798  // Clock Plots
799  //------------------------------
800  // Commented out to save space in the DQM files, but code should be kept
801  // for ( const auto& digis : *diamondDigis ) {
802  // const CTPPSDiamondDetId detId( digis.detId() );
803  // CTPPSDiamondDetId detId_pot( digis.detId() );
804  // if ( detId.channel() == CHANNEL_OF_VFAT_CLOCK ) {
805  // detId_pot.setPlane( 0 );
806  // detId_pot.setChannel( 0 );
807  // for ( const auto& digi : digis ) {
808  // if ( digi.getLeadingEdge() != 0 ) {
809  // if ( detId.plane() == 1 ) {
810  // potPlots_[detId_pot].clock_Digi1_le->Fill( HPTDC_BIN_WIDTH_NS * digi.getLeadingEdge() );
811  // potPlots_[detId_pot].clock_Digi1_te->Fill( HPTDC_BIN_WIDTH_NS * digi.getTrailingEdge() );
812  // }
813  // if ( detId.plane() == 3 ) {
814  // potPlots_[detId_pot].clock_Digi3_le->Fill( HPTDC_BIN_WIDTH_NS * digi.getLeadingEdge() );
815  // potPlots_[detId_pot].clock_Digi3_te->Fill( HPTDC_BIN_WIDTH_NS * digi.getTrailingEdge() );
816  // }
817  // }
818  // }
819  // }
820  // }
821 
822  //------------------------------
823  // Plane Plots
824  //------------------------------
825 
826  // Using CTPPSDiamondDigi
827  std::unordered_map<unsigned int, unsigned int> channelsPerPlane;
828  for ( const auto& digis : *diamondDigis ) {
829  const CTPPSDiamondDetId detId( digis.detId() );
830  CTPPSDiamondDetId detId_plane( digis.detId() );
831  for ( const auto& digi : digis ) {
832  detId_plane.setChannel( 0 );
833  if ( detId.channel() == CHANNEL_OF_VFAT_CLOCK ) continue;
834  if ( planePlots_.find( detId_plane ) == planePlots_.end() ) continue;
835 
836  if ( digi.getLeadingEdge() != 0 ) {
837  planePlots_[detId_plane].digiProfileCumulativePerPlane->Fill( detId.channel() );
838  if ( channelsPerPlane.find(detId_plane) != channelsPerPlane.end() ) channelsPerPlane[detId_plane]++;
839  else channelsPerPlane[detId_plane] = 0;
840  }
841  }
842  }
843 
844  for ( const auto& plt : channelsPerPlane ) {
845  planePlots_[plt.first].hit_multiplicity->Fill( plt.second );
846  }
847 
848  // Using CTPPSDiamondRecHit
849  for ( const auto& rechits : *diamondRecHits ) {
850  CTPPSDiamondDetId detId_plane( rechits.detId() );
851  detId_plane.setChannel( 0 );
852  for ( const auto& rechit : rechits ) {
853  if ( excludeMultipleHits_ && rechit.getMultipleHits() > 0 ) continue;
854  if ( rechit.getToT() == 0 ) continue;
855  if ( planePlots_.find( detId_plane ) != planePlots_.end() ) {
856  if ( centralOOT_ != -999 && rechit.getOOTIndex() == centralOOT_ ) {
857  TH1F *hitHistoTmp = planePlots_[detId_plane].hitProfile->getTH1F();
858  int startBin = hitHistoTmp->FindBin( rechit.getX() - horizontalShiftOfDiamond_ - 0.5*rechit.getXWidth() );
859  int numOfBins = rechit.getXWidth()*INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
860  for ( int i=0; i<numOfBins; ++i) {
861  hitHistoTmp->Fill( hitHistoTmp->GetBinCenter(startBin+i) );
862  }
863  }
864  }
865  }
866  }
867 
868 
869  //Tomography of diamonds using pixel and Efficiency WRT Pixels
870  for ( const auto& ds : *pixelTracks ) {
871  const CTPPSPixelDetId pixId( ds.detId() );
872  if ( pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_FAR_RP_ID ) continue;
873  if ( ds.size() > 1 ) continue;
874  for ( const auto& lt : ds ) {
875  if ( lt.isValid() ) {
876  // For efficieny
878  potPlots_[detId_pot].pixelTracksMap.Fill( lt.getX0() - horizontalShiftBwDiamondPixels_, lt.getY0() );
879 
880  std::set< CTPPSDiamondDetId > planesWitHits_set;
881  for ( const auto& rechits : *diamondRecHits ) {
882  CTPPSDiamondDetId detId_plane( rechits.detId() );
883  detId_plane.setChannel( 0 );
884  for ( const auto& rechit : rechits ) {
885  if ( excludeMultipleHits_ && rechit.getMultipleHits() > 0 ) continue;
886  if ( rechit.getOOTIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.getToT() == 0 ) continue;
887  if ( planePlots_.find(detId_plane) == planePlots_.end() ) continue;
888  if ( pixId.arm() == detId_plane.arm() && lt.getX0() - horizontalShiftBwDiamondPixels_ < 24 ) {
889  planePlots_[detId_plane].pixelTomography_far->Fill( lt.getX0() - horizontalShiftBwDiamondPixels_ + 25*rechit.getOOTIndex(), lt.getY0() );
890  if ( centralOOT_ != -999 && rechit.getOOTIndex() == centralOOT_ ) planesWitHits_set.insert( detId_plane );
891  }
892 
893  }
894  }
895 
896  for (auto& planeId : planesWitHits_set)
897  planePlots_[planeId].pixelTracksMapWithDiamonds.Fill( lt.getX0() - horizontalShiftBwDiamondPixels_, lt.getY0() );
898 
899  }
900 
901  }
902  }
903 
904 
905  //------------------------------
906  // Channel Plots
907  //------------------------------
908 
909  // digi profile cumulative
910  for ( const auto& digis : *diamondDigis ) {
911  const CTPPSDiamondDetId detId( digis.detId() );
912  for ( const auto& digi : digis ) {
913  if ( detId.channel() == CHANNEL_OF_VFAT_CLOCK ) continue;
914  if ( channelPlots_.find( detId ) != channelPlots_.end() ) {
915  // HPTDC Errors
916  const HPTDCErrorFlags hptdcErrors = digi.getHPTDCErrorFlags();
917  for ( unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex )
918  if ( hptdcErrors.getErrorId( hptdcErrorIndex-1 ) ) channelPlots_[detId].HPTDCErrorFlags->Fill( hptdcErrorIndex );
919  if ( digi.getMultipleHit() ) ++(channelPlots_[detId].MHCounter);
920 
921  // Check dropped trailing edges
922  if ( digi.getLeadingEdge() != 0 || digi.getTrailingEdge() != 0 ) {
923  ++(channelPlots_[detId].HitCounter);
924  if ( digi.getLeadingEdge() != 0 && digi.getTrailingEdge() == 0 ) {
925  ++(channelPlots_[detId].LeadingOnlyCounter);
926  channelPlots_[detId].leadingEdgeCumulative_le->Fill( HPTDC_BIN_WIDTH_NS * digi.getLeadingEdge() );
927  }
928  if ( digi.getLeadingEdge() == 0 && digi.getTrailingEdge() != 0 ) {
929  ++(channelPlots_[detId].TrailingOnlyCounter);
930  channelPlots_[detId].trailingEdgeCumulative_te->Fill( HPTDC_BIN_WIDTH_NS * digi.getTrailingEdge() );
931  }
932  if ( digi.getLeadingEdge() != 0 && digi.getTrailingEdge() != 0 ) {
933  ++(channelPlots_[detId].CompleteCounter);
934  channelPlots_[detId].LeadingTrailingCorrelationPerChannel->Fill( HPTDC_BIN_WIDTH_NS * digi.getLeadingEdge(), HPTDC_BIN_WIDTH_NS * digi.getTrailingEdge() );
935  }
936  }
937  }
938  }
939  }
940 
941  // Using CTPPSDiamondRecHit
942 
943  for ( const auto& rechits : *diamondRecHits ) {
944  CTPPSDiamondDetId detId( rechits.detId() );
945  for ( const auto& rechit : rechits ) {
946  if ( excludeMultipleHits_ && rechit.getMultipleHits() > 0 ) continue;
947  if ( channelPlots_.find( detId ) != channelPlots_.end() ) {
948  if ( rechit.getOOTIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.getToT() != 0 ) {
949  channelPlots_[detId].leadingEdgeCumulative_both->Fill( rechit.getT() + 25*rechit.getOOTIndex() );
950  channelPlots_[detId].TimeOverThresholdCumulativePerChannel->Fill( rechit.getToT() );
951  }
952  ++(lumiCache->hitsCounterMap[detId]);
953  }
954 
955  if ( rechit.getOOTIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.getOOTIndex() < (int) channelPlots_[detId].activity_per_bx.size() )
956  channelPlots_[detId].activity_per_bx.at( rechit.getOOTIndex() )->Fill( event.bunchCrossing() );
957  }
958 
959  }
960 
961  // Tomography of diamonds using pixel
962  for ( const auto& rechits : *diamondRecHits ) {
963  const CTPPSDiamondDetId detId( rechits.detId() );
964  for ( const auto& rechit : rechits ) {
965  if ( excludeMultipleHits_ && rechit.getMultipleHits() > 0 ) continue;
966  if ( rechit.getOOTIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.getToT() == 0 ) continue;
967  if ( !pixelTracks.isValid() ) continue;
968  if (channelPlots_.find(detId) == channelPlots_.end()) continue;
969 
970  for ( const auto& ds : *pixelTracks ) {
971  const CTPPSPixelDetId pixId( ds.detId() );
972  if ( pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_FAR_RP_ID ) continue;
973  if ( ds.size() > 1 ) continue;
974  for ( const auto& lt : ds ) {
975  if ( lt.isValid() && pixId.arm() == detId.arm() && lt.getX0() - horizontalShiftBwDiamondPixels_ < 24 )
976  channelPlots_[detId].pixelTomography_far->Fill( lt.getX0() - horizontalShiftBwDiamondPixels_ + 25*rechit.getOOTIndex(), lt.getY0() );
977  }
978  }
979  }
980  }
981 
982 }
983 
984 //----------------------------------------------------------------------------------------------------
985 
986 void
988 {
989 
990  auto lumiCache = luminosityBlockCache(iLumi.index());
991  for ( auto& plot : potPlots_ ) {
992  *(plot.second.hitDistribution2d_lumisection->getTH2F())=*(lumiCache->hitDistribution2dMap[plot.first]);
993  }
994  for ( auto& plot : channelPlots_ ) {
995  auto hitsCounterPerLumisection = lumiCache->hitsCounterMap[plot.first];
996  if ( hitsCounterPerLumisection != 0 ) {
997  plot.second.hit_rate->Fill( (double) hitsCounterPerLumisection / SEC_PER_LUMI_SECTION );
998  }
999 
1000  double HundredOverHitCounter = .0;
1001  if ( plot.second.HitCounter != 0 )
1002  HundredOverHitCounter = 100. / plot.second.HitCounter;
1003  plot.second.HPTDCErrorFlags->setBinContent( 16, HundredOverHitCounter * plot.second.MHCounter );
1004  plot.second.leadingWithoutTrailing->setBinContent(1, HundredOverHitCounter * plot.second.LeadingOnlyCounter );
1005  plot.second.leadingWithoutTrailing->setBinContent(2, HundredOverHitCounter * plot.second.TrailingOnlyCounter );
1006  plot.second.leadingWithoutTrailing->setBinContent(3, HundredOverHitCounter * plot.second.CompleteCounter );
1007  }
1008 
1009  for ( auto& plot : potPlots_ ) {
1010  double HundredOverHitCounterPot = 0.;
1011  if ( plot.second.HitCounter !=0 )
1012  HundredOverHitCounterPot = 100. / plot.second.HitCounter;
1013  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(1, HundredOverHitCounterPot * plot.second.LeadingOnlyCounter );
1014  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(2, HundredOverHitCounterPot * plot.second.TrailingOnlyCounter );
1015  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(3, HundredOverHitCounterPot * plot.second.CompleteCounter );
1016 
1017  plot.second.MHComprensive->Reset();
1018  CTPPSDiamondDetId rpId(plot.first);
1019  for ( auto& chPlot : channelPlots_ ) {
1020  CTPPSDiamondDetId chId(chPlot.first);
1021  if ( chId.arm() == rpId.arm() && chId.rp() == rpId.rp() ) {
1022  plot.second.MHComprensive->Fill(chId.plane(), chId.channel(), chPlot.second.HPTDCErrorFlags->getBinContent( 16 ) );
1023  }
1024  }
1025 
1026  }
1027 
1028  // Efficiencies of single channels
1029  for ( auto& plot : potPlots_ ) {
1030  plot.second.EfficiencyOfChannelsInPot->Reset();
1031  for ( auto& element : plot.second.effTriplecountingChMap ) {
1032  if ( plot.second.effDoublecountingChMap[ element.first ] > 0) {
1033  int plane = element.first / 100;
1034  int channel = element.first % 100;
1035  double counted = element.second;
1036  double total = plot.second.effDoublecountingChMap[ element.first ];
1037  double efficiency = counted / total;
1038 // double error = std::sqrt( efficiency * ( 1 - efficiency ) / total );
1039 
1040  plot.second.EfficiencyOfChannelsInPot->Fill(plane, channel, 100*efficiency);
1041  }
1042  }
1043  }
1044 
1045  // Efficeincy wrt pixels //TODO
1046  for ( auto& plot : planePlots_ ) {
1047  TH2F *hitHistoTmp = plot.second.EfficiencyWRTPixelsInPlane->getTH2F();
1048 
1049  CTPPSDiamondDetId detId_pot( plot.first );
1050  detId_pot.setPlane( 0 );
1051 
1052  hitHistoTmp->Divide( &(plot.second.pixelTracksMapWithDiamonds), &(potPlots_[detId_pot].pixelTracksMap) );
1053  }
1054 }
1055 
1056 //----------------------------------------------------------------------------------------------------
1057 
1058 void
1060 {}
1061 
1062 //----------------------------------------------------------------------------------------------------
1063 
static const int CTPPS_FED_ID_56
void analyze(const edm::Event &, const edm::EventSetup &) override
OptoRx headers and footers.
Definition: TotemFEDInfo.h:17
plots related to one Diamond plane
T getParameter(std::string const &) const
plots related to one Diamond detector package
Translation translation() const
Definition: DetGeomDesc.h:66
static const int CHANNEL_OF_VFAT_CLOCK
bool contains(EventRange const &lh, EventID const &rh)
Definition: EventRange.cc:38
RunNumber_t run() const
Definition: RunBase.h:40
static const double DISPLAY_RESOLUTION_FOR_HITS_MM
LuminosityBlockIndex index() const
static const int CTPPS_DIAMOND_NUM_OF_PLANES
std::vector< MonitorElement * > activity_per_bx
TH1F * getTH1F() const
void setPlane(uint32_t channel)
Reconstructed hit in diamond detectors.
const double tolerance
void endRun(const edm::Run &, const edm::EventSetup &) override
void setChannel(uint32_t channel)
void channelName(std::string &name, NameFlag flag=nFull) const
void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override
edm::EDGetTokenT< edm::DetSetVector< CTPPSDiamondDigi > > tokenDigi_
CTPPSDiamondDQMSource(const edm::ParameterSet &)
bool getErrorId(unsigned short id) const
static const int CTPPS_NUM_OF_ARMS
plots related to the whole system
int bunchCrossing() const
Definition: EventBase.h:64
static const int CTPPS_DIAMOND_NUM_OF_CHANNELS
example_stream void analyze(const edm::Event &, const edm::EventSetup &) override
Event setup record containing the real (actual) geometry information.
MonitorElement * leadingWithoutTrailingCumulativePot
static const int CTPPS_PIXEL_STATION_ID
void globalEndLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) override
static const int CTPPS_DIAMOND_STATION_ID
const DetGeomDesc * getSensor(unsigned int id) const
returns geometry of a detector performs necessary checks, returns NULL if fails
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:268
void bookHistograms(DQMStore::IBooker &, const edm::Run &, const edm::EventSetup &) override
std::vector< std::pair< edm::EventRange, int > > runParameters_
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
static const int CTPPS_NEAR_RP_ID
std::unordered_map< unsigned int, ChannelPlots > channelPlots_
Geometrical description of a sensor.
Definition: DetGeomDesc.h:35
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:106
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void rpName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:128
std::unordered_map< unsigned int, std::unique_ptr< TH2F > > hitDistribution2dMap
edm::EDGetTokenT< edm::DetSetVector< CTPPSPixelLocalTrack > > tokenPixelTrack_
plots related to one Diamond channel
uint32_t plane() const
LuminosityBlock const & getLuminosityBlock() const
Definition: Event.h:97
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:50
uint32_t arm() const
Definition: CTPPSDetId.h:51
bool isValid() const
Definition: HandleBase.h:74
TH2F * getTH2F() const
edm::EDGetTokenT< edm::DetSetVector< CTPPSDiamondLocalTrack > > tokenDiamondTrack_
The manager class for TOTEM RP geometry.
Definition: CTPPSGeometry.h:33
static const double HPTDC_BIN_WIDTH_NS
uint32_t channel() const
static const double INV_DISPLAY_RESOLUTION_FOR_HITS_MM
MonitorElement * book2D(Args &&...args)
Definition: DQMStore.h:109
example_stream void bookHistograms(DQMStore::IBooker &,@example_stream edm::Run const &,@example_stream edm::EventSetup const &) override
void planeName(std::string &name, NameFlag flag=nFull) const
std::shared_ptr< dds::Cache > globalBeginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) const override
bool channelAlignedWithTrack(const CTPPSGeometry *geom, const CTPPSDiamondDetId &detid, const CTPPSDiamondLocalTrack &localTrack, const float tolerance=1)
std::unordered_map< unsigned int, PotPlots > potPlots_
static constexpr int TIMESLICE_WITHOUT_LEADING
edm::EDGetTokenT< edm::DetSetVector< CTPPSDiamondRecHit > > tokenDiamondHit_
HLT enums.
std::vector< MonitorElement * > pixelTomographyAll
static const int CTPPS_FAR_RP_ID
T get() const
Definition: EventSetup.h:71
static const double SEC_PER_LUMI_SECTION
std::vector< double > params() const
Definition: DetGeomDesc.h:68
Detector ID class for CTPPS Timing Diamond detectors. Bits [19:31] : Assigend in CTPPSDetId Calss Bit...
std::unordered_map< unsigned int, PlanePlots > planePlots_
std::vector< MonitorElement * > activity_per_bx
static const int CTPPS_DIAMOND_RP_ID
static std::string getHPTDCErrorName(const unsigned short id)
edm::EDGetTokenT< std::vector< TotemFEDInfo > > tokenFEDInfo_
static const int CTPPS_FED_ID_45
T const * product() const
Definition: ESHandle.h:86
edm::EDGetTokenT< edm::DetSetVector< TotemVFATStatus > > tokenStatus_
std::unordered_map< unsigned int, unsigned long > hitsCounterMap
Definition: event.py:1
Definition: Run.h:45
uint32_t rp() const
Definition: CTPPSDetId.h:65