9#include <analysis/modules/ParticleMCDecayString/ParticleMCDecayStringModule.h>
11#include <mdst/dataobjects/MCParticle.h>
13#include <framework/logging/Logger.h>
14#include <framework/pcore/ProcHandler.h>
15#include <framework/utilities/RootFileCreationManager.h>
20#include <boost/algorithm/string.hpp>
27 DataStore::c_Persistent), m_decayHash(0.0), m_decayHashExtended(0.0)
29 setDescription(
"Creates the Monte Carlo decay string of a Particle and its daughters. "
30 "The MC decay string of the particle is hashed and saved as a 32bit pattern in the extra info field decayHash of the particle. "
31 "The MC decay string of the particle + its daughters is hashed as well and saved as another 32bit pattern in the extra info field decayHashExtended of the particle. "
32 "The mapping hash <-> MC decay string in saved in a TTree by this module. "
33 "The 32bit pattern must be saved as a float (because our extra info field, variable manager and ntuple output only supports float) "
34 "but they just represent 32 bits of a hash! "
35 "The MC decay string can also be stored in an analysis ROOT file using the MCDecayString NtupleTool. "
36 "Details on the MC decay string format can be found here: `MCDecayString`");
38 addParam(
"listName",
m_listName,
"Particles from these ParticleList are used as input.");
39 addParam(
"fileName",
m_fileName,
"Filename in which the hash strings are saved, if empty the strings are not saved",
41 addParam(
"treeName",
m_treeName,
"Tree name in which the hash strings are saved", std::string(
"hashtable"));
42 addParam(
"conciseString",
m_useConciseString,
"If set to true, the code will use a more concise format for the string.",
false);
43 addParam(
"identifiers",
m_identifiers,
"Identifiers used to identify particles in the concise format.",
44 std::string(
"abcdefghijklmnopqrstuvwxyz"));
62 B2WARNING(
"Could not create file " <<
m_fileName);
70 B2WARNING(
"Tree with this name already exists: " <<
m_fileName);
79 m_tree->get().SetBasketSize(
"*", 1600);
80 m_tree->get().SetCacheSize(100000);
91 for (
unsigned iParticle = 0; iParticle <
m_pList->getListSize(); ++iParticle) {
99 uint32_t decayHash =
m_hasher(decayString);
100 uint32_t decayHashExtended =
m_hasher(decayStringExtended);
102 uint64_t m_decayHashFull = decayHash;
103 m_decayHashFull <<= 32;
104 m_decayHashFull += decayHashExtended;
107 assert(
sizeof(
float) ==
sizeof(uint32_t));
113 convert bitconverter;
115 bitconverter.i = decayHash;
121 bitconverter.i = decayHashExtended;
128 particle->addRelationTo(stringWrapper);
131 auto it =
m_hashset->get().find(m_decayHashFull);
133 m_hashset->get().insert(m_decayHashFull);
148 TDirectory::TContext directoryGuard(
m_file.get());
151 const bool writeError =
m_file->TestBit(TFile::kWriteError);
154 B2FATAL(
"A write error occurred while saving '" <<
m_fileName <<
"', please check if enough disk space is available.");
164 if (mcPMother ==
nullptr) {
206 std::string output =
" ";
208 output += std::to_string(p->getPDGCode());
210 if (not isFSP(p->getPDGCode())) {
212 for (
auto daughter : p->getDaughters()) {
229 if (not isFSP(p->getPDGCode())) {
230 for (
auto& daughter : p->getDaughters()) {
242 if (mcPMatched ==
nullptr)
250 if (mcPMatched->
getPDG() == 10022)
251 return decayString +
" (Virtual gamma match)";
259 std::stringstream ss;
265 ss << mcPMother->
getPDG();
267 if (not isFSP(mcPMother->
getPDG())) {
281 std::vector<std::string> decayStrings;
282 boost::split(decayStrings,
string, boost::is_any_of(
"|"));
284 if (decayStrings.empty()) {
285 B2WARNING(
"ParticleMCDecayStringModule: unable to convert decay string to concise format.");
289 unsigned int nParticles(decayStrings.size() - 1);
291 B2WARNING(
"ParticleMCDecayStringModule: not enough identifiers have been specified to use the concise string format:"
292 << std::endl <<
"Number of particles in your decay mode = " << nParticles << std::endl
294 <<
"Standard format will be used instead.");
299 std::string mode(
"");
300 std::vector<int> caretPositions;
301 for (
auto& decayString : decayStrings) {
302 std::string thisString(decayString);
308 int caretPosition(thisString.find(
'^'));
309 caretPositions.push_back(caretPosition);
310 if (caretPosition > -1) {
311 decayString.erase(caretPosition, 1);
316 std::string theDecayString(
"");
317 for (
auto thisString : decayStrings) {
318 if (thisString == mode) {
continue;}
321 char finalChar(thisString.back());
322 if (finalChar !=
' ') {thisString = thisString +
" ";}
324 if (
" (No match) " != thisString) {
325 if (
"" == theDecayString) {
326 theDecayString = thisString;
328 if (theDecayString != thisString) {
336 std::string modifiedString(theDecayString);
339 int nStrings(caretPositions.size());
340 for (
int iString(0); iString < nStrings; ++iString) {
342 int insertPosition(caretPositions.at(iString));
343 if (insertPosition > -1) {
344 for (
int jString(0); jString < iString; ++jString) {
345 if (caretPositions.at(jString) > -1 && caretPositions.at(jString) <= caretPositions.at(iString)) {
349 modifiedString.insert(insertPosition, identifier);
353 modifiedString = mode +
"|" + modifiedString;
356 bool noMatchStringAdded(
false);
357 for (
int iString(0); iString < nStrings; ++iString) {
358 int insertPosition(caretPositions.at(iString));
359 if (-1 == insertPosition) {
360 if (!noMatchStringAdded) {
361 modifiedString +=
" | No match: ";
362 noMatchStringAdded =
true;
368 string = modifiedString;
In the store you can park objects that have to be accessed by various modules.
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
A Class to store the Monte Carlo particle information.
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
int getPDG() const
Return PDG code of particle.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
@ c_TerminateInAllProcesses
When using parallel processing, call this module's terminate() function in all processes().
float m_decayHash
Decay hash -> The hash of the decay string of the mother particle.
std::string getDecayStringFromParticle(const Particle *p)
get decay string of particle
virtual void initialize() override
Initialize the module.
const std::string c_ExtraInfoName
Name of the extraInfo, which is stored in each Particle.
virtual void event() override
Called for each event.
std::string m_decayString
The complete decay string.
std::string m_listName
Name of the particle list.
virtual void terminate() override
Terminate modules.
std::string m_fileName
Filename in which the hash strings are saved, if empty the strings are not saved.
std::string getMCDecayStringFromMCParticle(const MCParticle *mcPMatched)
get mc decay string from mc particle
std::hash< std::string > m_hasher
Hash function.
ParticleMCDecayStringModule()
Constructor.
bool m_useConciseString
Switch to use concise format for the extended string.
StoreObjPtr< RootMergeable< TTree > > m_tree
ROOT TNtuple containing the saved hashes and strings.
std::shared_ptr< TFile > m_file
ROOT file to store the hashes and strings.
const std::string c_ExtraInfoNameExtended
Name of the extraInfo, which is stored in each Particle.
StoreObjPtr< SetMergeable< std::unordered_set< uint64_t > > > m_hashset
Mergeable unordered set containing the encountered hashes.
StoreArray< StringWrapper > m_stringWrapperArray
StoreArray of StringWrappers.
std::string m_treeName
Tree name in which the hash strings are saved.
std::string m_identifiers
Characters used to identify particles in the concise decay string format (default: alphabet).
void convertToConciseString(std::string &string)
Convert the extended string to a more concise format.
std::string buildMCDecayString(const MCParticle *mcPMother, const MCParticle *mcPMatched)
return decay string for mcPMother, highlight mcPMatched.
const MCParticle * getInitialParticle(const MCParticle *mcP)
search from mcP upwards for a particle that matches specified mother PDG codes.
float m_decayHashExtended
Extended decay hash -> The hash of the decay string of all daughter particles.
std::string getMCDecayStringFromParticle(const Particle *p)
get mc decay string from particle
StoreObjPtr< ParticleList > m_pList
input particle list
std::string getDecayString(const Particle &p)
get the decay string for p.
Class to store reconstructed particles.
static bool isOutputProcess()
Return true if the process is an output process.
static bool parallelProcessingUsed()
Returns true if multiple processes have been spawned, false in single-core mode.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Accessor to arrays stored in the data store.
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
This class is a wrapper for strings, such as MCDecayStrings, to allow them to be associated with part...
void setString(const std::string &inputstring)
Set string.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
std::shared_ptr< TFile > getFile(std::string, bool ignoreErrors=false)
Get a file with a specific name, if is does not exist it will be created.
static RootFileCreationManager & getInstance()
Interface for the FileManager.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
MCParticle * getMother() const
Returns a pointer to the mother particle.
Abstract base class for different kinds of events.