9#include <analysis/modules/ParticleMCDecayString/ParticleMCDecayStringModule.h>
11#include <analysis/dataobjects/Particle.h>
13#include <mdst/dataobjects/MCParticle.h>
15#include <framework/logging/Logger.h>
16#include <framework/pcore/ProcHandler.h>
17#include <framework/utilities/RootFileCreationManager.h>
22#include <boost/algorithm/string.hpp>
31 setDescription(
"Creates the Monte Carlo decay string of a Particle and its daughters. "
32 "The MC decay string of the particle is hashed and saved as a 32bit pattern in the extra info field decayHash of the particle. "
33 "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. "
34 "The mapping hash <-> MC decay string in saved in a TTree by this module. "
35 "The 32bit pattern must be saved as a float (because our extra info field, variable manager and ntuple output only supports float) "
36 "but they just represent 32 bits of a hash! "
37 "The MC decay string can also be stored in an analysis ROOT file using the MCDecayString NtupleTool. "
38 "Details on the MC decay string format can be found here: `MCDecayString`");
40 addParam(
"listName",
m_listName,
"Particles from these ParticleList are used as input.");
41 addParam(
"fileName",
m_fileName,
"Filename in which the hash strings are saved, if empty the strings are not saved",
43 addParam(
"treeName",
m_treeName,
"Tree name in which the hash strings are saved", std::string(
"hashtable"));
44 addParam(
"conciseString",
m_useConciseString,
"If set to true, the code will use a more concise format for the string.",
false);
45 addParam(
"identifiers",
m_identifiers,
"Identifiers used to identify particles in the concise format.",
46 std::string(
"abcdefghijklmnopqrstuvwxyz"));
64 B2WARNING(
"Could not create file " <<
m_fileName);
72 B2WARNING(
"Tree with this name already exists: " <<
m_fileName);
81 m_tree->get().SetBasketSize(
"*", 1600);
82 m_tree->get().SetCacheSize(100000);
93 for (
unsigned iParticle = 0; iParticle <
m_pList->getListSize(); ++iParticle) {
101 uint32_t decayHash =
m_hasher(decayString);
102 uint32_t decayHashExtended =
m_hasher(decayStringExtended);
104 uint64_t m_decayHashFull = decayHash;
105 m_decayHashFull <<= 32;
106 m_decayHashFull += decayHashExtended;
109 assert(
sizeof(
float) ==
sizeof(uint32_t));
115 convert bitconverter;
117 bitconverter.i = decayHash;
123 bitconverter.i = decayHashExtended;
130 particle->addRelationTo(stringWrapper);
133 auto it =
m_hashset->get().find(m_decayHashFull);
135 m_hashset->get().insert(m_decayHashFull);
150 TDirectory::TContext directoryGuard(
m_file.get());
153 const bool writeError =
m_file->TestBit(TFile::kWriteError);
156 B2FATAL(
"A write error occurred while saving '" <<
m_fileName <<
"', please check if enough disk space is available.");
166 if (mcPMother ==
nullptr) {
208 std::string output =
" ";
210 output += std::to_string(p->getPDGCode());
212 if (not isFSP(p->getPDGCode())) {
214 for (
auto daughter : p->getDaughters()) {
231 if (not isFSP(p->getPDGCode())) {
232 for (
auto& daughter : p->getDaughters()) {
244 if (mcPMatched ==
nullptr)
252 if (mcPMatched->
getPDG() == 10022)
253 return decayString +
" (Virtual gamma match)";
261 std::stringstream ss;
267 ss << mcPMother->
getPDG();
269 if (not isFSP(mcPMother->
getPDG())) {
283 std::vector<std::string> decayStrings;
284 boost::split(decayStrings,
string, boost::is_any_of(
"|"));
286 if (decayStrings.empty()) {
287 B2WARNING(
"ParticleMCDecayStringModule: unable to convert decay string to concise format.");
291 unsigned int nParticles(decayStrings.size() - 1);
293 B2WARNING(
"ParticleMCDecayStringModule: not enough identifiers have been specified to use the concise string format:"
294 << std::endl <<
"Number of particles in your decay mode = " << nParticles << std::endl
296 <<
"Standard format will be used instead.");
301 std::string mode(
"");
302 std::vector<int> caretPositions;
303 for (
auto& decayString : decayStrings) {
304 std::string thisString(decayString);
310 int caretPosition(thisString.find(
'^'));
311 caretPositions.push_back(caretPosition);
312 if (caretPosition > -1) {
313 decayString.erase(caretPosition, 1);
318 std::string theDecayString(
"");
319 for (
auto thisString : decayStrings) {
320 if (thisString == mode) {
continue;}
323 char finalChar(thisString.back());
324 if (finalChar !=
' ') {thisString = thisString +
" ";}
326 if (
" (No match) " != thisString) {
327 if (
"" == theDecayString) {
328 theDecayString = thisString;
330 if (theDecayString != thisString) {
338 std::string modifiedString(theDecayString);
341 int nStrings(caretPositions.size());
342 for (
int iString(0); iString < nStrings; ++iString) {
344 int insertPosition(caretPositions.at(iString));
345 if (insertPosition > -1) {
346 for (
int jString(0); jString < iString; ++jString) {
347 if (caretPositions.at(jString) > -1 && caretPositions.at(jString) <= caretPositions.at(iString)) {
351 modifiedString.insert(insertPosition, identifier);
355 modifiedString = mode +
"|" + modifiedString;
358 bool noMatchStringAdded(
false);
359 for (
int iString(0); iString < nStrings; ++iString) {
360 int insertPosition(caretPositions.at(iString));
361 if (-1 == insertPosition) {
362 if (!noMatchStringAdded) {
363 modifiedString +=
" | No match: ";
364 noMatchStringAdded =
true;
370 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.