Belle II Software  release-08-02-06
CDCDQMModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 // Own include
10 #include <cdc/modules/cdcDQM/CDCDQMModule.h>
11 
12 // Dataobject classes
13 #include <framework/database/DBObjPtr.h>
14 
15 #include <TF1.h>
16 #include <TMath.h>
17 #include <TDirectory.h>
18 
19 #include <fstream>
20 #include <math.h>
21 #include <set>
22 
23 #include <cdc/dataobjects/WireID.h>
24 #include <cdc/geometry/CDCGeometryPar.h>
25 
26 using namespace std;
27 using namespace Belle2;
28 using namespace CDC;
29 
30 //-----------------------------------------------------------------
31 // Register module
32 //-----------------------------------------------------------------
33 
34 REG_MODULE(CDCDQM);
35 
36 CDCDQMModule::CDCDQMModule() : HistoModule()
37 {
38  // set module description (e.g. insert text)
39  setDescription("Make summary of data quality.");
40  addParam("MinHits", m_minHits, "Include only events with more than MinHits hits in CDC", 0);
41  addParam("AdjustWireShift", m_adjustWireShift,
42  "If true, gets the corrected phi view of the wires in stereo layers", m_adjustWireShift);
44 }
45 
47 {
48 }
49 
51 {
52  TDirectory* oldDir = gDirectory;
53  oldDir->mkdir("CDC");
54  oldDir->cd("CDC");
55  m_hNEvents = new TH1F("hNEvents", "hNEvents", 10, 0, 10);
56  m_hNEvents->GetXaxis()->SetBinLabel(1, "number of events");
57  m_hBit = new TH2F("hBit", "m_hBit", 7, 0, 7.0, 48, 0, 48.0);
58  m_hBit->SetTitle("CDC:Removed Data Bit;CDCRawIndex;Channell Index");
59  m_hOcc = new TH1F("hOcc", "hOccupancy", 150, 0, 1.5);
60  m_hADC = new TH2F("hADC", "hADC", 300, 0, 300, 200, 0, 1000);
61  m_hADC->SetTitle("ADC vs CDC-Boards;Board index;ADC");
62  m_hTDC = new TH2F("hTDC", "hTDC", 300, 0, 300, 1000, 4200, 5200);
63  m_hTDC->SetTitle("TDC vs CDC-Boards;Board index;TDC");
64  m_hHit = new TH2F("hHit", "hHit", 56, 0, 56, 400, 0, 400);
65  m_hHit->SetTitle("CDC-hits;layer index;nhits");
66  m_hPhi = new TH1F("hPhi", "", 360, -180.0, 180.0);
67  m_hPhi->SetTitle("CDC-track-#phi;cdctrack #phi (IP tracks + all events);entries");
68  m_hPhiIndex = new TH2F("hPhiIndex", "", 360, -180.0, 180.0, 8, 0, 8.0);
69  m_hPhiIndex->SetTitle("CDC-track-#phi;cdctrack #phi vs skims;selection-index");
70  m_hPhiEff = new TH2F("hPhiEff", "", 360, -180.0, 180.0, 100, 0, 100.0);
71  m_hPhiEff->SetTitle("CDC-track-#phi;cdctrack #phi vs cdchits;ncdchits");
72  m_hPhiHit = new TH2F("h2HitPhi", "h2HitPhi", 90, -180.0, 180.0, 56, 0, 56);
73  m_hPhiHit->SetTitle("CDC-hits-map (#phi vs layer);Track-#phi;Layer index");
74  m_hPhiNCDC = new TH2F("hPhiNCDC", "hPhiNCDC", 45, -180.0, 180.0, 61, -0.5, 60.5);
75  m_hPhiNCDC->SetTitle("nCDCHits vs #phi;Track-#phi;nCDCHits;Track / bin");
76  m_hTrackingWireEff = new TH2F("hTrackingWireEff", "title", 400, 0.5, 400 + 0.5, 56 * 2, -0.5, 56 * 2 - 0.5);
77  m_hTrackingWireEff->SetTitle("Attached vs Expected wires for all layers (backplate view);wire;layer;Track / bin");
78  oldDir->cd();
79 }
80 
82 {
83  REG_HISTOGRAM
84  m_cdcHits.isOptional();
85  m_cdcRawHits.isOptional();
86  m_trgSummary.isOptional();
87 
88  if (!m_Tracks.isOptional()) {
89  B2WARNING("Missing Tracks array");
90  return;
91  }
92 }
93 
95 {
96  if (!m_RecoTracks.isOptional()) {
97  B2DEBUG(22, "Missing recoTracks array in beginRun() ");
98  return;
99  }
100 
101  m_hNEvents->Reset();
102  m_hBit->Reset();
103  m_hOcc->Reset();
104  m_hADC->Reset();
105  m_hTDC->Reset();
106  m_hHit->Reset();
107  m_hPhi->Reset();
108  m_hPhiIndex->Reset();
109  m_hPhiEff->Reset();
110  m_hPhiHit->Reset();
111  m_hPhiNCDC->Reset();
112  m_hTrackingWireEff->Reset();
113 }
114 
116 {
117  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
118  const int nWires = 14336;
119  setReturnValue(1);
120  if (!m_trgSummary.isValid() || (m_trgSummary->getTimType() == Belle2::TRGSummary::TTYP_RAND)) {
121  setReturnValue(0);
122  return;
123  }
124 
125  if (!m_TrgResult.isValid()) {
126  B2WARNING("SoftwareTriggerResult object not available but require to select bhabha/mumu/hadron events skim");
127  return;
128  }
129 
130  const std::map<std::string, int>& fresults = m_TrgResult->getResults();
131  if ((fresults.find("software_trigger_cut&skim&accept_bhabha") == fresults.end()) ||
132  (fresults.find("software_trigger_cut&skim&accept_mumu_tight_or_highm") == fresults.end()) ||
133  (fresults.find("software_trigger_cut&skim&accept_hadron") == fresults.end())) {
134  B2WARNING("CDCDQMModule: Can't find required bhabha or mumu or hadron trigger identifier");
135  return;
136  }
137 
138  const bool IsBhabha = (m_TrgResult->getResult("software_trigger_cut&skim&accept_bhabha") ==
140  const bool IsHadron = (m_TrgResult->getResult("software_trigger_cut&skim&accept_hadron") ==
142  const bool IsMumu = (m_TrgResult->getResult("software_trigger_cut&skim&accept_mumu_tight_or_highm") ==
144 
145  if (m_cdcHits.getEntries() < m_minHits) {
146  setReturnValue(0);
147  return;
148  }
149 
150  m_nEvents += 1;
151  m_hOcc->Fill(static_cast<float>(m_cdcHits.getEntries()) / nWires);
152 
153  for (const auto& hit : m_cdcHits) {
154  int lay = hit.getICLayer();
155  int wire = hit.getIWire();
156  m_hHit->Fill(lay, wire);
157  }
158 
159  // to record removed databits
160  const int nEntries = m_rawCDCs.getEntries();
161  B2DEBUG(99, "nEntries of RawCDCs : " << nEntries);
162  for (int i = 0; i < nEntries; ++i) {
163  const int nEntriesRawCDC = m_rawCDCs[i]->GetNumEntries();
164  B2DEBUG(99, LogVar("nEntries of rawCDC[i]", nEntriesRawCDC));
165  for (int j = 0; j < nEntriesRawCDC; ++j) {
166  int MaxNumOfCh = m_rawCDCs[i]->GetMaxNumOfCh(j);
167  if (MaxNumOfCh != 4 && MaxNumOfCh != 48) {
168  B2ERROR("CDCDQM: Invalid value of GetMaxNumOfCh");
169  } else if (MaxNumOfCh == 48) {
170  for (int k = 0; k < MaxNumOfCh; ++k) {
171  if (m_rawCDCs[i]->CheckOnlineRemovedDataBit(j, k) == true)m_hBit->SetBinContent(i + 1, k + 1, -0.5);
172  else m_hBit->SetBinContent(i + 1, k + 1, 0.5);
173  }
174  }
175  }
176  }
177 
178  // ADC vs layer 2D histogram with only good track related hits
179  double iselect = -1.0;
180 
181  for (const auto& b2track : m_Tracks) {
182 
183  const Belle2::TrackFitResult* fitresult = b2track.getTrackFitResultWithClosestMass(Const::pion);
184  if (!fitresult) {
185  B2WARNING("No track fit result found.");
186  continue;
187  }
188 
189  Belle2::RecoTrack* track = b2track.getRelatedTo<Belle2::RecoTrack>(m_recoTrackArrayName);
190  if (!track) {
191  B2WARNING("Can not access RecoTrack of this Belle2::Track");
192  continue;
193  }
194 
195  const genfit::FitStatus* fs = track->getTrackFitStatus();
196  if (!fs) {
197  B2WARNING("Can not access FitStatus of this Track");
198  continue;
199  }
200 
201  // use tracks from IP for layer effi calculation
202  if (std::fabs(fitresult->getD0()) < 1.0 && std::fabs(fitresult->getZ0()) < 1.0) {
203  std::set<int> hitInSLayer; // list of contributing layers for this track
204  for (const RecoHitInformation::UsedCDCHit* hit : track->getCDCHitList()) {
205  const genfit::TrackPoint* tp = track->getCreatedTrackPoint(track->getRecoHitInformation(hit));
206  if (!tp) continue;
207  hitInSLayer.insert(hit->getICLayer());
208  }
209  if (hitInSLayer.empty()) continue;
210  auto helix = fitresult->getHelix();
211  int nSLayers = cdcgeo.getNumberOfSenseLayers();
212  for (int lay = 0; lay < nSLayers; lay++) {
213  double layerR = cdcgeo.senseWireR(lay);
214  // extrapolate to layer
215  double arcLength = helix.getArcLength2DAtCylindricalR(layerR);
216  if (std::isnan(arcLength)) continue;
217  const auto& result = helix.getPositionAtArcLength2D(arcLength);
218  if (result.Z() > cdcgeo.senseWireFZ(lay) || result.Z() < cdcgeo.senseWireBZ(lay)) continue;
219  // get phi of extrapolation and fill
220  double phi = getShiftedPhi(result, lay);
221  int fillXbin = findPhiBin(phi, lay);
222  m_hTrackingWireEff->Fill(fillXbin, lay);
223  if (hitInSLayer.count(lay)) // if hit is attached in this layer
224  m_hTrackingWireEff->Fill(fillXbin, lay + nSLayers);
225  }
226  }
227 
228  // require high NDF track
229  int ndf = fs->getNdf();
230  if (ndf < 20) continue;
231 
232  double phiDegree = fitresult->getPhi() / Unit::deg;
233  m_hPhiNCDC->Fill(phiDegree, TMath::Min(int(track->getNumberOfCDCHits()), 60));
234 
235  if (fabs(fitresult->getD0()) > 1.0 || fabs(fitresult->getZ0()) > 1.0) {
236  //Off IP tracks
237  m_hPhiIndex->Fill(phiDegree, 0.5); //all skims
238  if (IsBhabha) iselect = 1.5;
239  if (IsHadron) iselect = 2.5;
240  if (IsMumu) iselect = 3.5;
241  m_hPhiIndex->Fill(phiDegree, iselect);
242  } else {
243  //IP tracks
244  m_hPhi->Fill(phiDegree);
245  m_hPhiIndex->Fill(phiDegree, 4.5); //all skims
246  if (IsBhabha) iselect = 5.5;
247  if (IsHadron) iselect = 6.5;
248  if (IsMumu) iselect = 7.5;
249  m_hPhiIndex->Fill(phiDegree, iselect);
250 
251  //for tracking efficiency part
252  double nsvdhits = fitresult->getHitPatternVXD().getNSVDHits();
253  double ncdchits = fitresult->getHitPatternCDC().getNHits();
254  if (nsvdhits > 6) {
255  if (ncdchits >= 100)ncdchits = 99.5; //push to last bin
256  m_hPhiEff->Fill(phiDegree, ncdchits);
257  }
258  }
259 
260  // Fill histograms of ADC/TDC if hits are associated with track
261  for (const RecoHitInformation::UsedCDCHit* hit : track->getCDCHitList()) {
262 
263  const genfit::TrackPoint* tp = track->getCreatedTrackPoint(track->getRecoHitInformation(hit));
264  if (!tp) {
265  B2WARNING("Can not access TrackPoint of this hit");
266  continue;
267  }
268 
269  UChar_t lay = hit->getICLayer();
270  UShort_t IWire = hit->getIWire();
271  UShort_t adc = hit->getADCCount();
272  unsigned short tdc = hit->getTDCCount();
273  WireID wireid(lay, IWire);
274  unsigned short bid = cdcgeo.getBoardID(wireid);
275 
276  m_hADC->Fill(bid, adc);
277  m_hTDC->Fill(bid, tdc);
278  m_hPhiHit->Fill(phiDegree, lay);
279  }
280  }
281 }
282 
284 {
285  m_hNEvents->SetBinContent(1, m_nEvents);
286 }
287 
289 {
290 }
291 
292 int CDCDQMModule::findPhiBin(double phi, const int& lay)
293 {
294  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
295  int nWires = cdcgeo.nWiresInLayer(lay);
296  double offset = cdcgeo.offset(lay);
297  double shift = (offset - 0.5) * 2 * TMath::Pi() / nWires;
298  double binLow = shift;
299  double binHigh = 2 * TMath::Pi() + shift;
300  // wrap around
301  if (phi < binLow) phi += 2 * TMath::Pi(); // Wrap around for values less than binLow
302  else if (phi >= binHigh) phi -= 2 * TMath::Pi(); // Wrap around for values >= binHigh
303  double binWidth = (binHigh - binLow) / nWires;
304  int binIndex = (phi - binLow) / binWidth;
305  // Return the bin index (1-based for ROOT histograms)
306  return binIndex + 1;
307 }
308 
309 double CDCDQMModule::getShiftedPhi(const ROOT::Math::XYZVector& position, const int& lay)
310 {
311  double phi = TMath::ATan2(position.Y(), position.X());
312  if (m_adjustWireShift) {
313  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
314  int nShifts = cdcgeo.nShifts(lay);
315  if (nShifts) {
316  int nWires = cdcgeo.nWiresInLayer(lay);
317  double fZ = cdcgeo.senseWireFZ(lay);
318  double bZ = cdcgeo.senseWireBZ(lay);
319  double R = cdcgeo.senseWireR(lay);
320  double phiSize = 2 * TMath::Pi() / nWires;
321  double phiF = phiSize * 0.5 * nShifts;
322  B2Vector3D f(R * TMath::Cos(phiF), R * TMath::Sin(phiF), fZ);
323  B2Vector3D b(R, 0, bZ);
324  B2Vector3D v = f - b;
325  B2Vector3D u = v.Unit();
326  double beta = (position.Z() - b.Z()) / u.Z();
327  B2Vector3D p = b + beta * u;
328  phi -= TMath::ATan2(p.Y(), p.X());
329  }
330  }
331  while (phi < 0) phi += (2 * TMath::Pi());
332  while (phi >= 2 * TMath::Pi()) phi -= (2 * TMath::Pi());
333  return phi;
334 }
double R
typedef autogenerated by FFTW
B2Vector3< DataType > Unit() const
Unit vector parallel to this.
Definition: B2Vector3.h:269
std::string m_recoTrackArrayName
Belle2::RecoTrack StoreArray name.
Definition: CDCDQMModule.h:114
StoreArray< RawCDC > m_rawCDCs
Input array for CDC Raw.
Definition: CDCDQMModule.h:110
TH2F * m_hPhiNCDC
Histogram of track associated nCDCHits vs phi.
Definition: CDCDQMModule.h:130
TH2F * m_hBit
Histogram of online databit removed.
Definition: CDCDQMModule.h:125
void initialize() override
Initialize the Module.
Definition: CDCDQMModule.cc:81
int m_minHits
Minimum hits for processing.
Definition: CDCDQMModule.h:117
void event() override
Event processor.
StoreArray< CDCRawHit > m_cdcRawHits
CDC raw hits.
Definition: CDCDQMModule.h:109
void endRun() override
End-of-run action.
TH2F * m_hPhiIndex
Histogram of cdc phi of different IP + skims tracks.
Definition: CDCDQMModule.h:127
StoreObjPtr< TRGSummary > m_trgSummary
Trigger summary.
Definition: CDCDQMModule.h:111
void terminate() override
Termination action.
double getShiftedPhi(const ROOT::Math::XYZVector &position, const int &lay)
Compute and shift phi if it is stereo layer return [0,2pi].
int findPhiBin(double phi, const int &lay)
Find bin corresponds to a specific phi in a layer phi must be in [0,2pi].
TH1F * m_hNEvents
Histogram of num.
Definition: CDCDQMModule.h:120
TH2F * m_hTDC
Histogram of TDC with track associated hits for all boards (0-299)
Definition: CDCDQMModule.h:123
TH2F * m_hPhiHit
Histogram of track associated hits in phi vs layer
Definition: CDCDQMModule.h:129
void beginRun() override
Called when entering a new run.
Definition: CDCDQMModule.cc:94
TH2F * m_hPhiEff
Histogram of cdc phi of tracking eff.
Definition: CDCDQMModule.h:128
bool m_adjustWireShift
If true, gets the correct phi view of the boards.
Definition: CDCDQMModule.h:118
TH1F * m_hPhi
Histogram of cdc phi of IP tracks.
Definition: CDCDQMModule.h:126
StoreArray< CDCHit > m_cdcHits
CDC hits.
Definition: CDCDQMModule.h:108
virtual ~CDCDQMModule()
Destructor.
Definition: CDCDQMModule.cc:46
TH2F * m_hADC
Histogram of ADC with track associated hits for all boards (0-299)
Definition: CDCDQMModule.h:122
TH1F * m_hOcc
Histogram of occupancy.
Definition: CDCDQMModule.h:121
StoreArray< RecoTrack > m_RecoTracks
RecoTracks.
Definition: CDCDQMModule.h:113
StoreArray< Track > m_Tracks
Tracks.
Definition: CDCDQMModule.h:112
StoreObjPtr< SoftwareTriggerResult > m_TrgResult
Store array for Trigger selection.
Definition: CDCDQMModule.h:115
TH2F * m_hHit
Histogram of Hits for all layers (0-55)
Definition: CDCDQMModule.h:124
void defineHisto() override
Histogram definitions.
Definition: CDCDQMModule.cc:50
Long64_t m_nEvents
Number of events processed.
Definition: CDCDQMModule.h:119
TH2F * m_hTrackingWireEff
Histogram of attached and expected CDC wires in layer.
Definition: CDCDQMModule.h:131
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Definition: CDCHit.h:40
The Class for CDC Geometry Parameters.
unsigned short getBoardID(const WireID &wID) const
Returns frontend board id. corresponding to the wire id.
int nShifts(int layerId) const
Returns number shift.
double offset(int layerID) const
Return wire offset in phi direction at endplate.
double senseWireBZ(int layerId) const
Returns backward z position of sense wire in each layer.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
double senseWireFZ(int layerId) const
Returns forward z position of sense wire in each layer.
ushort getNumberOfSenseLayers() const
Get the number of sense layers.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
double senseWireR(int layerId) const
Returns radius of sense wire in each layer.
static const ChargedStable pion
charged pion particle
Definition: Const.h:652
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29
unsigned short getNHits() const
Get the total Number of CDC hits in the fit.
unsigned short getNSVDHits() const
Get total number of hits in the SVD.
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
void setReturnValue(int value)
Sets the return value for this module as integer.
Definition: Module.cc:220
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:79
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
@ TTYP_RAND
random trigger events
Definition: TRGSummary.h:67
Values of the result of a track fit with a given particle hypothesis.
Helix getHelix() const
Conversion to framework Helix (without covariance).
double getPhi() const
Getter for phi0 with CDF naming convention.
double getD0() const
Getter for d0.
double getZ0() const
Getter for z0.
HitPatternCDC getHitPatternCDC() const
Getter for the hit pattern in the CDC;.
HitPatternVXD getHitPatternVXD() const
Getter for the hit pattern in the VXD;.
static const double deg
degree to radians
Definition: Unit.h:109
Class to identify a wire inside the CDC.
Definition: WireID.h:34
Class to store variables with their name which were sent to the logging service.
Class where important numbers and properties of a fit can be stored.
Definition: FitStatus.h:80
double getNdf() const
Get the degrees of freedom of the fit.
Definition: FitStatus.h:122
Object containing AbsMeasurement and AbsFitterInfo objects.
Definition: TrackPoint.h:46
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
@ c_accept
Accept this event.
Abstract base class for different kinds of events.