Belle II Software development
BtubeCreatorModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <analysis/modules/BtubeCreator/BtubeCreatorModule.h>
10
11// framework aux
12#include <framework/gearbox/Unit.h>
13#include <framework/gearbox/Const.h>
14#include <framework/logging/Logger.h>
15
16// dataobjects
17#include <analysis/dataobjects/Particle.h>
18#include <analysis/DecayDescriptor/ParticleListName.h>
19
20// utilities
21#include <analysis/utility/PCmsLabTransform.h>
22#include <analysis/utility/ParticleCopy.h>
23
24// Magnetic field
25#include <framework/geometry/BFieldManager.h>
26
27#include <TMath.h>
28#include <Eigen/Core>
29
30using namespace std;
31using namespace Belle2;
32
33//-----------------------------------------------------------------
34// Register the Module
35//-----------------------------------------------------------------
36REG_MODULE(BtubeCreator);
37
38//-----------------------------------------------------------------
39// Implementation
40//-----------------------------------------------------------------
41
43 m_Bfield(0)
44{
45 // Set module properties
46 setDescription("BtubeCreator : This module creates Btube object, an object geometrically similar to a very long ellipsoid along a particular direction and can be used as a constraint in vertexing B particles. Upsilon4S decays to two Bs. the user selects one B with a ^ in decaystring. The order of daughters in reconstructdecay of Upsilon4S and this decaystring should be same. Using selected B as reference, the module calculates the direction in which the other B should fly and constructs a Btube object along that direction. In semi-leptonic analyses, the selected B is usually the fully reconstructed one, while for time dependent studies, the selected B is usually signal B which can be partially reconstructed");
48
49 // Parameter definitions
50 addParam("listName", m_listName, "name of mother particle list", string(""));
51 addParam("confidenceLevel", m_confidenceLevel, "Confidence level to accept the fit.", 0.001);
52 addParam("decayString", m_decayString,
53 "decay string of the mother particle, the selected daughter specifies which daughter will be used as reference to create Btube",
54 string(""));
55 addParam("associateBtubeToBselected", m_associateBtubeToBselected,
56 "whether to associate the Btube with the selected B",
57 false);
58 addParam("verbosity", m_verbose, "print statements", true);
59}
60
62{
63
64 m_plist.isRequired(m_listName);
65
66 // magnetic field
67 m_Bfield = BFieldManager::getFieldInTesla(ROOT::Math::XYZVector(0, 0, 0)).Z();
68
69 m_BeamSpotCenter = m_beamSpotDB->getIPPosition();
70 m_beamSpotCov.ResizeTo(3, 3);
71 m_beamSpotCov = m_beamSpotDB->getCovVertex();
72 B2INFO("BtubeCreator : magnetic field = " << m_Bfield);
73
74 m_tubeArray.registerInDataStore();
76
78 if (!valid)
79 B2ERROR("BtubeCreatorModule: invalid decay string" << m_decayString);
80 int nProducts = m_decaydescriptor.getNDaughters();
81 if (nProducts != 2)
82 B2ERROR("BtubeCreatorModule: decay string should contain only two daughters");
83}
84
86{
88
89 std::vector<unsigned int> toRemove;
90 unsigned int n = m_plist->getListSize();
91
92 for (unsigned i = 0; i < n; i++) {
93 Particle* particle = m_plist->getParticle(i);
94
95 std::vector<Particle*> daughtervec = particle->getDaughters();
96 std::vector<const Particle*> selParticles = m_decaydescriptor.getSelectionParticles(particle);
97 if (selParticles.size() > 1) {
98 B2FATAL("Please select only one daughter which will be used as reference to create Btube");
99 }
100
101 int selectindex = 1;
102 if ((daughtervec.at(0))->getArrayIndex() == (selParticles.at(0))->getArrayIndex()) selectindex = 0 ;
103
104 Particle* tubecreatorB = const_cast<Particle*>(particle->getDaughter(selectindex));
105 Particle* otherB = const_cast<Particle*>(particle->getDaughter(1 - selectindex));
106
107 if ((tubecreatorB->getVertexErrorMatrix()(2, 2)) == 0.0) {
108 B2FATAL("Please perform a vertex fit of the selected B before calling this module");
109 }
110
111 //make a copy of tubecreatorB so as not to modify the original object
112
113 Particle* tubecreatorBCopy = ParticleCopy::copyParticle(tubecreatorB);
114
115 if (m_verbose) {
116 B2DEBUG(10, "tubecreator B decay vertex: ");
117 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex().X() << "," << std::fixed <<
118 std::setprecision(
119 20) << tubecreatorBCopy->getVertex().Y() << "," << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex().Z() << "}");
120 }
121
122 bool ok0 = doVertexFit(tubecreatorBCopy);
123
124 if (ok0) {
125 if (tubecreatorBCopy->getPValue() < m_confidenceLevel) {
126 toRemove.push_back(particle->getArrayIndex());
127 } else {
128 particle->setVertex(tubecreatorBCopy->getVertex());
129 particle->setMomentumVertexErrorMatrix(tubecreatorBCopy->getMomentumVertexErrorMatrix());
130
131 tubecreatorB->writeExtraInfo("prod_vtx_x", tubecreatorBCopy->getVertex().X());
132 tubecreatorB->writeExtraInfo("prod_vtx_y", tubecreatorBCopy->getVertex().Y());
133 tubecreatorB->writeExtraInfo("prod_vtx_z", tubecreatorBCopy->getVertex().Z());
134 tubecreatorB->writeExtraInfo("prod_vtx_cov00", tubecreatorBCopy->getVertexErrorMatrix()(0, 0));
135 tubecreatorB->writeExtraInfo("prod_vtx_cov01", tubecreatorBCopy->getVertexErrorMatrix()(0, 1));
136 tubecreatorB->writeExtraInfo("prod_vtx_cov02", tubecreatorBCopy->getVertexErrorMatrix()(0, 2));
137 tubecreatorB->writeExtraInfo("prod_vtx_cov10", tubecreatorBCopy->getVertexErrorMatrix()(1, 0));
138 tubecreatorB->writeExtraInfo("prod_vtx_cov11", tubecreatorBCopy->getVertexErrorMatrix()(1, 1));
139 tubecreatorB->writeExtraInfo("prod_vtx_cov12", tubecreatorBCopy->getVertexErrorMatrix()(1, 2));
140 tubecreatorB->writeExtraInfo("prod_vtx_cov20", tubecreatorBCopy->getVertexErrorMatrix()(2, 0));
141 tubecreatorB->writeExtraInfo("prod_vtx_cov21", tubecreatorBCopy->getVertexErrorMatrix()(2, 1));
142 tubecreatorB->writeExtraInfo("prod_vtx_cov22", tubecreatorBCopy->getVertexErrorMatrix()(2, 2));
143
144 tubecreatorB->writeExtraInfo("Px_after_avf", (tubecreatorBCopy->get4Vector()).Px());
145 tubecreatorB->writeExtraInfo("Py_after_avf", (tubecreatorBCopy->get4Vector()).Py());
146 tubecreatorB->writeExtraInfo("Pz_after_avf", (tubecreatorBCopy->get4Vector()).Pz());
147 tubecreatorB->writeExtraInfo("E_after_avf", (tubecreatorBCopy->get4Vector()).E());
148
149 Eigen::Matrix<double, 3, 1> tubecreatorBOriginpos(tubecreatorBCopy->getVertex().X(), tubecreatorBCopy->getVertex().Y(),
150 tubecreatorBCopy->getVertex().Z());
151 ROOT::Math::PxPyPzEVector v4Final = tubecreatorBCopy->get4Vector();
153 ROOT::Math::PxPyPzEVector vec = T.rotateLabToCms() * v4Final;
154 ROOT::Math::PxPyPzEVector vecNew(-1 * vec.Px(), -1 * vec.Py(), -1 * vec.Pz(), vec.E());
155 ROOT::Math::PxPyPzEVector v4FinalNew = T.rotateCmsToLab() * vecNew;
156
157 if (m_verbose) {
158 B2DEBUG(10, "beamspot center :");
159 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << m_BeamSpotCenter.X() << "," << std::fixed << std::setprecision(
160 20) << m_BeamSpotCenter.Y() << "," << std::fixed << std::setprecision(20) << m_BeamSpotCenter.Z() << "}");
161 B2DEBUG(10, "beamspot cov :");
162
163 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << m_beamSpotCov(0,
164 0) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(0,
165 1) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(0, 2) << "},");
166 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << m_beamSpotCov(1,
167 0) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(1,
168 1) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(1, 2) << "},");
169 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << m_beamSpotCov(2,
170 0) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(2,
171 1) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(2, 2) << "}");
172 }
173 TMatrixFSym pp = (tubecreatorBCopy->getMomentumErrorMatrix()).GetSub(0, 2, 0, 2, "S");
174 double pe = tubecreatorBCopy->getMomentumErrorMatrix()(2, 2);
175 TMatrixFSym pv = tubecreatorBCopy->getVertexErrorMatrix();
176
177 // start rotation
178
179 double theta = v4FinalNew.Theta();
180 double phi = v4FinalNew.Phi();
181
182 double st = TMath::Sin(theta);
183 double ct = TMath::Cos(theta);
184 double sp = TMath::Sin(phi);
185 double cp = TMath::Cos(phi);
186
187 TMatrix r2z(3, 3); r2z(2, 2) = 1;
188 r2z(0, 0) = cp; r2z(0, 1) = -1 * sp;
189 r2z(1, 0) = sp; r2z(1, 1) = cp;
190
191 TMatrix r2y(3, 3); r2y(1, 1) = 1;
192 r2y(0, 0) = ct; r2y(0, 2) = st;
193 r2y(2, 0) = -1 * st; r2y(2, 2) = ct;
194
195 TMatrix r2(3, 3); r2.Mult(r2z, r2y);
196 TMatrix r2t(3, 3); r2t.Transpose(r2);
197
198 TMatrix longerror(3, 3); longerror(2, 2) = 1000;
199 TMatrix longerror_temp(3, 3); longerror_temp.Mult(r2, longerror);
200 TMatrix longerrorRotated(3, 3); longerrorRotated.Mult(longerror_temp, r2t);
201
202 TMatrix pvNew(3, 3);
203 pvNew += pv;
204 pvNew += longerrorRotated;
205
206 TMatrixFSym errNew(7);
207 errNew.SetSub(0, 0, pp);
208 errNew.SetSub(4, 4, pvNew);
209 errNew(3, 3) = pe;
210
211 TMatrixFSym tubeMat(3);
212 tubeMat.SetSub(0, 0, pvNew);
213
214 TMatrixFSym tubeMatCenterError(3);
215 tubeMatCenterError.SetSub(0, 0, pv);
216
217 if (m_verbose) {
218 B2DEBUG(10, "B origin error matrix : ");
219 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pv(0, 0) << "," << std::fixed << std::setprecision(20) << pv(0,
220 1) << "," << std::fixed << std::setprecision(20) << pv(0, 2) << "},");
221 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pv(1, 0) << "," << std::fixed << std::setprecision(20) << pv(1,
222 1) << "," << std::fixed << std::setprecision(20) << pv(1, 2) << "},");
223 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pv(2, 0) << "," << std::fixed << std::setprecision(20) << pv(2,
224 1) << "," << std::fixed << std::setprecision(20) << pv(2, 2) << "}");
225
226 B2DEBUG(10, "B tube error matrix : ");
227 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pvNew(0, 0) << "," << std::fixed << std::setprecision(20) << pvNew(0,
228 1) << "," << std::fixed << std::setprecision(20) << pvNew(0, 2) << "},");
229 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pvNew(1, 0) << "," << std::fixed << std::setprecision(20) << pvNew(1,
230 1) << "," << std::fixed << std::setprecision(20) << pvNew(1, 2) << "},");
231 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pvNew(2, 0) << "," << std::fixed << std::setprecision(20) << pvNew(2,
232 1) << "," << std::fixed << std::setprecision(20) << pvNew(2, 2) << "}");
233
234 B2DEBUG(10, "B origin ");
235 B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex().X() << "," << std::fixed <<
236 std::setprecision(
237 20) << tubecreatorBCopy->getVertex().Y() << "," << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex().Z() << "}");
238 }
239
240 tubecreatorBCopy->setMomentumVertexErrorMatrix(errNew);
241
242 Btube* tubeconstraint = m_tubeArray.appendNew(Btube());
244 tubecreatorB->addRelationTo(tubeconstraint);
245 } else {
246 otherB->addRelationTo(tubeconstraint);
247 }
248
249 tubeconstraint->setTubeCenter(tubecreatorBOriginpos);
250 tubeconstraint->setTubeMatrix(tubeMat);
251 tubeconstraint->setTubeCenterErrorMatrix(tubeMatCenterError);
252
254 addextrainfos(tubecreatorB, tubecreatorBCopy, pvNew, v4FinalNew);
255 } else {
256 addextrainfos(otherB, tubecreatorBCopy, pvNew, v4FinalNew);
257 }
258 }
259 }
260 if (!ok0) toRemove.push_back(particle->getArrayIndex());
261 }
262 m_plist->removeParticles(toRemove);
263
265}
266
268{
270
272 rsg.addTrack(mother);
273 int nvert = rsg.fit("avf");
274
275 if (nvert == 1) {
276 rsg.updateDaughters();
277 double pValue = rsg.getPValue();
278 mother->setPValue(pValue);
279 } else {return false;}
280 return true;
281}
282
283void BtubeCreatorModule::addextrainfos(Particle* daughter, Particle* copy, TMatrix mat, ROOT::Math::PxPyPzEVector TLV)
284{
285 daughter->writeExtraInfo("TubePosX", copy->getVertex().X());
286 daughter->writeExtraInfo("TubePosY", copy->getVertex().Y());
287 daughter->writeExtraInfo("TubePosZ", copy->getVertex().Z());
288
289 daughter->writeExtraInfo("TubeCov00", mat(0, 0));
290 daughter->writeExtraInfo("TubeCov01", mat(0, 1));
291 daughter->writeExtraInfo("TubeCov02", mat(0, 2));
292 daughter->writeExtraInfo("TubeCov10", mat(1, 0));
293 daughter->writeExtraInfo("TubeCov11", mat(1, 1));
294 daughter->writeExtraInfo("TubeCov12", mat(1, 2));
295 daughter->writeExtraInfo("TubeCov20", mat(2, 0));
296 daughter->writeExtraInfo("TubeCov21", mat(2, 1));
297 daughter->writeExtraInfo("TubeCov22", mat(2, 2));
298
299 daughter->writeExtraInfo("TubeDirX", (TLV.Px() / TLV.P()));
300 daughter->writeExtraInfo("TubeDirY", (TLV.Py() / TLV.P()));
301 daughter->writeExtraInfo("TubeDirZ", (TLV.Pz() / TLV.P()));
302 daughter->writeExtraInfo("TubeB_p_estimated", TLV.P());
303}
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:435
DataType X() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:431
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:433
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
Definition: BFieldManager.h:60
TMatrixDSym m_beamSpotCov
Beam spot covariance matrix.
virtual void initialize() override
declare data store elements
StoreArray< Btube > m_tubeArray
the (output) array of Btube objects
virtual void event() override
process event
std::string m_decayString
specifies which daughter particles will be used as reference to create Btube
std::string m_listName
name of particle list
B2Vector3D m_BeamSpotCenter
Beam spot position.
BtubeCreatorModule()
Constructor: Sets the description, the properties and the parameters of the module.
DBObjPtr< BeamSpot > m_beamSpotDB
Beam spot database object.
bool doVertexFit(Particle *p)
Main steering routine.
double m_confidenceLevel
required fit confidence level
DecayDescriptor m_decaydescriptor
Decay descriptor of decays to look for.
void addextrainfos(Particle *daughter, Particle *copy, TMatrix mat, ROOT::Math::PxPyPzEVector TLV)
fills extrainfos to the particle
double m_Bfield
magnetic field from data base
StoreObjPtr< ParticleList > m_plist
the input particle list
bool m_verbose
run fit with a lot of B2INFOs for debugging
bool m_associateBtubeToBselected
whether to associate the Btube with the selected B
For each MCParticle with hits in the CDC, this class stores some summarising information on those hit...
Definition: Btube.h:22
void setTubeCenterErrorMatrix(const TMatrixFSym &tubecentererrormatrix)
Sets Btube Center Error Matrix.
Definition: Btube.h:54
void setTubeCenter(const Eigen::Matrix< double, 3, 1 > &tubecenter)
Sets Btube Center.
Definition: Btube.h:41
void setTubeMatrix(const TMatrixFSym &tubematrix)
Sets Btube Matrix.
Definition: Btube.h:49
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
int getNDaughters() const
return number of direct daughters.
std::vector< const Particle * > getSelectionParticles(const Particle *particle)
Get a vector of pointers with selected daughters in the decay tree.
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
Class to hold Lorentz transformations from/to CMS and boost vector.
const ROOT::Math::LorentzRotation rotateLabToCms() const
Returns Lorentz transformation from Lab to CMS.
const ROOT::Math::LorentzRotation rotateCmsToLab() const
Returns Lorentz transformation from CMS to Lab.
Class to store reconstructed particles.
Definition: Particle.h:76
TMatrixFSym getVertexErrorMatrix() const
Returns the 3x3 position error sub-matrix.
Definition: Particle.cc:478
void writeExtraInfo(const std::string &name, const double value)
Sets the user defined extraInfo.
Definition: Particle.cc:1393
double getPValue() const
Returns chi^2 probability of fit if done or -1.
Definition: Particle.h:687
ROOT::Math::XYZVector getVertex() const
Returns vertex position (POCA for charged, IP for neutral FS particles)
Definition: Particle.h:651
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
Definition: Particle.h:567
TMatrixFSym getMomentumErrorMatrix() const
Returns the 4x4 momentum error matrix.
Definition: Particle.cc:466
void setMomentumVertexErrorMatrix(const TMatrixFSym &errMatrix)
Sets 7x7 error matrix.
Definition: Particle.cc:424
void setPValue(double pValue)
Sets chi^2 probability of fit.
Definition: Particle.h:377
TMatrixFSym getMomentumVertexErrorMatrix() const
Returns 7x7 error matrix.
Definition: Particle.cc:451
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).
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
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.
Definition: StoreArray.h:140
static void initialize(int verbosity=1, double MagneticField=1.5)
Set everything up so everything needed for vertex fitting is there.
Definition: RaveSetup.cc:33
static RaveSetup * getInstance()
get the pointer to the instance to get/set any of options stored in RaveSetup
Definition: RaveSetup.h:43
void setBeamSpot(const B2Vector3D &beamSpot, const TMatrixDSym &beamSpotCov)
The beam spot position and covariance is known you can set it here so that and a vertex in the beam s...
Definition: RaveSetup.cc:72
void reset()
frees memory allocated by initialize().
Definition: RaveSetup.cc:58
The RaveVertexFitter class is part of the RaveInterface together with RaveSetup.
int fit(std::string options="default")
do the vertex fit with all tracks previously added with the addTrack or addMother function.
void addTrack(const Particle *const aParticlePtr)
add a track (in the format of a Belle2::Particle) to set of tracks that should be fitted to a vertex
void updateDaughters()
update the Daughters particles
double getPValue(VecSize vertexId=0) const
get the p value of the fitted vertex.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:649
Particle * copyParticle(const Particle *original)
Function takes argument Particle and creates a copy of it and copies of all its (grand-)^n-daughters.
Definition: ParticleCopy.cc:17
Abstract base class for different kinds of events.
STL namespace.