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