10#include <analysis/modules/BremsCorrection/BremsFinderModule.h>
13#include <framework/gearbox/Const.h>
14#include <framework/logging/Logger.h>
15#include <framework/datastore/RelationArray.h>
16#include <framework/datastore/RelationVector.h>
19#include <mdst/dataobjects/Track.h>
20#include <mdst/dataobjects/ECLCluster.h>
23#include <analysis/DecayDescriptor/ParticleListName.h>
24#include <analysis/DecayDescriptor/DecayDescriptor.h>
27#include <analysis/variables/ECLVariables.h>
31#include <TMatrixFSym.h>
51This module copies each particle in the ``inputList`` to the ``outputList`` and uses
52the results of the **eclTrackBremFinder** module to look for possible bremsstrahlung photons; if these
53photons exist, it adds their four momentum to the particle in the ``outputList``.
54It also adds the original particle and these photons as daughters of the new, corrected particle.
55Track and PID information of the original particle are copied onto the new one to facilitate their access
56in the analysis scripts.
58The **eclTrackBremFinder** module uses the lepton track PXD and SVD hits and extrapolates them to the ECL;
59then looks for ECL clusters with energies between 0.02 and 1 times the track energy and without associated
60tracks, and checks if the normalized distance between each of these clusters
61and the extrapolated hit is smaller than 0.05. If it is, a *Bremsstrahlung* weighted relation
62between said cluster and the track is established. The weight is determined as
66 \text{max}\left(\frac{\left|\phi_{\text{cluster}}-\phi_{\text{hit}}\right|}{\Delta\phi_{\text{cluster}}+\Delta\phi_{\text{hit}}}, \, \frac{\left|\theta_{\text{cluster}}-\theta_{\text{hit}}\right|}{\Delta\theta_{\text{cluster}}+\Delta\theta_{\text{hit}}}\right)
68where :math:`\phi_i` and :math:`\theta_i` are the azimuthal and polar angles of the ECL cluster and the
69extrapolated hit, and :math:`\Delta x` represents the uncertainty of the value :math:`x`. The details of the
70calculation of these quantities are `here`_. By default, only relations with a weight smaller than 3.0 are stored.
71The user can further reduce the maximally allowed value of this weight to remove unwanted photons from the
72bremsstrahlung correction.
74This module looks for photons in the ``gammaList`` whose clusters have a *Bremsstrahlung* relation with the track
75of one of the particles in the ``inputList``, and adds their 4-momentum to the particle's one. It also stores the value
76of each relation weight as ``extraInfo`` of the corrected particle, under the name ``"bremsWeightWithPhotonN"``, where
77N is the index of the photon as daughter of the corrected particle; thus ``"bremsWeightWithPhoton0"`` gives the weight
78of the Bremsstrahlung relation between the new, corrected particle, and the first photon daughter.
81 Even in the event of no bremsstrahlung photons found, a new particle is still created, and the original one is still
82 added as its daughter.
85 Studies have shown that the requirements that the energy of the photon must be between 0.2 and 1 times the track energy and
86 that only track-photon relations with a weight below three are considered, are too tight. Until these are relaxed and a new
87 processing is done (MC15 and proc 13) it might be better to use the alternative `BelleBremRecovery` module.
90 `eclTrackBremFinder module`_
92.. _eclTrackBremFinder module: https://gitlab.desy.de/belle2/software/basf2/-/tree/main/ecl/modules/eclTrackBremFinder
93.. _here: https://gitlab.desy.de/belle2/software/basf2/-/tree/main/ecl/modules/eclTrackBremFinder/src/BremFindingMatchCompute.cc
100 R
"DOC(The initial particle list name containing the particles to correct. *It should already exist* and *the particles must have an associated track.*)DOC");
102 R
"DOC(The photon list containing the preselected bremsstrahlung candidates. *It should already exist* and *the particles in the list must be photons*)DOC");
104 "The maximum value of the relation weight between a bremsstrahlung cluster and a particle track",
109 R
"DOC(If true, each brems candidate is used to correct maximum 1 particle (the one with the lowest relation weight among all in the ``inputList``).)DOC",
112 R
"DOC(If true, the output ``ParticleList`` will be saved by `RootOutput`. If false, it will be ignored when writing the file.)DOC",
127 B2ERROR(
"[BremsFinderModule] Invalid particle list. the particles in " <<
m_inputListName <<
" should have an associated track.");
137 B2ERROR(
"[BremsFinderModule] Invalid particle list. the particles in " <<
m_gammaListName <<
" should be photons!");
143 B2ERROR(
"[BremsFinderModule] Input and output particle list names are the same: " <<
m_inputListName);
145 B2ERROR(
"[BremsFinderModule] The input and output particle list correspond to different particles: " <<
m_inputListName <<
" --> "
173 const unsigned int nGamma =
m_gammaList->getListSize();
176 const unsigned int nLep =
m_inputList->getListSize();
178 const std::string relationName =
"Bremsstrahlung";
182 for (
unsigned n = 0; n < nGamma; n++) {
192 unsigned bestMatchIndex = 0;
193 unsigned trkIndex = 0;
195 for (
auto trk = relatedTracks.
begin(); trk != relatedTracks.
end(); trk++, trkIndex++) {
197 for (
unsigned i = 0; i < nLep; i++) {
199 auto leptonTrack = lepton->
getTrack();
201 if (leptonTrack->getArrayIndex() == trk->getArrayIndex()) {
202 double weight = relatedTracks.
weight(trkIndex);
203 if (weight < bestWeight) {
206 bestMatchIndex = trk->getArrayIndex();
219 for (
unsigned i = 0; i < nLep; i++) {
228 std::vector<std::pair <double, Particle*> > selectedGammas;
231 for (
auto bremCluster = bremClusters.
begin(); bremCluster != bremClusters.
end(); bremCluster++, j++) {
232 double weight = bremClusters.
weight(j);
236 for (
unsigned k = 0; k < nGamma; k++) {
241 if (bremCluster->getUniqueClusterId() == cluster->getUniqueClusterId()) {
243 if (track->getArrayIndex() ==
static_cast<int>
245 selectedGammas.push_back(std::make_pair(weight, gamma));
247 selectedGammas.push_back(std::make_pair(weight, gamma));
256 ROOT::Math::PxPyPzEVector new4Vec = lepton->
get4Vector();
259 std::sort(selectedGammas.begin(), selectedGammas.end());
262 for (
auto const& bremsPair : selectedGammas) {
264 new4Vec += g->get4Vector();
270 track->getArrayIndex());
276 TMatrixFSym corLepMatrix(lepErrorMatrix);
278 double bremsGammaEnergySum = 0.0;
281 for (
auto const& bremsPair : selectedGammas) {
283 Particle* bremsGamma = bremsPair.second;
284 std::string extraInfoName =
"bremsWeightWithPhoton" + std::to_string(photonIndex);
285 correctedLepton.
addExtraInfo(extraInfoName, bremsPair.first);
287 bremsGammaEnergySum += Variable::eclClusterE(bremsGamma);
290 for (
int irow = 0; irow <= 3; irow++) {
291 for (
int icol = irow; icol <= 3; icol++) corLepMatrix(irow, icol) += gammaErrorMatrix(irow, icol);
294 B2DEBUG(10,
"[BremsFinderModule] Found a bremsstrahlung gamma and added its 4-vector to the charged particle");
303 correctedLepton.
addExtraInfo(
"bremsCorrected",
float(selectedGammas.size() > 0));
304 correctedLepton.
addExtraInfo(
"bremsCorrectedPhotonEnergy", bremsGammaEnergySum);
virtual void initialize() override
Use this to initialize resources or memory your module needs.
double m_maximumAcceptance
photons whose clusters have relation weights higher than this will not be used for bremsstrahlung cor...
std::string m_gammaListName
input gamma list name
virtual void event() override
Called once for each event.
bool m_addMultiplePhotons
In case there is more than one brems photon, use only the best one (based on the weight of the relati...
StoreObjPtr< ParticleList > m_outputAntiList
StoreObjptr for output antiparticlelist.
StoreArray< Particle > m_particles
StoreArray of Particle objects.
StoreObjPtr< ParticleList > m_outputList
StoreObjptr for output particlelist.
StoreArray< PIDLikelihood > m_pidlikelihoods
StoreArray of PIDLikelihood objects.
StoreObjPtr< ParticleList > m_inputList
StoreObjptr for input charged particle list.
StoreObjPtr< ParticleList > m_gammaList
StoreObjptr for gamma list.
bool m_writeOut
Write the output particle list in the final file?
StoreArray< MCParticle > m_mcParticles
StoreArray of MCParticle objects.
bool m_usePhotonOnlyOnce
Each brems photon can be used to correct only one particle (the one with the smallest relation weight...
int m_pdgCode
PDG code of the particle to be corrected.
std::string m_outputAntiListName
output anti-particle list name
std::string m_inputListName
input particle list name
BremsFinderModule()
Constructor, for setting module description and parameters.
std::string m_outputListName
output particle list name
static const ParticleSet chargedStableSet
set of charged stable particles
static const ParticleType invalidParticle
Invalid particle, used internally.
static const ParticleType photon
photon particle
EStoreFlags
Flags describing behaviours of objects etc.
@ c_WriteOut
Object/array should be saved by output modules.
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
int getPDGCode() const
Return PDG code.
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
const DecayDescriptorParticle * getMother() const
return mother.
A Class to store the Monte Carlo particle information.
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...
Class to collect log likelihoods from TOP, ARICH, dEdx, ECL and KLM aimed for output to mdst includes...
Class to store reconstructed particles.
const Track * getTrack() const
Returns the pointer to the Track object that was used to create this Particle (ParticleType == c_Trac...
void appendDaughter(const Particle *daughter, const bool updateType=true, const int daughterProperty=c_Ordinary)
Appends index of daughter to daughters index array.
const ECLCluster * getECLCluster() const
Returns the pointer to the ECLCluster object that was used to create this Particle (if ParticleType =...
void setVertex(const ROOT::Math::XYZVector &vertex)
Sets position (decay vertex)
double getPValue() const
Returns chi^2 probability of fit if done or -1.
ROOT::Math::XYZVector getVertex() const
Returns vertex position (POCA for charged, IP for neutral FS particles)
bool hasExtraInfo(const std::string &name) const
Return whether the extra info with the given name is set.
const PIDLikelihood * getPIDLikelihood() const
Returns the pointer to the PIDLikelihood object that is related to the Track, which was used to creat...
int getPDGCode(void) const
Returns PDG code.
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
void setMomentumVertexErrorMatrix(const TMatrixFSym &errMatrix)
Sets 7x7 error matrix.
void setPValue(double pValue)
Sets chi^2 probability of fit.
@ c_Flavored
Is either particle or antiparticle.
TMatrixFSym getMomentumVertexErrorMatrix() const
Returns 7x7 error matrix.
double getExtraInfo(const std::string &name) const
Return given value if set.
Low-level class to create/modify relations between StoreArrays.
Class for type safe access to objects that are referred to in relations.
iterator end()
Return iterator to last entry +1.
iterator begin()
Return iterator to first entry.
float weight(int index) const
Get weight with index.
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).
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
T * appendNew()
Construct a new T object at the end of the array.
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.
Class that bundles various TrackFitResults.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
std::string antiParticleListName(const std::string &listName)
Returns name of anti-particle-list corresponding to listName.
Abstract base class for different kinds of events.