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>
46 BremsFinderModule::BremsFinderModule() :
51 This module copies each particle in the ``inputList`` to the ``outputList`` and uses
52 the results of the **eclTrackBremFinder** module to look for possible bremsstrahlung photons; if these
53 photons exist, it adds their four momentum to the particle in the ``outputList``.
54 It also adds the original particle and these photons as daughters of the new, corrected particle.
55 Track and PID information of the original particle are copied onto the new one to facilitate their access
56 in the analysis scripts.
58 The **eclTrackBremFinder** module uses the lepton track PXD and SVD hits and extrapolates them to the ECL;
59 then looks for ECL clusters with energies between 0.02 and 1 times the track energy and without associated
60 tracks, and checks if the normalized distance between each of these clusters
61 and the extrapolated hit is smaller than 0.05. If it is, a *Bremsstrahlung* weighted relation
62 between 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)
68 where :math:`\phi_i` and :math:`\theta_i` are the azimuthal and polar angles of the ECL cluster and the
69 extrapolated hit, and :math:`\Delta x` represents the uncertainty of the value :math:`x`. The details of the
70 calculation of these quantities are `here`_. By default, only relations with a weight smaller than 3.0 are stored.
71 The user can further reduce the maximally allowed value of this weight to remove unwanted photons from the
72 bremsstrahlung correction.
74 This module looks for photons in the ``gammaList`` whose clusters have a *Bremsstrahlung* relation with the track
75 of one of the particles in the ``inputList``, and adds their 4-momentum to the particle's one. It also stores the value
76 of each relation weight as ``extraInfo`` of the corrected particle, under the name ``"bremsWeightWithPhotonN"``, where
77 N is the index of the photon as daughter of the corrected particle; thus ``"bremsWeightWithPhoton0"`` gives the weight
78 of 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)DOC");
99 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");
101 R
"DOC(The photon list containing the preselected bremsstrahlung candidates. *It should already exist* and *the particles in the list must be photons*)DOC");
103 "The maximum value of the relation weight between a bremsstrahlung cluster and a particle track",
108 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",
111 R
"DOC(If true, the output ``ParticleList`` will be saved by `RootOutput`. If false, it will be ignored when writing the file.)DOC",
126 B2ERROR(
"[BremsFinderModule] Invalid particle list. the particles in " <<
m_inputListName <<
" should have an associated track.");
136 B2ERROR(
"[BremsFinderModule] Invalid particle list. the particles in " <<
m_gammaListName <<
" should be photons!");
142 B2ERROR(
"[BremsFinderModule] Input and output particle list names are the same: " <<
m_inputListName);
144 B2ERROR(
"[BremsFinderModule] The input and output particle list correspond to different particles: " <<
m_inputListName <<
" --> "
172 const unsigned int nGamma =
m_gammaList->getListSize();
175 const unsigned int nLep =
m_inputList->getListSize();
177 const std::string relationName =
"Bremsstrahlung";
181 for (
unsigned n = 0; n < nGamma; n++) {
185 if (gamma->hasExtraInfo(
"bestMatchIndex"))
continue;
187 auto cluster = gamma->getECLCluster();
191 unsigned bestMatchIndex = 0;
192 unsigned trkIndex = 0;
194 for (
auto trk = relatedTracks.
begin(); trk != relatedTracks.
end(); trk++, trkIndex++) {
196 for (
unsigned i = 0; i < nLep; i++) {
198 auto leptonTrack = lepton->
getTrack();
200 if (leptonTrack->getArrayIndex() == trk->getArrayIndex()) {
201 double weight = relatedTracks.
weight(trkIndex);
202 if (weight < bestWeight) {
205 bestMatchIndex = trk->getArrayIndex();
212 gamma->addExtraInfo(
"bestMatchIndex", bestMatchIndex);
218 for (
unsigned i = 0; i < nLep; i++) {
227 std::vector<std::pair <double, Particle*> > selectedGammas;
230 for (
auto bremCluster = bremClusters.
begin(); bremCluster != bremClusters.
end(); bremCluster++, j++) {
231 double weight = bremClusters.
weight(j);
235 for (
unsigned k = 0; k < nGamma; k++) {
238 auto cluster = gamma->getECLCluster();
240 if (bremCluster->getClusterId() == cluster->getClusterId()) {
242 if (track->getArrayIndex() ==
static_cast<int>
243 (gamma->getExtraInfo(
"bestMatchIndex")))
244 selectedGammas.push_back(std::make_pair(weight, gamma));
246 selectedGammas.push_back(std::make_pair(weight, gamma));
255 ROOT::Math::PxPyPzEVector new4Vec = lepton->
get4Vector();
258 std::sort(selectedGammas.begin(), selectedGammas.end());
261 for (
auto const& bremsPair : selectedGammas) {
263 new4Vec += g->get4Vector();
268 Particle correctedLepton(new4Vec, lepton->
getPDGCode(), Particle::EFlavorType::c_Flavored, Particle::c_Track,
269 track->getArrayIndex());
275 TMatrixFSym corLepMatrix(lepErrorMatrix);
277 double bremsGammaEnergySum = 0.0;
280 for (
auto const& bremsPair : selectedGammas) {
282 Particle* bremsGamma = bremsPair.second;
283 std::string extraInfoName =
"bremsWeightWithPhoton" + std::to_string(photonIndex);
284 correctedLepton.
addExtraInfo(extraInfoName, bremsPair.first);
286 bremsGammaEnergySum += Variable::eclClusterE(bremsGamma);
289 for (
int irow = 0; irow <= 3; irow++) {
290 for (
int icol = irow; icol <= 3; icol++) corLepMatrix(irow, icol) += gammaErrorMatrix(irow, icol);
293 B2DEBUG(10,
"[BremsFinderModule] Found a bremsstrahlung gamma and added its 4-vector to the charged particle");
302 correctedLepton.
addExtraInfo(
"bremsCorrected",
float(selectedGammas.size() > 0));
303 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
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.
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)
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.
TMatrixFSym getMomentumVertexErrorMatrix() const
Returns 7x7 error matrix.
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.
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.