11 #include <top/modules/TOPRingPlotter/TOPRingPlotterModule.h>
13 #include <analysis/dataobjects/ParticleList.h>
14 #include <analysis/dataobjects/Particle.h>
16 #include <framework/datastore/StoreArray.h>
17 #include <framework/datastore/StoreObjPtr.h>
19 #include <framework/logging/Logger.h>
20 #include <framework/utilities/MakeROOTCompatible.h>
29 #include <framework/datastore/DataStore.h>
30 #include <framework/datastore/StoreArray.h>
31 #include <framework/datastore/StoreObjPtr.h>
34 #include <framework/gearbox/Unit.h>
35 #include <framework/gearbox/Const.h>
36 #include <framework/logging/Logger.h>
39 #include <framework/dataobjects/EventMetaData.h>
40 #include <mdst/dataobjects/Track.h>
41 #include <mdst/dataobjects/MCParticle.h>
42 #include <top/dataobjects/TOPLikelihood.h>
43 #include <top/dataobjects/TOPBarHit.h>
44 #include <tracking/dataobjects/ExtHit.h>
45 #include <top/dataobjects/TOPDigit.h>
46 #include <mdst/dataobjects/ECLCluster.h>
48 #include <analysis/VariableManager/Manager.h>
50 #include <top/geometry/TOPGeometryPar.h>
51 #include <top/reconstruction/TOPreco.h>
52 #include <top/reconstruction/TOPtrack.h>
53 #include <top/reconstruction/TOPconfigure.h>
57 using namespace Belle2::Variable;
66 R
"DOC(A module to plot the x-t images from TOP, and in general study the distribution of the digits associated to the particles in a particleList)DOC");
69 addParam(
"particleList", m_particleList,
"List of particles to be used for plotting", std::string(
"pi+:all"));
70 addParam(
"variables", m_variables,
"List of variables to be saved", {});
71 addParam(
"pdgHyp", m_pdgHyp,
"List of pdg codes for which the PDF is sampled ansd saved. Valid values are 11, 13, 211, 321, 2212.",
73 addParam(
"outputName", m_outputName,
"Name of the output file", std::string(
"TOPRings.root"));
74 addParam(
"nToys", m_toyNumber,
75 "Number of toys used to sample the PDFs. Set it to a large number for a precise sampling of the PDF in the histograms (suggested for small number of events) ",
77 addParam(
"saveHistograms", m_saveHistograms,
78 "Set true to save the histograms of the maps in addition to the list of sampled pseudo-digits",
false);
95 m_hitMapMCPI->Reset();
98 m_hitMapMCMU->Reset();
100 for (
int i = 0; i < m_MaxPDFPhotons; i++) {
116 for (
int i = 0; i < m_MaxPhotons; i++) {
118 m_digitChannel[i] = 0;
120 m_digitPixelCol[i] = 0;
121 m_digitPixelRow[i] = 0;
122 m_digitAmplitude[i] = 0;
124 m_digitASICChannel[i] = 0;
125 m_digitPMTNumber[i] = 0;
126 m_digitSlot[i] = {0};
127 m_digitBoardstack[i] = {0};
128 m_digitCarrier[i] = {0};
129 m_digitAsic[i] = {0};
130 m_digitQuality[i] = {0};
139 float* timeArray,
int& arrayGuard,
int& toyCounter)
149 TOPreco reco(1, &mass, &pdgCode);
159 m_pdfAsHisto->Reset();
162 for (
int pixelID = 1; pixelID <= 512; pixelID++) {
163 for (
int iBinY = 1; iBinY < 500 + 1; iBinY++) {
165 auto time = m_pdfAsHisto->GetYaxis()->GetBinCenter(iBinY);
166 auto pdfVal = reco.
getPDF(pixelID, time, mass, pdgCode);
167 m_pdfAsHisto->Fill(pixelID - 0.5, time, pdfVal * 0.2);
168 short pixelCol = (pixelID - 1) % 64 + 1;
169 histo->Fill(pixelCol, time, pdfVal * 1.6);
175 m_pdfAsHisto->Scale(nExpPhot);
176 histo->Scale(nExpPhot);
179 for (
int iSim = 0; iSim < m_toyNumber; iSim++) {
184 std::vector<float> tmpTime;
185 std::vector<short> tmpPixel;
187 short numPhot = gRandom->Poisson(nExpPhot);
189 for (
short rn = 0;
rn < numPhot;
rn++) {
192 m_pdfAsHisto->GetRandom2(pxID, time);
193 tmpTime.push_back(time);
194 tmpPixel.push_back(
short(pxID));
200 if (arrayGuard + tmpTime.size() < m_MaxPDFPhotons) {
201 for (
unsigned int iPh = 0; iPh < tmpTime.size(); iPh++) {
202 pixelArray[arrayGuard] = tmpPixel[iPh];
203 timeArray[arrayGuard] = tmpTime[iPh];
223 for (
auto pdg : m_pdgHyp) {
224 if ((pdg != 11) & (pdg != 211) & (pdg != 321) & (pdg != 13) & (pdg != 2212))
225 B2FATAL(
"Invalid PDG hypothesis for the PDF evaluation: " << pdg);
226 short duplicateCount = 0;
227 for (
auto pdg2 : m_pdgHyp) {
231 if (duplicateCount > 1)
232 B2FATAL(
"Duplicate PDG hypothesis found");
235 m_hitMapMCK =
new TH2F(
"hitMapMCK",
"x-t map of the kaon PDF", 64, 0, 64, 500, 0, 100);
236 m_hitMapMCPI =
new TH2F(
"hitMapMCPI",
"x-t map of the pion PDF", 64, 0, 64, 500, 0, 100);
237 m_hitMapMCP =
new TH2F(
"hitMapMCP",
"x-t map of the proton PDF", 64, 0, 64, 500, 0, 100);
238 m_hitMapMCE =
new TH2F(
"hitMapMCE",
"x-t map of the electron PDF", 64, 0, 64, 500, 0, 100);
239 m_hitMapMCMU =
new TH2F(
"hitMapMCMU",
"x-t map of the muon PDF", 64, 0, 64, 500, 0, 100);
241 m_pdfAsHisto =
new TH2F(
"pdfAsHisto",
"tms holder for the pdf to be sampled", 512, 0, 512, 500, 0, 100);
243 B2INFO(
"creating a tree for TOPRingPlotterModule");
244 m_outputFile =
new TFile(m_outputName.c_str(),
"recreate");
245 m_tree =
new TTree(
"tree",
"tree");
247 if (m_saveHistograms) {
248 for (
auto pdg : m_pdgHyp) {
250 m_tree->Branch(
"hitMapMCE",
"TH2F", &m_hitMapMCE, 32000, 0);
252 m_tree->Branch(
"hitMapMCMU",
"TH2F", &m_hitMapMCMU, 32000, 0);
254 m_tree->Branch(
"hitMapMCPI",
"TH2F", &m_hitMapMCPI, 32000, 0);
256 m_tree->Branch(
"hitMapMCK",
"TH2F", &m_hitMapMCK, 32000, 0);
257 else if (pdg == 2212)
258 m_tree->Branch(
"hitMapMCP",
"TH2F", &m_hitMapMCP, 32000, 0);
262 m_tree->Branch(
"nDigits", &m_nDigits,
"m_nDigits/S");
263 m_tree->Branch(
"digitTime", m_digitTime,
"m_digitTime[m_nDigits]/F");
264 m_tree->Branch(
"digitAmplitude", m_digitAmplitude,
"m_digitAmplitude[m_nDigits]/F");
265 m_tree->Branch(
"digitWidth", m_digitWidth,
"m_digitWidth[m_nDigits]/F");
266 m_tree->Branch(
"digitChannel", m_digitChannel,
"m_digitChannel[m_nDigits]/S");
267 m_tree->Branch(
"digitPixel", m_digitPixel,
"m_digitPixel[m_nDigits]/S");
268 m_tree->Branch(
"digitPixelCol", m_digitPixelCol,
"m_digitPixelCol[m_nDigits]/S");
269 m_tree->Branch(
"digitPixelRow", m_digitPixelRow,
"m_digitPixelRow[m_nDigits]/S");
270 m_tree->Branch(
"digitASICChannel", m_digitASICChannel,
"m_digitASICChannel[m_nDigits]/S");
271 m_tree->Branch(
"digitPMTNumber", m_digitPMTNumber,
"m_digitPMTNumber[m_nDigits]/S");
272 m_tree->Branch(
"digitSlot", m_digitSlot,
"m_digitSlot[m_nDigits]/S");
273 m_tree->Branch(
"digitBoardstack", m_digitBoardstack,
"m_digitBoardstack[m_nDigits]/S");
274 m_tree->Branch(
"digitCarrier", m_digitCarrier,
"m_digitCarrier[m_nDigits]/S");
275 m_tree->Branch(
"digitAsic", m_digitAsic,
"m_digitAsic[m_nDigits]/S");
276 m_tree->Branch(
"digitQuality", m_digitQuality,
"m_digitQuality[m_nDigits]/S");
278 m_tree->Branch(
"pdfSamplesP", &m_pdfSamplesP,
"m_pdfSamplesP/I");
279 m_tree->Branch(
"pdfToysP", &m_pdfToysP,
"m_pdfToysP/I");
280 m_tree->Branch(
"pdfPixelP", m_pdfPixelP,
"m_pdfPixelP[m_pdfSamplesP]/S");
281 m_tree->Branch(
"pdfTimeP", m_pdfTimeP,
"m_pdfTimeP[m_pdfSamplesP]/F");
283 m_tree->Branch(
"pdfSamplesK", &m_pdfSamplesK,
"m_pdfSamplesK/I");
284 m_tree->Branch(
"pdfToysK", &m_pdfToysK,
"m_pdfToysK/I");
285 m_tree->Branch(
"pdfPixelK", m_pdfPixelK,
"m_pdfPixelK[m_pdfSamplesK]/S");
286 m_tree->Branch(
"pdfTimeK", m_pdfTimeK,
"m_pdfTimeK[m_pdfSamplesK]/F");
288 m_tree->Branch(
"pdfSamplesPI", &m_pdfSamplesPI,
"m_pdfSamplesPI/I");
289 m_tree->Branch(
"pdfToysPI", &m_pdfToysPI,
"m_pdfToysPI/I");
290 m_tree->Branch(
"pdfPixelPI", m_pdfPixelPI,
"m_pdfPixelPI[m_pdfSamplesPI]/S");
291 m_tree->Branch(
"pdfTimePI", m_pdfTimePI,
"m_pdfTimePI[m_pdfSamplesPI]/F");
293 m_tree->Branch(
"pdfSamplesMU", &m_pdfSamplesMU,
"m_pdfSamplesMU/I");
294 m_tree->Branch(
"pdfToysMU", &m_pdfToysMU,
"m_pdfToysMU/I");
295 m_tree->Branch(
"pdfPixelMU", m_pdfPixelMU,
"m_pdfPixelMU[m_pdfSamplesMU]/S");
296 m_tree->Branch(
"pdfTimeMU", m_pdfTimeMU,
"m_pdfTimeMU[m_pdfSamplesMU]/F");
298 m_tree->Branch(
"pdfSamplesE", &m_pdfSamplesE,
"m_pdfSamplesE/I");
299 m_tree->Branch(
"pdfToysE", &m_pdfToysE,
"m_pdfToysE/I");
300 m_tree->Branch(
"pdfPixelE", m_pdfPixelE,
"m_pdfPixelE[m_pdfSamplesE]/S");
301 m_tree->Branch(
"pdfTimeE", m_pdfTimeE,
"m_pdfTimeE[m_pdfSamplesE]/F");
306 m_branchAddresses.resize(m_variables.size() + 1);
307 size_t enumerate = 0;
308 for (
const std::string& varStr : m_variables) {
310 m_tree->Branch(branchName.c_str(), &m_branchAddresses[enumerate], (branchName +
"/D").c_str());
314 B2ERROR(
"Variable '" << varStr <<
"' is not available in Variable::Manager!");
316 if (m_particleList.empty() && var->description.find(
"[Eventbased]") == std::string::npos) {
317 B2ERROR(
"Variable '" << varStr <<
"' is not an event-based variable, "
318 "but you are using VariablesToNtuple without a decay string, i.e. in the event-wise mode.\n"
319 "If you have created an event-based alias you can wrap your alias with `eventCached` to "
320 "declare it as event based, which avoids this error.\n\n"
321 "vm.addAlias('myAliasName', 'eventCached(myAlias)')");
324 m_functions.push_back(var->function);
332 extHits.isRequired();
334 likelihoods.isRequired();
338 barHits.isOptional();
355 if (! particles.isValid())
359 int n_part = particles->getListSize();
360 for (
int i = 0; i < n_part; i++) {
366 const Particle* particle = particles->getParticle(i);
367 const Track* track = particle->getTrack();
369 bool isFromTrack =
true;
371 short deltaModule = 0;
378 const ECLCluster* clstr = particle->getECLCluster();
386 auto phi = particle->getECLCluster()->getPhi();
388 phi = 2 * TMath::Pi() - phi;
389 auto rawModuleID = phi / (TMath::Pi() / 8) + 1;
390 moduleID = int(rawModuleID);
391 if (rawModuleID - moduleID > 0.5) {
413 for (
const auto& digi : digits) {
415 if ((digi.getModuleID() == moduleID) || (!isFromTrack && digi.getModuleID() == moduleID + deltaModule)) {
416 m_digitTime[m_nDigits] = digi.getTime();
417 m_digitChannel[m_nDigits] = digi.getChannel();
418 m_digitPixel[m_nDigits] = digi.getPixelID();
419 m_digitPixelCol[m_nDigits] = digi.getPixelCol();
420 m_digitPixelRow[m_nDigits] = digi.getPixelRow();
421 m_digitAmplitude[m_nDigits] = digi.getPulseHeight();
422 m_digitWidth[m_nDigits] = digi.getPulseWidth();
423 m_digitASICChannel[m_nDigits] = digi.getASICChannel();
424 m_digitPMTNumber[m_nDigits] = digi.getPMTNumber();
425 m_digitSlot[m_nDigits] = digi.getModuleID();
426 m_digitBoardstack[m_nDigits] = digi.getBoardstackNumber();
427 m_digitCarrier[m_nDigits] = digi.getCarrierNumber();
428 m_digitAsic[m_nDigits] = digi.getASICNumber();
429 m_digitQuality[m_nDigits] = digi.getHitQuality();
431 if (m_nDigits > m_MaxPhotons)
break;
436 for (
unsigned int iVar = 0; iVar < m_variables.size(); iVar++) {
437 m_branchAddresses[iVar] = m_functions[iVar](particle);
442 for (
auto pdg : m_pdgHyp) {
446 fillPDF(
Belle2::Const::muon, track, m_hitMapMCMU, m_pdfPixelMU, m_pdfTimeMU, m_pdfSamplesMU, m_pdfToysMU);
448 fillPDF(
Belle2::Const::pion, track, m_hitMapMCPI, m_pdfPixelPI, m_pdfTimePI, m_pdfSamplesPI, m_pdfToysPI);
450 fillPDF(
Belle2::Const::kaon, track, m_hitMapMCK, m_pdfPixelK, m_pdfTimeK, m_pdfSamplesK, m_pdfToysK);
451 else if (pdg == 2212)
452 fillPDF(
Belle2::Const::proton, track, m_hitMapMCP, m_pdfPixelP, m_pdfTimeP, m_pdfSamplesP, m_pdfToysP);
465 m_outputFile->Close();