Belle II Software  release-08-01-10
TOPPhotonYieldsCollectorModule.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 #include <top/modules/collectors/TOPPhotonYieldsCollectorModule.h>
10 #include <top/reconstruction_cpp/TOPTrack.h>
11 #include <top/geometry/TOPGeometryPar.h>
12 
13 // framework aux
14 #include <framework/gearbox/Unit.h>
15 #include <framework/logging/Logger.h>
16 
17 // root
18 #include <TH1F.h>
19 #include <TH2F.h>
20 #include <TProfile.h>
21 
22 using namespace std;
23 
24 namespace Belle2 {
30  using namespace TOP;
31 
32  //-----------------------------------------------------------------
34  //-----------------------------------------------------------------
35 
36  REG_MODULE(TOPPhotonYieldsCollector);
37 
38  //-----------------------------------------------------------------
39  // Implementation
40  //-----------------------------------------------------------------
41 
42  TOPPhotonYieldsCollectorModule::TOPPhotonYieldsCollectorModule()
43  {
44  // set module description and processing properties
45  setDescription("A collector for photon pixel yields aimed for PMT ageing studies and for finding optically decoupled PMT's");
46  setPropertyFlags(c_ParallelProcessingCertified);
47 
48  // module parameters
49  addParam("sample", m_sample, "sample type: one of dimuon or bhabha", std::string("dimuon"));
50  addParam("deltaEcms", m_deltaEcms, "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
51  addParam("dr", m_dr, "cut on POCA in r", 2.0);
52  addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
53  addParam("minThresholdEffi", m_minThresholdEffi, "threshold efficiency cut to suppress unreliable calibrations", 0.7);
54 
55  }
56 
57 
58  void TOPPhotonYieldsCollectorModule::prepare()
59  {
60  // input collections
61  m_digits.isRequired();
62  m_tracks.isRequired();
63  m_extHits.isRequired();
64  m_recBunch.isRequired();
65  m_asicMask.isRequired();
66  m_associatedPDFs.isRequired();
67 
68  // set track selector
69  if (m_sample == "dimuon" or m_sample == "bhabha") {
70  m_selector = TrackSelector(m_sample);
71  m_selector.setDeltaEcms(m_deltaEcms);
72  m_selector.setCutOnPOCA(m_dr, m_dz);
73  m_selector.setCutOnLocalZ(m_minZ, m_maxZ);
74  } else {
75  B2ERROR("Invalid sample type '" << m_sample << "'");
76  }
77 
78  // create and register histograms
79 
80  const int numModules = 16;
81  const int numPixels = 512;
82 
83  // time stamp (average unix time and its standard deviation)
84  auto* timeStamp = new TProfile("timeStamp", "Time stamp; ; unix time", 1, 0, 1, 0, 1.0e10, "S");
85  registerObject<TProfile>("timeStamp", timeStamp);
86 
87  // number of selected tracks per slot
88  auto* numTracks = new TH1F("numTracks", "Number of tracks per slot; slot number; track count", numModules, 0.5, numModules + 0.5);
89  registerObject<TH1F>("numTracks", numTracks);
90 
91  // number of pixel hits in a signal time window
92  for (int slot = 1; slot <= numModules; slot++) {
93  string name = (slot < 10) ? "signalHits_0" + to_string(slot) : "signalHits_" + to_string(slot);
94  string title = "Hits in signal window for slot " + to_string(slot);
95  auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
96  h->SetXTitle("pixel number");
97  h->SetYTitle("hit count");
98  registerObject<TH1F>(name, h);
99  m_signalNames.push_back(name);
100  }
101 
102  // number of pixel hits in a background time window
103  for (int slot = 1; slot <= numModules; slot++) {
104  string name = (slot < 10) ? "bkgHits_0" + to_string(slot) : "bkgHits_" + to_string(slot);
105  string title = "Hits in background window for slot " + to_string(slot);
106  auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
107  h->SetXTitle("pixel number");
108  h->SetYTitle("hit count");
109  registerObject<TH1F>(name, h);
110  m_bkgNames.push_back(name);
111  }
112 
113  // active pixels
114  for (int slot = 1; slot <= numModules; slot++) {
115  string name = (slot < 10) ? "activePixels_0" + to_string(slot) : "activePixels_" + to_string(slot);
116  string title = "Active pixels for slot " + to_string(slot);
117  auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
118  h->SetXTitle("pixel number");
119  h->SetYTitle("track count");
120  registerObject<TH1F>(name, h);
121  m_activeNames.push_back(name);
122  }
123 
124  // number of pixel hits with low impact angle on photo cathode
125  for (int slot = 1; slot <= numModules; slot++) {
126  string name = (slot < 10) ? "alphaLow_0" + to_string(slot) : "alphaLow_" + to_string(slot);
127  string title = "Hits w/ low alpha for slot " + to_string(slot);
128  auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
129  h->SetXTitle("pixel number");
130  h->SetYTitle("hit count");
131  registerObject<TH1F>(name, h);
132  m_alphaLowNames.push_back(name);
133  }
134 
135  // number of pixel hits with high impact angle on photo cathode
136  for (int slot = 1; slot <= numModules; slot++) {
137  string name = (slot < 10) ? "alphaHigh_0" + to_string(slot) : "alphaHigh_" + to_string(slot);
138  string title = "Hits w/ high alpha for slot " + to_string(slot);
139  auto h = new TH1F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5);
140  h->SetXTitle("pixel number");
141  h->SetYTitle("hit count");
142  registerObject<TH1F>(name, h);
143  m_alphaHighNames.push_back(name);
144  }
145 
146  // pixel pulse-height distributions
147  for (int slot = 1; slot <= numModules; slot++) {
148  string name = (slot < 10) ? "pulseHeights_0" + to_string(slot) : "pulseHeights_" + to_string(slot);
149  string title = "Pulse height distributions for slot " + to_string(slot);
150  auto h = new TH2F(name.c_str(), title.c_str(), numPixels, 0.5, numPixels + 0.5, 200, 0, 2000);
151  h->SetXTitle("pixel number");
152  h->SetYTitle("pulse height");
153  registerObject<TH2F>(name, h);
154  m_pulseHeightNames.push_back(name);
155  }
156 
157  // local z-distribution of tracks
158  for (int slot = 1; slot <= numModules; slot++) {
159  string name = (slot < 10) ? "muonZ_0" + to_string(slot) : "muonZ_" + to_string(slot);
160  string title = "Track z-distribution for slot " + to_string(slot);
161  auto h = new TH1F(name.c_str(), title.c_str(), 100, m_minZ, m_maxZ);
162  h->SetXTitle("local z [cm]");
163  h->SetYTitle("track count");
164  registerObject<TH1F>(name, h);
165  m_muonZNames.push_back(name);
166  }
167 
168  }
169 
170 
171  void TOPPhotonYieldsCollectorModule::collect()
172  {
173  // bunch must be reconstructed
174 
175  if (not m_recBunch->isReconstructed()) return;
176 
177  // loop over reconstructed tracks, make a selection and fill histograms
178 
179  for (const auto& track : m_tracks) {
180  // track selection
181  TOPTrack trk(track);
182  if (not trk.isValid()) continue;
183  if (not m_selector.isSelected(trk)) continue;
184 
185  // fill histograms
186  auto timeStamp = getObjectPtr<TProfile>("timeStamp");
187  timeStamp->Fill(0.5, m_eventMetaData->getTime() / 1000000000);
188 
189  int slot = trk.getModuleID();
190  auto numTracks = getObjectPtr<TH1F>("numTracks");
191  numTracks->Fill(slot);
192 
193  auto muonZ = getObjectPtr<TH1F>(m_muonZNames[slot - 1]);
194  muonZ->Fill(m_selector.getLocalPosition().Z());
195 
196  auto signalHits = getObjectPtr<TH1F>(m_signalNames[slot - 1]);
197  auto bkgHits = getObjectPtr<TH1F>(m_bkgNames[slot - 1]);
198  auto pulseHeight = getObjectPtr<TH2F>(m_pulseHeightNames[slot - 1]);
199  for (const auto& digit : m_digits) {
200  if (digit.getModuleID() != slot) continue;
201  if (digit.getHitQuality() != TOPDigit::c_Good) continue; // junk hit or pixel masked-out
202  if (not m_thresholdEff->isCalibrated(slot, digit.getChannel())) continue; // threshold effi. not calibrated
203  double effi = m_thresholdEff->getThrEff(slot, digit.getChannel());
204  if (effi < m_minThresholdEffi) continue; // to suppress possibly unreliable calibration
205  if (std::abs(digit.getTime()) > m_timeWindow) continue;
206  // fill signal and background hits with weight=1/effi to correct for threshold efficiency
207  if (digit.getTime() > 0) {
208  signalHits->Fill(digit.getPixelID(), 1 / effi);
209  pulseHeight->Fill(digit.getPixelID(), digit.getPulseHeight());
210  } else {
211  bkgHits->Fill(digit.getPixelID(), 1 / effi);
212  }
213  }
214 
215  auto activePixels = getObjectPtr<TH1F>(m_activeNames[slot - 1]);
216  const auto& chMapper = TOPGeometryPar::Instance()->getChannelMapper();
217  for (int pixel = 1; pixel <= activePixels->GetNbinsX(); pixel++) {
218  unsigned channel = chMapper.getChannel(pixel);
219  if (not m_thresholdEff->isCalibrated(slot, channel)) continue; // pixel excluded in counting hits
220  if (m_thresholdEff->getThrEff(slot, channel) < m_minThresholdEffi) continue; // pixel excluded in counting hits
221  if (m_channelMask->isActive(slot, channel) and m_asicMask->isActive(slot, channel)) activePixels->Fill(pixel);
222  }
223 
224  if (std::abs(m_selector.getLocalPosition().Z()) > m_excludedZ) {
225  auto alphaLow = getObjectPtr<TH1F>(m_alphaLowNames[slot - 1]);
226  auto alphaHigh = getObjectPtr<TH1F>(m_alphaHighNames[slot - 1]);
227  for (const auto& digit : m_digits) {
228  if (digit.getModuleID() != slot) continue;
229  if (digit.getHitQuality() != TOPDigit::c_Good) continue; // junk hit or pixel masked-out
230  const auto* pdf = digit.getRelated<TOPAssociatedPDF>();
231  if (not pdf) continue;
232  const auto* peak = pdf->getSinglePeak();
233  if (not peak) continue; // hit associated with background
234  double alpha = acos(std::abs(peak->kzd)) / Unit::deg;
235  if (alpha > 60) continue;
236  if (alpha < 30) alphaLow->Fill(digit.getPixelID());
237  else alphaHigh->Fill(digit.getPixelID());
238  }
239  }
240  }
241 
242  }
243 
244 
246 }
Class to store analytic PDF associated with a photon.
Reconstructed track at TOP.
Definition: TOPTrack.h:39
bool isValid() const
Checks if track is successfully constructed.
Definition: TOPTrack.h:137
int getModuleID() const
Returns slot ID.
Definition: TOPTrack.h:143
Utility for the track selection - used in various calibration modules.
Definition: TrackSelector.h:27
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.