Belle II Software  release-08-01-10
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 
30 using namespace std;
31 using namespace Belle2;
32 
33 //-----------------------------------------------------------------
34 // Register the Module
35 //-----------------------------------------------------------------
36 REG_MODULE(BtubeCreator);
37 
38 //-----------------------------------------------------------------
39 // Implementation
40 //-----------------------------------------------------------------
41 
42 BtubeCreatorModule::BtubeCreatorModule() : Module(),
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");
47 
48  // Parameter definitions
49  addParam("listName", m_listName, "name of mother particle list", string(""));
50  addParam("confidenceLevel", m_confidenceLevel, "Confidence level to accept the fit.", 0.001);
51  addParam("decayString", m_decayString,
52  "decay string of the mother particle, the selected daughter specifies which daughter will be used as reference to create Btube",
53  string(""));
54  addParam("associateBtubeToBselected", m_associateBtubeToBselected,
55  "whether to associate the Btube with the selected B",
56  false);
57  addParam("verbosity", m_verbose, "print statements", true);
58 }
59 
61 {
62 
63  m_plist.isRequired(m_listName);
64 
65  // magnetic field
66  m_Bfield = BFieldManager::getFieldInTesla(ROOT::Math::XYZVector(0, 0, 0)).Z();
67 
68  m_BeamSpotCenter = m_beamSpotDB->getIPPosition();
69  m_beamSpotCov.ResizeTo(3, 3);
70  m_beamSpotCov = m_beamSpotDB->getCovVertex();
71  B2INFO("BtubeCreator : magnetic field = " << m_Bfield);
72 
73  m_tubeArray.registerInDataStore();
75 
76  bool valid = m_decaydescriptor.init(m_decayString);
77  if (!valid)
78  B2ERROR("BtubeCreatorModule: invalid decay string" << m_decayString);
79  int nProducts = m_decaydescriptor.getNDaughters();
80  if (nProducts != 2)
81  B2ERROR("BtubeCreatorModule: decay string should contain only two daughters");
82 }
83 
85 {
87 
88  std::vector<unsigned int> toRemove;
89  unsigned int n = m_plist->getListSize();
90 
91  for (unsigned i = 0; i < n; i++) {
92  Particle* particle = m_plist->getParticle(i);
93 
94  std::vector<Particle*> daughtervec = particle->getDaughters();
95  std::vector<const Particle*> selParticles = m_decaydescriptor.getSelectionParticles(particle);
96  if (selParticles.size() > 1) {
97  B2FATAL("Please select only one daughter which will be used as reference to create Btube");
98  }
99 
100  int selectindex = 1;
101  if ((daughtervec.at(0))->getArrayIndex() == (selParticles.at(0))->getArrayIndex()) selectindex = 0 ;
102 
103  Particle* tubecreatorB = const_cast<Particle*>(particle->getDaughter(selectindex));
104  Particle* otherB = const_cast<Particle*>(particle->getDaughter(1 - selectindex));
105 
106  if ((tubecreatorB->getVertexErrorMatrix()(2, 2)) == 0.0) {
107  B2FATAL("Please perform a vertex fit of the selected B before calling this module");
108  }
109 
110  //make a copy of tubecreatorB so as not to modify the original object
111 
112  Particle* tubecreatorBCopy = ParticleCopy::copyParticle(tubecreatorB);
113 
114  if (m_verbose) {
115  B2DEBUG(10, "tubecreator B decay vertex: ");
116  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex().X() << "," << std::fixed <<
117  std::setprecision(
118  20) << tubecreatorBCopy->getVertex().Y() << "," << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex().Z() << "}");
119  }
120 
121  bool ok0 = doVertexFit(tubecreatorBCopy);
122 
123  if (ok0) {
124  if (tubecreatorBCopy->getPValue() < m_confidenceLevel) {
125  toRemove.push_back(particle->getArrayIndex());
126  } else {
127  particle->setVertex(tubecreatorBCopy->getVertex());
128  particle->setMomentumVertexErrorMatrix(tubecreatorBCopy->getMomentumVertexErrorMatrix());
129 
130  tubecreatorB->writeExtraInfo("prod_vtx_x", tubecreatorBCopy->getVertex().X());
131  tubecreatorB->writeExtraInfo("prod_vtx_y", tubecreatorBCopy->getVertex().Y());
132  tubecreatorB->writeExtraInfo("prod_vtx_z", tubecreatorBCopy->getVertex().Z());
133  tubecreatorB->writeExtraInfo("prod_vtx_cov00", tubecreatorBCopy->getVertexErrorMatrix()(0, 0));
134  tubecreatorB->writeExtraInfo("prod_vtx_cov01", tubecreatorBCopy->getVertexErrorMatrix()(0, 1));
135  tubecreatorB->writeExtraInfo("prod_vtx_cov02", tubecreatorBCopy->getVertexErrorMatrix()(0, 2));
136  tubecreatorB->writeExtraInfo("prod_vtx_cov10", tubecreatorBCopy->getVertexErrorMatrix()(1, 0));
137  tubecreatorB->writeExtraInfo("prod_vtx_cov11", tubecreatorBCopy->getVertexErrorMatrix()(1, 1));
138  tubecreatorB->writeExtraInfo("prod_vtx_cov12", tubecreatorBCopy->getVertexErrorMatrix()(1, 2));
139  tubecreatorB->writeExtraInfo("prod_vtx_cov20", tubecreatorBCopy->getVertexErrorMatrix()(2, 0));
140  tubecreatorB->writeExtraInfo("prod_vtx_cov21", tubecreatorBCopy->getVertexErrorMatrix()(2, 1));
141  tubecreatorB->writeExtraInfo("prod_vtx_cov22", tubecreatorBCopy->getVertexErrorMatrix()(2, 2));
142 
143  tubecreatorB->writeExtraInfo("Px_after_avf", (tubecreatorBCopy->get4Vector()).Px());
144  tubecreatorB->writeExtraInfo("Py_after_avf", (tubecreatorBCopy->get4Vector()).Py());
145  tubecreatorB->writeExtraInfo("Pz_after_avf", (tubecreatorBCopy->get4Vector()).Pz());
146  tubecreatorB->writeExtraInfo("E_after_avf", (tubecreatorBCopy->get4Vector()).E());
147 
148  Eigen::Matrix<double, 3, 1> tubecreatorBOriginpos(tubecreatorBCopy->getVertex().X(), tubecreatorBCopy->getVertex().Y(),
149  tubecreatorBCopy->getVertex().Z());
150  ROOT::Math::PxPyPzEVector v4Final = tubecreatorBCopy->get4Vector();
152  ROOT::Math::PxPyPzEVector vec = T.rotateLabToCms() * v4Final;
153  ROOT::Math::PxPyPzEVector vecNew(-1 * vec.Px(), -1 * vec.Py(), -1 * vec.Pz(), vec.E());
154  ROOT::Math::PxPyPzEVector v4FinalNew = T.rotateCmsToLab() * vecNew;
155 
156  if (m_verbose) {
157  B2DEBUG(10, "beamspot center :");
158  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << m_BeamSpotCenter.X() << "," << std::fixed << std::setprecision(
159  20) << m_BeamSpotCenter.Y() << "," << std::fixed << std::setprecision(20) << m_BeamSpotCenter.Z() << "}");
160  B2DEBUG(10, "beamspot cov :");
161 
162  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << m_beamSpotCov(0,
163  0) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(0,
164  1) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(0, 2) << "},");
165  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << m_beamSpotCov(1,
166  0) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(1,
167  1) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(1, 2) << "},");
168  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << m_beamSpotCov(2,
169  0) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(2,
170  1) << "," << std::fixed << std::setprecision(20) << m_beamSpotCov(2, 2) << "}");
171  }
172  TMatrixFSym pp = (tubecreatorBCopy->getMomentumErrorMatrix()).GetSub(0, 2, 0, 2, "S");
173  double pe = tubecreatorBCopy->getMomentumErrorMatrix()(2, 2);
174  TMatrixFSym pv = tubecreatorBCopy->getVertexErrorMatrix();
175 
176  // start rotation
177 
178  double theta = v4FinalNew.Theta();
179  double phi = v4FinalNew.Phi();
180 
181  double st = TMath::Sin(theta);
182  double ct = TMath::Cos(theta);
183  double sp = TMath::Sin(phi);
184  double cp = TMath::Cos(phi);
185 
186  TMatrix r2z(3, 3); r2z(2, 2) = 1;
187  r2z(0, 0) = cp; r2z(0, 1) = -1 * sp;
188  r2z(1, 0) = sp; r2z(1, 1) = cp;
189 
190  TMatrix r2y(3, 3); r2y(1, 1) = 1;
191  r2y(0, 0) = ct; r2y(0, 2) = st;
192  r2y(2, 0) = -1 * st; r2y(2, 2) = ct;
193 
194  TMatrix r2(3, 3); r2.Mult(r2z, r2y);
195  TMatrix r2t(3, 3); r2t.Transpose(r2);
196 
197  TMatrix longerror(3, 3); longerror(2, 2) = 1000;
198  TMatrix longerror_temp(3, 3); longerror_temp.Mult(r2, longerror);
199  TMatrix longerrorRotated(3, 3); longerrorRotated.Mult(longerror_temp, r2t);
200 
201  TMatrix pvNew(3, 3);
202  pvNew += pv;
203  pvNew += longerrorRotated;
204 
205  TMatrixFSym errNew(7);
206  errNew.SetSub(0, 0, pp);
207  errNew.SetSub(4, 4, pvNew);
208  errNew(3, 3) = pe;
209 
210  TMatrixFSym tubeMat(3);
211  tubeMat.SetSub(0, 0, pvNew);
212 
213  TMatrixFSym tubeMatCenterError(3);
214  tubeMatCenterError.SetSub(0, 0, pv);
215 
216  if (m_verbose) {
217  B2DEBUG(10, "B origin error matrix : ");
218  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pv(0, 0) << "," << std::fixed << std::setprecision(20) << pv(0,
219  1) << "," << std::fixed << std::setprecision(20) << pv(0, 2) << "},");
220  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pv(1, 0) << "," << std::fixed << std::setprecision(20) << pv(1,
221  1) << "," << std::fixed << std::setprecision(20) << pv(1, 2) << "},");
222  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pv(2, 0) << "," << std::fixed << std::setprecision(20) << pv(2,
223  1) << "," << std::fixed << std::setprecision(20) << pv(2, 2) << "}");
224 
225  B2DEBUG(10, "B tube error matrix : ");
226  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pvNew(0, 0) << "," << std::fixed << std::setprecision(20) << pvNew(0,
227  1) << "," << std::fixed << std::setprecision(20) << pvNew(0, 2) << "},");
228  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pvNew(1, 0) << "," << std::fixed << std::setprecision(20) << pvNew(1,
229  1) << "," << std::fixed << std::setprecision(20) << pvNew(1, 2) << "},");
230  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << pvNew(2, 0) << "," << std::fixed << std::setprecision(20) << pvNew(2,
231  1) << "," << std::fixed << std::setprecision(20) << pvNew(2, 2) << "}");
232 
233  B2DEBUG(10, "B origin ");
234  B2DEBUG(10, "{" << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex().X() << "," << std::fixed <<
235  std::setprecision(
236  20) << tubecreatorBCopy->getVertex().Y() << "," << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex().Z() << "}");
237  }
238 
239  tubecreatorBCopy->setMomentumVertexErrorMatrix(errNew);
240 
241  Btube* tubeconstraint = m_tubeArray.appendNew(Btube());
243  tubecreatorB->addRelationTo(tubeconstraint);
244  } else {
245  otherB->addRelationTo(tubeconstraint);
246  }
247 
248  tubeconstraint->setTubeCenter(tubecreatorBOriginpos);
249  tubeconstraint->setTubeMatrix(tubeMat);
250  tubeconstraint->setTubeCenterErrorMatrix(tubeMatCenterError);
251 
253  addextrainfos(tubecreatorB, tubecreatorBCopy, pvNew, v4FinalNew);
254  } else {
255  addextrainfos(otherB, tubecreatorBCopy, pvNew, v4FinalNew);
256  }
257  }
258  }
259  if (!ok0) toRemove.push_back(particle->getArrayIndex());
260  }
261  m_plist->removeParticles(toRemove);
262 
264 }
265 
267 {
269 
271  rsg.addTrack(mother);
272  int nvert = rsg.fit("avf");
273 
274  if (nvert == 1) {
275  rsg.updateDaughters();
276  double pValue = rsg.getPValue();
277  mother->setPValue(pValue);
278  } else {return false;}
279  return true;
280 }
281 
282 void BtubeCreatorModule::addextrainfos(Particle* daughter, Particle* copy, TMatrix mat, ROOT::Math::PxPyPzEVector TLV)
283 {
284  daughter->writeExtraInfo("TubePosX", copy->getVertex().X());
285  daughter->writeExtraInfo("TubePosY", copy->getVertex().Y());
286  daughter->writeExtraInfo("TubePosZ", copy->getVertex().Z());
287 
288  daughter->writeExtraInfo("TubeCov00", mat(0, 0));
289  daughter->writeExtraInfo("TubeCov01", mat(0, 1));
290  daughter->writeExtraInfo("TubeCov02", mat(0, 2));
291  daughter->writeExtraInfo("TubeCov10", mat(1, 0));
292  daughter->writeExtraInfo("TubeCov11", mat(1, 1));
293  daughter->writeExtraInfo("TubeCov12", mat(1, 2));
294  daughter->writeExtraInfo("TubeCov20", mat(2, 0));
295  daughter->writeExtraInfo("TubeCov21", mat(2, 1));
296  daughter->writeExtraInfo("TubeCov22", mat(2, 2));
297 
298  daughter->writeExtraInfo("TubeDirX", (TLV.Px() / TLV.P()));
299  daughter->writeExtraInfo("TubeDirY", (TLV.Py() / TLV.P()));
300  daughter->writeExtraInfo("TubeDirZ", (TLV.Pz() / TLV.P()));
301  daughter->writeExtraInfo("TubeB_p_estimated", TLV.P());
302 }
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:61
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.
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:27
void setTubeCenterErrorMatrix(const TMatrixFSym &tubecentererrormatrix)
Sets Btube Center Error Matrix.
Definition: Btube.h:59
void setTubeCenter(const Eigen::Matrix< double, 3, 1 > &tubecenter)
Sets Btube Center.
Definition: Btube.h:46
void setTubeMatrix(const TMatrixFSym &tubematrix)
Sets Btube Matrix.
Definition: Btube.h:54
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
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:75
TMatrixFSym getVertexErrorMatrix() const
Returns the 3x3 position error sub-matrix.
Definition: Particle.cc:451
void writeExtraInfo(const std::string &name, const double value)
Sets the user defined extraInfo.
Definition: Particle.cc:1309
double getPValue() const
Returns chi^2 probability of fit if done or -1.
Definition: Particle.h:625
ROOT::Math::XYZVector getVertex() const
Returns vertex position (POCA for charged, IP for neutral FS particles)
Definition: Particle.h:589
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
Definition: Particle.h:517
TMatrixFSym getMomentumErrorMatrix() const
Returns the 4x4 momentum error matrix.
Definition: Particle.cc:439
void setMomentumVertexErrorMatrix(const TMatrixFSym &errMatrix)
Sets 7x7 error matrix.
Definition: Particle.cc:397
TMatrixFSym getMomentumVertexErrorMatrix() const
Returns 7x7 error matrix.
Definition: Particle.cc:424
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
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:18
Abstract base class for different kinds of events.