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. ");
39 addParam(
"listName",
m_listName,
"Particles from these ParticleList are used as input.");
40 addParam(
"fileName",
m_fileName,
"Filename in which the hash strings are saved, if empty the strings are not saved",
42 addParam(
"treeName",
m_treeName,
"Tree name in which the hash strings are saved", std::string(
"hashtable"));
43 addParam(
"conciseString",
m_useConciseString,
"If set to true, the code will use a more concise format for the string.",
false);
44 addParam(
"identifiers",
m_identifiers,
"Identifiers used to identify particles in the concise format.",
45 std::string(
"abcdefghijklmnopqrstuvwxyz"));
63 B2WARNING(
"Could not create file " <<
m_fileName);
71 B2WARNING(
"Tree with this name already exists: " <<
m_fileName);
80 m_tree->get().SetBasketSize(
"*", 1600);
81 m_tree->get().SetCacheSize(100000);
92 for (
unsigned iParticle = 0; iParticle <
m_pList->getListSize(); ++iParticle) {
100 uint32_t decayHash =
m_hasher(decayString);
101 uint32_t decayHashExtended =
m_hasher(decayStringExtended);
103 uint64_t m_decayHashFull = decayHash;
104 m_decayHashFull <<= 32;
105 m_decayHashFull += decayHashExtended;
108 assert(
sizeof(
float) ==
sizeof(uint32_t));
114 convert bitconverter;
116 bitconverter.i = decayHash;
120 bitconverter.i = decayHashExtended;
130 auto it =
m_hashset->get().find(m_decayHashFull);
132 m_hashset->get().insert(m_decayHashFull);
147 TDirectory::TContext directoryGuard(
m_file.get());
150 const bool writeError =
m_file->TestBit(TFile::kWriteError);
153 B2FATAL(
"A write error occurred while saving '" <<
m_fileName <<
"', please check if enough disk space is available.");
163 if (mcPMother ==
nullptr) {
205 std::string output =
" ";
207 output += std::to_string(p->getPDGCode());
209 if (not isFSP(p->getPDGCode())) {
211 for (
const auto* daughter : p->getDaughters()) {
228 if (not isFSP(p->getPDGCode())) {
229 for (
const auto* daughter : p->getDaughters()) {
241 if (mcPMatched ==
nullptr)
249 if (mcPMatched->
getPDG() == 10022)
250 return decayString +
" (Virtual gamma match)";
258 std::stringstream ss;
264 ss << mcPMother->
getPDG();
266 if (not isFSP(mcPMother->
getPDG())) {
268 for (
const auto* daughter : mcPMother->
getDaughters()) {
280 std::vector<std::string> decayStrings;
281 boost::split(decayStrings,
string, boost::is_any_of(
"|"));
283 if (decayStrings.empty()) {
284 B2WARNING(
"ParticleMCDecayStringModule: unable to convert decay string to concise format.");
288 unsigned int nParticles(decayStrings.size() - 1);
290 B2WARNING(
"ParticleMCDecayStringModule: not enough identifiers have been specified to use the concise string format:"
291 << std::endl <<
"Number of particles in your decay mode = " << nParticles << std::endl
293 <<
"Standard format will be used instead.");
298 std::string mode(
"");
299 std::vector<int> caretPositions;
300 for (
auto& decayString : decayStrings) {
301 std::string thisString(decayString);
307 int caretPosition(thisString.find(
'^'));
308 caretPositions.push_back(caretPosition);
309 if (caretPosition > -1) {
310 decayString.erase(caretPosition, 1);
315 std::string theDecayString(
"");
316 for (
auto thisString : decayStrings) {
317 if (thisString == mode) {
continue;}
320 char finalChar(thisString.back());
321 if (finalChar !=
' ') {thisString = thisString +
" ";}
323 if (
" (No match) " != thisString) {
324 if (
"" == theDecayString) {
325 theDecayString = thisString;
327 if (theDecayString != thisString) {
335 std::string modifiedString(theDecayString);
338 int nStrings(caretPositions.size());
339 for (
int iString(0); iString < nStrings; ++iString) {
341 int insertPosition(caretPositions.at(iString));
342 if (insertPosition > -1) {
343 for (
int jString(0); jString < iString; ++jString) {
344 if (caretPositions.at(jString) > -1 && caretPositions.at(jString) <= caretPositions.at(iString)) {
348 modifiedString.insert(insertPosition, identifier);
352 modifiedString = mode +
"|" + modifiedString;
355 bool noMatchStringAdded(
false);
356 for (
int iString(0); iString < nStrings; ++iString) {
357 int insertPosition(caretPositions.at(iString));
358 if (-1 == insertPosition) {
359 if (!noMatchStringAdded) {
360 modifiedString +=
" | No match: ";
361 noMatchStringAdded =
true;
367 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.
static 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.
static 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.
static std::string buildMCDecayString(const MCParticle *mcPMother, const MCParticle *mcPMatched)
return decay string for mcPMother, highlight mcPMatched.
static 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.
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
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.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to 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.
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(const 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.