9 #include <arich/modules/arichToNtuple/arichToNtupleModule.h>
11 #include <arich/dataobjects/ARICHLikelihood.h>
12 #include <arich/dataobjects/ARICHAeroHit.h>
13 #include <arich/dataobjects/ARICHTrack.h>
14 #include <arich/dataobjects/ARICHPhoton.h>
15 #include <arich/dataobjects/ARICHHit.h>
16 #include <mdst/dataobjects/Track.h>
17 #include <tracking/dataobjects/ExtHit.h>
20 #include <analysis/dataobjects/ParticleList.h>
21 #include <analysis/VariableManager/Manager.h>
22 #include <analysis/VariableManager/Utility.h>
25 #include <framework/logging/Logger.h>
26 #include <framework/pcore/ProcHandler.h>
27 #include <framework/core/ModuleParam.templateDetails.h>
29 #include <framework/datastore/DataStore.h>
30 #include <framework/datastore/StoreArray.h>
33 #include <framework/utilities/MakeROOTCompatible.h>
34 #include <framework/utilities/RootFileCreationManager.h>
49 setDescription(
"Local arich extension of VariblesToNtuple module to append detailed arich information to reconstructed candidates in the analysis output Ntuple. The TNtuple is candidate-based, meaning that the variables of each candidate are saved separate rows.");
50 setPropertyFlags(c_ParallelProcessingCertified | c_TerminateInAllProcesses);
52 vector<string> emptylist;
53 addParam(
"particleList", m_particleList,
54 "Name of particle list with reconstructed particles. If no list is provided the variables are saved once per event (only possible for event-type variables)",
56 addParam(
"arichSelector", m_arichSelector,
57 "Decay string with selected particles to which arich info should be appened", std::string(
""));
58 addParam(
"variables", m_variables,
59 "List of variables (or collections) to save. Variables are taken from Variable::Manager, and are identical to those available to e.g. ParticleSelector.",
61 addParam(
"arichVariables", m_arichVariables,
62 "List of aliases for particles to which arich info will be appended (used for tree branch names)",
65 addParam(
"fileName", m_fileName,
"Name of ROOT file for output.",
string(
"arichToNtuple.root"));
66 addParam(
"treeName", m_treeName,
"Name of the NTuple in the saved file.",
string(
"ntuple"));
68 std::tuple<std::string, std::map<int, unsigned int>> default_sampling{
"", {}};
69 addParam(
"sampling", m_sampling,
70 "Tuple of variable name and a map of integer values and inverse sampling rate. E.g. (signal, {1: 0, 0:10}) selects all signal candidates and every 10th background candidate.",
74 void arichToNtupleModule::initialize()
76 m_eventMetaData.isRequired();
86 if (not m_particleList.empty())
89 m_decaydescriptor.init(m_arichSelector);
92 if (m_fileName.empty()) {
93 B2FATAL(
"Output root file name is not set. Please set a vaild root output file name (\"fileName\" module parameter).");
97 m_file = RootFileCreationManager::getInstance().getFile(m_fileName);
99 B2ERROR(
"Could not create file \"" << m_fileName <<
100 "\". Please set a vaild root output file name (\"fileName\" module parameter).");
104 TDirectory::TContext directoryGuard(m_file.get());
107 if (m_file->Get(m_treeName.c_str())) {
108 B2FATAL(
"Tree with the name \"" << m_treeName
109 <<
"\" already exists in the file \"" << m_fileName <<
"\"\n"
110 <<
"\nYou probably want to either set the output fileName or the treeName to something else:\n\n"
111 <<
" from modularAnalysis import arichToNtuple\n"
112 <<
" arichToNtuple('pi+:all', ['p'], treename='pions', filename='arichToNtuple.root')\n"
113 <<
" arichToNtuple('gamma:all', ['p'], treename='photons', filename='arichToNtuple.root') # two trees, same file\n"
115 <<
" from modularAnalysis import arichToNtuple\n"
116 <<
" arichToNtuple('pi+:all', ['p'], filename='pions.root')\n"
117 <<
" arichToNtuple('gamma:all', ['p'], filename='photons.root') # two files\n"
123 m_tree.registerInDataStore(m_fileName + m_treeName, DataStore::c_DontWriteOut);
124 m_tree.construct(m_treeName.c_str(),
"");
125 m_tree->get().SetCacheSize(100000);
128 m_tree->get().Branch(
"__experiment__", &m_experiment,
"__experiment__/I");
129 m_tree->get().Branch(
"__run__", &m_run,
"__run__/I");
130 m_tree->get().Branch(
"__event__", &m_event,
"__event__/I");
131 if (not m_particleList.empty()) {
132 m_tree->get().Branch(
"__candidate__", &m_candidate,
"__candidate__/I");
133 m_tree->get().Branch(
"__ncandidates__", &m_ncandidates,
"__ncandidates__/I");
135 for (
const auto& variable : m_variables)
136 if (Variable::isCounterVariable(variable)) {
137 B2WARNING(
"The counter '" << variable
138 <<
"' is handled automatically by arichToNtuple, you don't need to add it.");
142 m_variables = Variable::Manager::Instance().resolveCollections(m_variables);
143 m_branchAddresses.resize(m_variables.size() + 1);
144 m_tree->get().Branch(
"__weight__", &m_branchAddresses[0],
"__weight__/D");
145 size_t enumerate = 1;
146 for (
const string& varStr : m_variables) {
149 m_tree->get().Branch(branchName.c_str(), &m_branchAddresses[enumerate], (branchName +
"/D").c_str());
154 B2ERROR(
"Variable '" << varStr <<
"' is not available in Variable::Manager!");
156 m_functions.push_back(var->function);
162 for (
const string& varStr : m_arichVariables) {
164 addARICHBranches(branchName);
167 m_tree->get().SetBasketSize(
"*", 1600);
169 m_sampling_name = std::get<0>(m_sampling);
170 m_sampling_rates = std::get<1>(m_sampling);
172 if (m_sampling_name !=
"") {
173 m_sampling_variable = Variable::Manager::Instance().getVariable(m_sampling_name);
174 if (m_sampling_variable ==
nullptr) {
175 B2FATAL(
"Couldn't find sample variable " << m_sampling_name <<
" via the Variable::Manager. Check the name!");
177 for (
const auto& pair : m_sampling_rates)
178 m_sampling_counts[pair.first] = 0;
180 m_sampling_variable =
nullptr;
185 float arichToNtupleModule::getInverseSamplingRateWeight(
const Particle* particle)
187 if (m_sampling_variable ==
nullptr)
190 long target = std::lround(m_sampling_variable->function(particle));
191 if (m_sampling_rates.find(target) != m_sampling_rates.end() and m_sampling_rates[target] > 0) {
192 m_sampling_counts[target]++;
193 if (m_sampling_counts[target] % m_sampling_rates[target] != 0)
196 m_sampling_counts[target] = 0;
197 return m_sampling_rates[target];
203 void arichToNtupleModule::event()
205 m_event = m_eventMetaData->getEvent();
206 m_run = m_eventMetaData->getRun();
207 m_experiment = m_eventMetaData->getExperiment();
209 if (m_particleList.empty()) {
210 m_branchAddresses[0] = getInverseSamplingRateWeight(
nullptr);
211 if (m_branchAddresses[0] > 0) {
212 for (
unsigned int iVar = 0; iVar < m_variables.size(); iVar++) {
213 m_branchAddresses[iVar + 1] = m_functions[iVar](
nullptr);
215 for (
auto& arich : m_arich) arich->clear();
216 m_tree->get().Fill();
221 m_ncandidates = particlelist->getListSize();
223 for (
unsigned int iPart = 0; iPart < m_ncandidates; iPart++) {
225 const Particle* particle = particlelist->getParticle(iPart);
226 m_branchAddresses[0] = getInverseSamplingRateWeight(particle);
227 if (m_branchAddresses[0] > 0) {
228 for (
unsigned int iVar = 0; iVar < m_variables.size(); iVar++) {
229 m_branchAddresses[iVar + 1] = m_functions[iVar](particle);
231 for (
auto& arich : m_arich) arich->clear();
232 fillARICHTree(particle);
233 m_tree->get().Fill();
239 void arichToNtupleModule::terminate()
241 if (!ProcHandler::parallelProcessingUsed() or ProcHandler::isOutputProcess()) {
242 B2INFO(
"Writing NTuple " << m_treeName);
243 TDirectory::TContext directoryGuard(m_file.get());
244 m_tree->write(m_file.get());
246 const bool writeError = m_file->TestBit(TFile::kWriteError);
249 B2FATAL(
"A write error occured while saving '" << m_fileName <<
"', please check if enough disk space is available.");
254 void arichToNtupleModule::addARICHBranches(
const std::string& name)
258 m_arich.push_back(tree);
259 m_tree->get().Branch((name +
"_detPhot").c_str(), &tree->detPhot,
"detPhot/I");
260 m_tree->get().Branch((name +
"_expPhot").c_str(), &tree->expPhot,
"e/F:mu:pi:K:p:d");
261 m_tree->get().Branch((name +
"_logL").c_str(), &tree->logL,
"e/F:mu:pi:K:p:d");
262 m_tree->get().Branch((name +
"_recHit").c_str(), &tree->recHit,
"PDG/I:x/F:y:z:p:theta:phi");
263 m_tree->get().Branch((name +
"_mcHit").c_str(), &tree->mcHit,
"PDG/I:x/F:y:z:p:theta:phi");
264 m_tree->get().Branch((name +
"_winHit").c_str(), &tree->winHit,
"x/F:y");
265 m_tree->get().Branch((name +
"_photons").c_str(),
"std::vector<Belle2::ARICHPhoton>", &tree->photons);
269 void arichToNtupleModule::fillARICHTree(
const Particle* particle)
272 std::vector<const Particle*> selParticles = m_decaydescriptor.getSelectionParticles(particle);
274 for (
auto p : selParticles) {
275 const Track* track = p->getTrack();
276 if (!track)
continue;
277 for (
const ExtHit& hit : track->getRelationsTo<
ExtHit>()) {
283 m_arich[iTree]->winHit[0] = winHit.X();
284 m_arich[iTree]->winHit[1] = winHit.Y();
290 m_arich[iTree]->recHit.x = recPos.X();
291 m_arich[iTree]->recHit.y = recPos.Y();
292 m_arich[iTree]->recHit.z = recPos.Z();
295 m_arich[iTree]->recHit.p = recMom.Mag();
296 m_arich[iTree]->recHit.theta = recMom.Theta();
297 m_arich[iTree]->recHit.phi = recMom.Phi();
302 m_arich[iTree]->logL.e = lkh->
getLogL(Const::electron);
303 m_arich[iTree]->logL.mu = lkh->
getLogL(Const::muon);
304 m_arich[iTree]->logL.pi = lkh->
getLogL(Const::pion);
305 m_arich[iTree]->logL.K = lkh->
getLogL(Const::kaon);
306 m_arich[iTree]->logL.p = lkh->
getLogL(Const::proton);
307 m_arich[iTree]->logL.d = lkh->
getLogL(Const::deuteron);
309 m_arich[iTree]->expPhot.e = lkh->
getExpPhot(Const::electron);
310 m_arich[iTree]->expPhot.mu = lkh->
getExpPhot(Const::muon);
311 m_arich[iTree]->expPhot.pi = lkh->
getExpPhot(Const::pion);
312 m_arich[iTree]->expPhot.K = lkh->
getExpPhot(Const::kaon);
313 m_arich[iTree]->expPhot.p = lkh->
getExpPhot(Const::proton);
314 m_arich[iTree]->expPhot.d = lkh->
getExpPhot(Const::deuteron);
322 m_arich[iTree]->mcHit.x = truePos.X();
323 m_arich[iTree]->mcHit.y = truePos.Y();
324 m_arich[iTree]->mcHit.z = truePos.Z();
327 m_arich[iTree]->mcHit.p = trueMom.Mag();
328 m_arich[iTree]->mcHit.theta = trueMom.Theta();
329 m_arich[iTree]->mcHit.phi = trueMom.Phi();
330 m_arich[iTree]->mcHit.PDG = aeroHit->
getPDG();
Datastore class that holds information on track parameters at the entrance in aerogel.
TVector3 getMomentum() const
Get track momentum (at entrance in 1. aerogel plane)
int getPDG() const
Get particle PDG identity number.
TVector3 getPosition() const
Get track position (at entrance in 1. aerogel plane)
This is a class to store ARICH likelihoods in the datastore.
float getDetPhot() const
Return number of detected photons for a given particle.
float getLogL(const Const::ChargedStable &part) const
Return log likelihood for a given particle.
float getExpPhot(const Const::ChargedStable &part) const
Return number of expected photons for a given particle.
Datastore class that holds position and momentum information of tracks that hit ARICH.
const std::vector< ARICHPhoton > & getPhotons() const
Returns vector of ARICHPhoton's associated with track.
bool hitsWindow() const
Returns true if track hits HAPD window.
TVector3 getPosition() const
returns track position vector
TVector2 windowHitPosition() const
Get HAPD window hit position.
TVector3 getDirection() const
returns track direction vector
double getMomentum() const
returns track momentum
In the store you can park objects that have to be accessed by various modules.
Store one Ext hit as a ROOT object.
Class to store reconstructed particles.
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Accessor to arrays stored in the data store.
Type-safe access to single objects in the data store.
Class that bundles various TrackFitResults.
This module extends existing variablesToNtuple to append detailed arich information to candidates in ...
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.
Abstract base class for different kinds of events.
Structure of a flat ntuple.
A variable returning a floating-point value for a given Particle.