Belle II Software  release-06-02-00
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 
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 
60 void BtubeCreatorModule::initialize()
61 {
62 
63  m_plist.isRequired(m_listName);
64 
65  // magnetic field
66  m_Bfield = BFieldManager::getField(TVector3(0, 0, 0)).Z() / Unit::T;
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 
84 void BtubeCreatorModule::event()
85 {
86  analysis::RaveSetup::initialize(1, m_Bfield);
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()[0] << "," << std::fixed <<
117  std::setprecision(
118  20) << tubecreatorBCopy->getVertex()[1] << "," << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex()[2] << "}");
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()[0]);
131  tubecreatorB->writeExtraInfo("prod_vtx_y", tubecreatorBCopy->getVertex()[1]);
132  tubecreatorB->writeExtraInfo("prod_vtx_z", tubecreatorBCopy->getVertex()[2]);
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()[0], tubecreatorBCopy->getVertex()[1],
149  tubecreatorBCopy->getVertex()[2]);
150  TLorentzVector v4Final = tubecreatorBCopy->get4Vector();
152  TLorentzVector vec = T.rotateLabToCms() * v4Final;
153  TLorentzVector vecNew(-1 * vec.Px(), -1 * vec.Py(), -1 * vec.Pz(), vec.E());
154  TLorentzVector 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()[0] << "," << std::fixed <<
235  std::setprecision(
236  20) << tubecreatorBCopy->getVertex()[1] << "," << std::fixed << std::setprecision(20) << tubecreatorBCopy->getVertex()[2] << "}");
237  }
238 
239  tubecreatorBCopy->setMomentumVertexErrorMatrix(errNew);
240 
241  Btube* tubeconstraint = m_tubeArray.appendNew(Btube());
242  if (m_associateBtubeToBselected) {
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 
252  if (m_associateBtubeToBselected) {
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 
263  analysis::RaveSetup::getInstance()->reset();
264 }
265 
266 bool BtubeCreatorModule::doVertexFit(Particle* mother)
267 {
268  analysis::RaveSetup::getInstance()->setBeamSpot(m_BeamSpotCenter, m_beamSpotCov);
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, TLorentzVector TLV)
283 {
284  daughter->writeExtraInfo("TubePosX", copy->getVertex()[0]);
285  daughter->writeExtraInfo("TubePosY", copy->getVertex()[1]);
286  daughter->writeExtraInfo("TubePosZ", copy->getVertex()[2]);
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.Mag()));
299  daughter->writeExtraInfo("TubeDirY", (TLV.Py() / TLV.Mag()));
300  daughter->writeExtraInfo("TubeDirZ", (TLV.Pz() / TLV.Mag()));
301  daughter->writeExtraInfo("TubeB_p_estimated", TLV.Mag());
302 }
Create a B particle from a Bbar particle.
For each MCParticle with hits in the CDC, this class stores some summarising information on those hit...
Definition: Btube.h:28
void setTubeCenterErrorMatrix(const TMatrixFSym &tubecentererrormatrix)
Sets Btube Center Error Matrix.
Definition: Btube.h:60
void setTubeCenter(const Eigen::Matrix< double, 3, 1 > &tubecenter)
Sets Btube Center.
Definition: Btube.h:47
void setTubeMatrix(const TMatrixFSym &tubematrix)
Sets Btube Matrix.
Definition: Btube.h:55
Base class for Modules.
Definition: Module.h:72
Class to hold Lorentz transformations from/to CMS and boost vector.
const TLorentzRotation rotateLabToCms() const
Returns Lorentz transformation from Lab to CMS.
const TLorentzRotation rotateCmsToLab() const
Returns Lorentz transformation from CMS to Lab.
Class to store reconstructed particles.
Definition: Particle.h:74
TMatrixFSym getVertexErrorMatrix() const
Returns the 3x3 position error sub-matrix.
Definition: Particle.cc:457
void writeExtraInfo(const std::string &name, const float value)
Sets the user defined extraInfo.
Definition: Particle.cc:1261
TVector3 getVertex() const
Returns vertex position (POCA for charged, IP for neutral FS particles)
Definition: Particle.h:551
float getPValue() const
Returns chi^2 probability of fit if done or -1.
Definition: Particle.h:587
TMatrixFSym getMomentumErrorMatrix() const
Returns the 4x4 momentum error matrix.
Definition: Particle.cc:445
TLorentzVector get4Vector() const
Returns Lorentz vector.
Definition: Particle.h:477
void setMomentumVertexErrorMatrix(const TMatrixFSym &errMatrix)
Sets 7x7 error matrix.
Definition: Particle.cc:403
TMatrixFSym getMomentumVertexErrorMatrix() const
Returns 7x7 error matrix.
Definition: Particle.cc:430
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
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.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.