9 #include <top/modules/TOPRingPlotter/TOPRingPlotterModule.h>
11 #include <analysis/dataobjects/ParticleList.h>
12 #include <analysis/dataobjects/Particle.h>
14 #include <framework/datastore/StoreArray.h>
15 #include <framework/datastore/StoreObjPtr.h>
17 #include <framework/logging/Logger.h>
18 #include <framework/utilities/MakeROOTCompatible.h>
25 #include <TDirectory.h>
28 #include <framework/datastore/DataStore.h>
29 #include <framework/datastore/StoreArray.h>
30 #include <framework/datastore/StoreObjPtr.h>
33 #include <framework/gearbox/Unit.h>
34 #include <framework/gearbox/Const.h>
35 #include <framework/logging/Logger.h>
38 #include <mdst/dataobjects/Track.h>
39 #include <mdst/dataobjects/MCParticle.h>
40 #include <top/dataobjects/TOPLikelihoodScanResult.h>
41 #include <top/dataobjects/TOPLikelihood.h>
42 #include <top/dataobjects/TOPBarHit.h>
43 #include <tracking/dataobjects/ExtHit.h>
44 #include <top/dataobjects/TOPDigit.h>
45 #include <mdst/dataobjects/ECLCluster.h>
47 #include <analysis/VariableManager/Manager.h>
49 #include <top/geometry/TOPGeometryPar.h>
50 #include <top/reconstruction_cpp/TOPTrack.h>
51 #include <top/reconstruction_cpp/PDFConstructor.h>
52 #include <top/reconstruction_cpp/TOPRecoManager.h>
56 using namespace Belle2::Variable;
65 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");
68 addParam(
"particleList", m_particleList,
"List of particles to be used for plotting", std::string(
"pi+:all"));
69 addParam(
"variables", m_variables,
"List of variables to be saved", {});
70 addParam(
"pdgHyp", m_pdgHyp,
"List of pdg codes for which the PDF is sampled ansd saved. Valid values are 11, 13, 211, 321, 2212.",
72 addParam(
"outputName", m_outputName,
"Name of the output file", std::string(
"TOPRings.root"));
73 addParam(
"nToys", m_toyNumber,
74 "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) ",
76 addParam(
"saveHistograms", m_saveHistograms,
77 "Set true to save the histograms of the maps in addition to the list of sampled pseudo-digits",
false);
78 addParam(
"saveLLScan", m_saveLLScan,
79 "Set true to save the results of the LL scan. Requires to add TOPLLScannerModule to the path",
false);
97 m_hitMapMCPI->Reset();
100 m_hitMapMCMU->Reset();
103 for (
int i = 0; i < 10000; i++) {
108 for (
int i = 0; i < m_MaxPDFPhotons; i++) {
124 for (
int i = 0; i < m_MaxPhotons; i++) {
126 m_digitChannel[i] = 0;
128 m_digitPixelCol[i] = 0;
129 m_digitPixelRow[i] = 0;
130 m_digitAmplitude[i] = 0;
132 m_digitASICChannel[i] = 0;
133 m_digitPMTNumber[i] = 0;
134 m_digitSlot[i] = {0};
135 m_digitBoardstack[i] = {0};
136 m_digitCarrier[i] = {0};
137 m_digitAsic[i] = {0};
138 m_digitQuality[i] = {0};
147 float* timeArray,
int& arrayGuard,
int& toyCounter)
150 if (not track)
return;
158 if (not pdfConstructor.
isValid())
return;
161 m_pdfAsHisto->Reset();
164 for (
int pixelID = 1; pixelID <= 512; pixelID++) {
165 for (
int iBinY = 1; iBinY < 500 + 1; iBinY++) {
167 auto time = m_pdfAsHisto->GetYaxis()->GetBinCenter(iBinY);
168 auto pdfVal = pdfConstructor.
getPDFValue(pixelID, time, 0.070);
169 m_pdfAsHisto->Fill(pixelID - 0.5, time, pdfVal * 0.2);
170 short pixelCol = (pixelID - 1) % 64 + 1;
171 histo->Fill(pixelCol, time, pdfVal * 1.6);
177 m_pdfAsHisto->Scale(nExpPhot);
178 histo->Scale(nExpPhot);
181 for (
int iSim = 0; iSim < m_toyNumber; iSim++) {
186 std::vector<float> tmpTime;
187 std::vector<short> tmpPixel;
189 short numPhot = gRandom->Poisson(nExpPhot);
191 for (
short rn = 0;
rn < numPhot;
rn++) {
194 m_pdfAsHisto->GetRandom2(pxID, time);
195 tmpTime.push_back(time);
196 tmpPixel.push_back(
short(pxID));
201 if (arrayGuard + tmpTime.size() < m_MaxPDFPhotons) {
202 for (
unsigned int iPh = 0; iPh < tmpTime.size(); iPh++) {
203 pixelArray[arrayGuard] = tmpPixel[iPh];
204 timeArray[arrayGuard] = tmpTime[iPh];
221 for (
auto pdg : m_pdgHyp) {
224 B2FATAL(
"Invalid PDG hypothesis for the PDF evaluation: " << pdg);
225 short duplicateCount = 0;
226 for (
auto pdg2 : m_pdgHyp) {
230 if (duplicateCount > 1)
231 B2FATAL(
"Duplicate PDG hypothesis found");
234 m_hitMapMCK =
new TH2F(
"hitMapMCK",
"x-t map of the kaon PDF", 64, 0, 64, 500, 0, 100);
235 m_hitMapMCPI =
new TH2F(
"hitMapMCPI",
"x-t map of the pion PDF", 64, 0, 64, 500, 0, 100);
236 m_hitMapMCP =
new TH2F(
"hitMapMCP",
"x-t map of the proton PDF", 64, 0, 64, 500, 0, 100);
237 m_hitMapMCE =
new TH2F(
"hitMapMCE",
"x-t map of the electron PDF", 64, 0, 64, 500, 0, 100);
238 m_hitMapMCMU =
new TH2F(
"hitMapMCMU",
"x-t map of the muon PDF", 64, 0, 64, 500, 0, 100);
240 m_pdfAsHisto =
new TH2F(
"pdfAsHisto",
"tms holder for the pdf to be sampled", 512, 0, 512, 500, 0, 100);
242 TDirectory::TContext context;
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);
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");
304 m_tree->Branch(
"nScanPoints", &m_nScanPoints,
"m_nScanPoints/I");
305 m_tree->Branch(
"scanMass", m_scanMass,
"m_scanMass[m_nScanPoints]/F");
306 m_tree->Branch(
"scanLL", m_scanLL,
"m_scanLL[m_nScanPoints]/F");
312 m_branchAddresses.resize(m_variables.size() + 1);
313 size_t enumerate = 0;
314 for (
const std::string& varStr : m_variables) {
316 m_tree->Branch(branchName.c_str(), &m_branchAddresses[enumerate], (branchName +
"/D").c_str());
320 B2ERROR(
"Variable '" << varStr <<
"' is not available in Variable::Manager!");
322 if (m_particleList.empty() && var->description.find(
"[Eventbased]") == std::string::npos) {
323 B2ERROR(
"Variable '" << varStr <<
"' is not an event-based variable, "
324 "but you are using VariablesToNtuple without a decay string, i.e. in the event-wise mode.\n"
325 "If you have created an event-based alias you can wrap your alias with `eventCached` to "
326 "declare it as event based, which avoids this error.\n\n"
327 "vm.addAlias('myAliasName', 'eventCached(myAlias)')");
330 m_functions.push_back(var->function);
359 if (! particles.isValid())
363 int n_part = particles->getListSize();
364 for (
int i = 0; i < n_part; i++) {
370 const Particle* particle = particles->getParticle(i);
371 const Track* track = particle->getTrack();
373 bool isFromTrack =
true;
375 short deltaModule = 0;
382 const ECLCluster* clstr = particle->getECLCluster();
390 auto phi = particle->getECLCluster()->getPhi();
392 phi = 2 * TMath::Pi() - phi;
393 auto rawModuleID = phi / (TMath::Pi() / 8) + 1;
394 moduleID = int(rawModuleID);
395 if (rawModuleID - moduleID > 0.5) {
417 for (
const auto& digi : digits) {
419 if (m_nDigits >= m_MaxPhotons)
break;
420 if ((digi.getModuleID() == moduleID) || (!isFromTrack && digi.getModuleID() == moduleID + deltaModule)) {
421 m_digitTime[m_nDigits] = digi.getTime();
422 m_digitChannel[m_nDigits] = digi.getChannel();
423 m_digitPixel[m_nDigits] = digi.getPixelID();
424 m_digitPixelCol[m_nDigits] = digi.getPixelCol();
425 m_digitPixelRow[m_nDigits] = digi.getPixelRow();
426 m_digitAmplitude[m_nDigits] = digi.getPulseHeight();
427 m_digitWidth[m_nDigits] = digi.getPulseWidth();
428 m_digitASICChannel[m_nDigits] = digi.getASICChannel();
429 m_digitPMTNumber[m_nDigits] = digi.getPMTNumber();
430 m_digitSlot[m_nDigits] = digi.getModuleID();
431 m_digitBoardstack[m_nDigits] = digi.getBoardstackNumber();
432 m_digitCarrier[m_nDigits] = digi.getCarrierNumber();
433 m_digitAsic[m_nDigits] = digi.getASICNumber();
434 m_digitQuality[m_nDigits] = digi.getHitQuality();
440 for (
unsigned int iVar = 0; iVar < m_variables.size(); iVar++) {
441 m_branchAddresses[iVar] = m_functions[iVar](particle);
451 auto lls = llScan->getCoarseScanLLValues();
452 m_nScanPoints = lls.size();
453 for (
unsigned int j = 0; j < lls.size(); j++) {
454 m_scanMass[j] = masses[j];
455 m_scanLL[j] = lls[j];
459 for (
auto pdg : m_pdgHyp) {
463 fillPDF(
Belle2::Const::muon, track, m_hitMapMCMU, m_pdfPixelMU, m_pdfTimeMU, m_pdfSamplesMU, m_pdfToysMU);
465 fillPDF(
Belle2::Const::pion, track, m_hitMapMCPI, m_pdfPixelPI, m_pdfTimePI, m_pdfSamplesPI, m_pdfToysPI);
467 fillPDF(
Belle2::Const::kaon, track, m_hitMapMCK, m_pdfPixelK, m_pdfTimeK, m_pdfSamplesK, m_pdfToysK);
469 fillPDF(
Belle2::Const::proton, track, m_hitMapMCP, m_pdfPixelP, m_pdfTimeP, m_pdfSamplesP, m_pdfToysP);
481 TDirectory::TContext context;
484 m_outputFile->Close();
Provides a type-safe way to pass members of the chargedStableSet set.
static const ChargedStable muon
muon particle
static const ChargedStable pion
charged pion particle
static const ChargedStable proton
proton particle
static const ChargedStable kaon
charged kaon particle
static const ChargedStable electron
electron particle
int getDetectorRegion() const
Return detector region: 0: below acceptance, 1: FWD, 2: BRL, 3: BWD, 11: FWDGAP, 13: BWDGAP.
Class to store reconstructed particles.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
Accessor to arrays stored in the data store.
Type-safe access to single objects in the data store.
Class to store the result of the TOP LL scan (output of TOPLLScanner).
std::vector< float > getCoarseScanMassPoints() const
Return a std::vector containing the mass points used for the coarse LL scane.
A module to plot the x-t images from TOP, and in general study the distribution of the digits associa...
void initialize() override
Prepares the tree.
void event() override
Fills the tree.
void fillPDF(Belle2::Const::ChargedStable, const Track *, TH2F *, short *, float *, int &, int &)
Fills the pdf-related branches.
void terminate() override
Writes the tree.
void resetTree()
reset the tree variables.
PDF construction and log likelihood determination for a given track and particle hypothesis.
double getPDFValue(int pixelID, double time, double timeErr, double sigt=0) const
Returns PDF value.
bool isValid() const
Checks the object status.
double getExpectedPhotons() const
Returns the expected number of photons within the default time window.
@ c_Fine
y dependent everywhere
static void setTimeWindow(double minTime, double maxTime)
Sets time window.
Reconstructed track at TOP.
bool isValid() const
Checks if track is successfully constructed.
int getModuleID() const
Returns slot ID.
Class that bundles various TrackFitResults.
std::vector< std::string > resolveCollections(const std::vector< std::string > &variables)
Resolve Collection Returns variable names corresponding to the given collection or if it is not a col...
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
static Manager & Instance()
get singleton instance.
std::string makeROOTCompatible(std::string str)
Remove special characters that ROOT dislikes in branch names, e.g.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
TString rn()
Get random string.
Abstract base class for different kinds of events.
A variable returning a floating-point value for a given Particle.