Belle II Software light-2509-fornax
V0DaughterTrackVariables.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// Own header.
10#include <analysis/variables/V0DaughterTrackVariables.h>
11
12// include VariableManager
13#include <analysis/VariableManager/Manager.h>
14
15#include <analysis/dataobjects/Particle.h>
16#include <analysis/variables/TrackVariables.h>
17
18// framework - DataStore
19#include <framework/dataobjects/Helix.h>
20
21// dataobjects from the MDST
22#include <mdst/dataobjects/Track.h>
23#include <mdst/dataobjects/MCParticle.h>
24#include <mdst/dataobjects/TrackFitResult.h>
25#include <mdst/dataobjects/HitPatternCDC.h>
26#include <mdst/dataobjects/HitPatternVXD.h>
27
28// framework aux
29#include <framework/logging/Logger.h>
30
31#include <algorithm>
32#include <cmath>
33
34using namespace std;
35
36namespace Belle2 {
41 namespace Variable {
42
43 // helper function to get the helix parameters of the V0 daughter tracks
44 // Not registered in variable manager
45 double getV0DaughterTrackDetNHits(const Particle* particle, const double daughterID, const Const::EDetector& det)
46 {
47 auto daughter = particle->getDaughter(daughterID);
48 return trackNHits(daughter, det);
49 }
50
51 double v0DaughterTrackNRemovedHits(const Particle* part, const std::vector<double>& daughterID)
52 {
53 // returns 0 if called for non-V0 particles
54 if (part->getParticleSource() != Particle::EParticleSourceObject::c_V0)
55 return 0;
56 auto daughter = part->getDaughter(daughterID[0]);
57 const Track* track = daughter->getTrack();
58 if (!track) return Const::doubleNaN;
59 const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(Const::ChargedStable(abs(
60 daughter->getPDGCode())));
61 if (!trackFit) return Const::doubleNaN;
62 double nHitsBeforeRemoval = trackFit->getHitPatternCDC().getNHits()
63 + trackFit->getHitPatternVXD().getNSVDHits()
64 + trackFit->getHitPatternVXD().getNPXDHits();
65 double nHitsAfterRemoval = trackNVXDHits(daughter) + trackNCDCHits(daughter);
66 return nHitsBeforeRemoval - nHitsAfterRemoval;
67 }
68
69 double v0DaughterD0(const Particle* particle, const std::vector<double>& daughterID)
70 {
71 if (!particle)
72 return Const::doubleNaN;
73
74 ROOT::Math::XYZVector v0Vertex = particle->getVertex();
75
76 const Particle* daug = particle->getDaughter(daughterID[0]);
77
78 const TrackFitResult* trackFit = daug->getTrackFitResult();
79 if (!trackFit) return Const::doubleNaN;
80
81 UncertainHelix helix = trackFit->getUncertainHelix();
82 helix.passiveMoveBy(v0Vertex);
83
84 return helix.getD0();
85 }
86
87 double v0DaughterD0Diff(const Particle* particle)
88 {
89 return v0DaughterD0(particle, {0}) - v0DaughterD0(particle, {1});
90 }
91
92 double v0DaughterZ0(const Particle* particle, const std::vector<double>& daughterID)
93 {
94 if (!particle)
95 return Const::doubleNaN;
96
97 ROOT::Math::XYZVector v0Vertex = particle->getVertex();
98
99 const Particle* daug = particle->getDaughter(daughterID[0]);
100
101 const TrackFitResult* trackFit = daug->getTrackFitResult();
102 if (!trackFit) return Const::doubleNaN;
103
104 UncertainHelix helix = trackFit->getUncertainHelix();
105 helix.passiveMoveBy(v0Vertex);
106
107 return helix.getZ0();
108 }
109
110 double v0DaughterZ0Diff(const Particle* particle)
111 {
112 return v0DaughterZ0(particle, {0}) - v0DaughterZ0(particle, {1});
113 }
114
115 // helper function to get pull of the helix parameters of the V0 daughter tracks with the true vertex as the pivot.
116 // Not registered in variable manager
117 double getHelixParameterPullOfV0DaughterWithTrueVertexAsPivotAtIndex(const Particle* particle, const double daughterID,
118 const int tauIndex)
119 {
120 if (!particle) { return Const::doubleNaN; }
121
122 const int dID = int(std::lround(daughterID));
123 if (not(dID == 0 || dID == 1)) { return Const::doubleNaN; }
124
125 const MCParticle* mcparticle_v0 = particle->getMCParticle();
126 if (!mcparticle_v0) { return Const::doubleNaN; }
127
128 if (!(particle->getDaughter(dID))) { return Const::doubleNaN; }
129
130 const MCParticle* mcparticle = particle->getDaughter(dID)->getMCParticle();
131 if (!mcparticle) { return Const::doubleNaN; }
132
133 const TrackFitResult* trackFit = particle->getDaughter(dID)->getTrackFitResult();
134 if (!trackFit) { return Const::doubleNaN; }
135
136 // MC information
137 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
138 const ROOT::Math::XYZVector mcMomentum = mcparticle->getMomentum();
139 const double mcParticleCharge = mcparticle->getCharge();
140 const double BzAtProdVertex = BFieldManager::getFieldInTesla(mcProdVertex).Z();
141 Helix mcHelix = Helix(mcProdVertex, mcMomentum, mcParticleCharge, BzAtProdVertex);
142 mcHelix.passiveMoveBy(mcProdVertex);
143 const std::vector<double> mcHelixPars = { mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(),
144 mcHelix.getZ0(), mcHelix.getTanLambda()
145 };
146
147 // measured information (from the reconstructed particle)
148 UncertainHelix measHelix = trackFit->getUncertainHelix();
149 measHelix.passiveMoveBy(mcProdVertex);
150 const TMatrixDSym measCovariance = measHelix.getCovariance();
151 const std::vector<double> measHelixPars = {measHelix.getD0(), measHelix.getPhi0(), measHelix.getOmega(),
152 measHelix.getZ0(), measHelix.getTanLambda()
153 };
154 const std::vector<double> measErrSquare = {measCovariance[0][0], measCovariance[1][1], measCovariance[2][2],
155 measCovariance[3][3], measCovariance[4][4]
156 };
157
158 if (measErrSquare.at(tauIndex) > 0)
159 return (mcHelixPars.at(tauIndex) - measHelixPars.at(tauIndex)) / std::sqrt(measErrSquare.at(tauIndex));
160 else
161 return Const::doubleNaN;
162 }
163
164 double v0DaughterHelixWithTrueVertexAsPivotD0Pull(const Particle* part, const std::vector<double>& daughterID)
165 {
166 return getHelixParameterPullOfV0DaughterWithTrueVertexAsPivotAtIndex(part, daughterID[0], 0);
167 }
168
169 double v0DaughterHelixWithTrueVertexAsPivotPhi0Pull(const Particle* part, const std::vector<double>& daughterID)
170 {
171 return getHelixParameterPullOfV0DaughterWithTrueVertexAsPivotAtIndex(part, daughterID[0], 1);
172 }
173
174 double v0DaughterHelixWithTrueVertexAsPivotOmegaPull(const Particle* part, const std::vector<double>& daughterID)
175 {
176 return getHelixParameterPullOfV0DaughterWithTrueVertexAsPivotAtIndex(part, daughterID[0], 2);
177 }
178
179 double v0DaughterHelixWithTrueVertexAsPivotZ0Pull(const Particle* part, const std::vector<double>& daughterID)
180 {
181 return getHelixParameterPullOfV0DaughterWithTrueVertexAsPivotAtIndex(part, daughterID[0], 3);
182 }
183
184 double v0DaughterHelixWithTrueVertexAsPivotTanLambdaPull(const Particle* part, const std::vector<double>& daughterID)
185 {
186 return getHelixParameterPullOfV0DaughterWithTrueVertexAsPivotAtIndex(part, daughterID[0], 4);
187 }
188
189 double v0DaughterTrackParam5AtIPPerigee(const Particle* part, const std::vector<double>& params)
190 {
191 auto daughter = part->getDaughter(params[0]);
192 if (!daughter) {
193 return Const::doubleNaN;
194 }
195 auto trackFit = daughter->getTrackFitResult();
196 if (!trackFit) {
197 return Const::doubleNaN;
198 }
199
200 const int paramID = int(std::lround(params[1]));
201 if (not(0 <= paramID && paramID < 5))
202 return Const::doubleNaN;
203
204 std::vector<float> tau = trackFit->getTau();
205 return tau[paramID];
206 }
207
208 double v0DaughterTrackParamCov5x5AtIPPerigee(const Particle* part, const std::vector<double>& params)
209 {
210 auto daughter = part->getDaughter(params[0]);
211 if (!daughter) {
212 return Const::doubleNaN;
213 }
214 auto trackFit = daughter->getTrackFitResult();
215 if (!trackFit) {
216 return Const::doubleNaN;
217 }
218
219 const int paramID = int(std::lround(params[1]));
220 if (not(0 <= paramID && paramID < 15))
221 return Const::doubleNaN;
222
223 std::vector<float> cov = trackFit->getCov();
224 return cov[paramID];
225 }
226
227 int convertedPhotonErrorChecks(const Particle* gamma, const std::vector<double>& daughterIndices)
228 {
229 //Check that exactly two daughter indices are provided
230 if (daughterIndices.size() != 2) {
231 B2ERROR("Invalid number of daughter indices. Please specify exactly two valid daughter indices.");
232 return -1;
233 }
234
235 //Check that there are at least (r+1) daughters where r is the bigger of the two indices provided
236 int daughterIndex1 = int(daughterIndices[0]);
237 int daughterIndex2 = int(daughterIndices[1]);
238 if (int(gamma->getNDaughters()) <= std::max(daughterIndex1, daughterIndex2)) {
239 B2ERROR("Invalid daughter indices provided. Particle does not have that many daughters.");
240 return -1;
241 }
242
243 //Check that there exists tracks associated with the daughter indices provided
244 if (!gamma->getDaughter(daughterIndex1)->getTrack()) {
245 B2ERROR("There is no track associated with daughter index " << daughterIndex1);
246 return -1;
247 }
248 if (!gamma->getDaughter(daughterIndex2)->getTrack()) {
249 B2ERROR("There is no track associated with daughter index " << daughterIndex2);
250 return -1;
251 }
252
253 //Check whether tracks used to calculate variable has been reconstructed as electrons/positrons or not (INCONSEQUENTIAL)
254 if (fabs(gamma->getDaughter(daughterIndex1)->getPDGCode()) != 11) {
255 B2INFO("The first track provided has not been reconstructed as an electron/positron. It has PDG code " << gamma->getDaughter(
256 daughterIndex1)->getPDGCode() << ". However, this is still fully admissible.");
257 }
258 if (fabs(gamma->getDaughter(daughterIndex2)->getPDGCode()) != 11) {
259 B2INFO("The second track provided has not been reconstructed as an electron/positron. It has PDG code " << gamma->getDaughter(
260 daughterIndex1)->getPDGCode() << ".However, this is still fully admissible.");
261 }
262
263 return 0;
264 }
265
266
267 int convertedPhotonLoadHelixParams(const Particle* gamma, int daughterIndex1, int daughterIndex2, double& Phi01, double& D01,
268 double& Omega1, double& Z01, double& TanLambda1, double& Phi02, double& D02, double& Omega2, double& Z02,
269 double& TanLambda2)
270 {
271 //Get helix parameters
272 //Electron/track 1
273 const TrackFitResult* e1TrackFit = gamma->getDaughter(daughterIndex1)->getTrackFitResult();
274 if (!e1TrackFit) return -1;
275 Helix e1Helix = e1TrackFit->getHelix();
276
277 Phi01 = e1Helix.getPhi0();
278 D01 = e1Helix.getD0() ;
279 Omega1 = e1Helix.getOmega();
280 Z01 = e1Helix.getZ0();
281 TanLambda1 = e1Helix.getTanLambda();
282
283 //Electron/track 2
284 const TrackFitResult* e2TrackFit = gamma->getDaughter(daughterIndex2)->getTrackFitResult();
285 if (!e2TrackFit) return -2;
286 Helix e2Helix = e2TrackFit->getHelix();
287
288 Phi02 = e2Helix.getPhi0();
289 D02 = e2Helix.getD0() ;
290 Omega2 = e2Helix.getOmega();
291 Z02 = e2Helix.getZ0();
292 TanLambda2 = e2Helix.getTanLambda();
293
294 //Check if either track has zero curvature
295 if (Omega1 == 0) {return -1;}
296 else if (Omega2 == 0) {return -2;}
297 else {return 0;}
298
299 }
300
301 double convertedPhotonInvariantMass(const Particle* gamma, const std::vector<double>& daughterIndices)
302 {
303 //Do basic checks
304 int errFlag = convertedPhotonErrorChecks(gamma, daughterIndices);
305 if (errFlag == -1) {return Const::doubleNaN;}
306
307 //Load helix parameters
308 double Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02, Omega2, Z02, TanLambda2;
309 int daughterIndex1 = int(daughterIndices[0]);
310 int daughterIndex2 = int(daughterIndices[1]);
311 errFlag = convertedPhotonLoadHelixParams(gamma, daughterIndex1, daughterIndex2, Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02,
312 Omega2, Z02, TanLambda2);
313 if (errFlag != 0) return Const::doubleNaN;
314
315 //Calculating invariant mass
316 //Sine and cosine Lambda
317 double sinlam1 = TanLambda1 / sqrt(1 + (TanLambda1 * TanLambda1));
318 double coslam1 = 1 / sqrt(1 + (TanLambda1 * TanLambda1));
319 double sinlam2 = TanLambda2 / sqrt(1 + (TanLambda2 * TanLambda2));
320 double coslam2 = 1 / sqrt(1 + (TanLambda2 * TanLambda2));
321
322 //Transverse and longitudinal momentum components; energy with electron mass hypothesis
323 //electron 1
324 double p1 = gamma->getDaughter(daughterIndex1)->getMomentumMagnitude();
325 double pt1 = p1 * coslam1, pz1 = p1 * sinlam1;
326 double e1 = sqrt((p1 * p1) + (Const::electronMass * Const::electronMass));
327 //electron 2
328 double p2 = gamma->getDaughter(daughterIndex2)->getMomentumMagnitude();
329 double pt2 = p2 * coslam2, pz2 = p2 * sinlam2;
330 double e2 = sqrt((p2 * p2) + (Const::electronMass * Const::electronMass));
331
332 //Invariant mass of the two track system
333 double vtxMass = sqrt(pow(e1 + e2, 2.0) - pow(pt1 + pt2, 2.0) - pow(pz1 + pz2, 2.0));
334 return vtxMass;
335 }
336
337 double convertedPhotonDelTanLambda(const Particle* gamma, const std::vector<double>& daughterIndices)
338 {
339 //Do basic checks
340 int errFlag = convertedPhotonErrorChecks(gamma, daughterIndices);
341 if (errFlag == -1) {return Const::doubleNaN;}
342
343 //Load helix parameters
344 double Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02, Omega2, Z02, TanLambda2;
345 int daughterIndex1 = int(daughterIndices[0]);
346 int daughterIndex2 = int(daughterIndices[1]);
347 errFlag = convertedPhotonLoadHelixParams(gamma, daughterIndex1, daughterIndex2, Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02,
348 Omega2, Z02, TanLambda2);
349 if (errFlag != 0) return Const::doubleNaN;
350
351 //Delta-TanLambda
352 return (TanLambda2 - TanLambda1);
353 }
354
355 double convertedPhotonDelR(const Particle* gamma, const std::vector<double>& daughterIndices)
356 {
357 //Do basic checks
358 int errFlag = convertedPhotonErrorChecks(gamma, daughterIndices);
359 if (errFlag == -1) {return Const::doubleNaN;}
360
361 //Load helix parameters
362 double Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02, Omega2, Z02, TanLambda2;
363 int daughterIndex1 = int(daughterIndices[0]);
364 int daughterIndex2 = int(daughterIndices[1]);
365 errFlag = convertedPhotonLoadHelixParams(gamma, daughterIndex1, daughterIndex2, Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02,
366 Omega2, Z02, TanLambda2);
367 if (errFlag == -1) {
368 B2ERROR("First track provided has curvature zero. Calculation of convertedPhotonDelR failed.");
369 return Const::doubleNaN;
370 }
371 if (errFlag == -2) {
372 B2ERROR("Second track provided has curvature zero. Calculation of convertedPhotonDelR failed.");
373 return Const::doubleNaN;
374 }
375
376 //Delta-R
377 double radius1 = 1 / Omega1;
378 double radius2 = 1 / Omega2;
379
380 ROOT::Math::XYVector center1((radius1 + D01) * sin(Phi01), -1 * (radius1 + D01) * cos(Phi01));
381 ROOT::Math::XYVector center2((radius2 + D02) * sin(Phi02), -1 * (radius2 + D02) * cos(Phi02));
382 ROOT::Math::XYVector cenDiff = center1 - center2;
383
384 double delR = fabs(radius1) + fabs(radius2) - cenDiff.R();
385 return delR;
386 }
387
388 std::pair<double, double> convertedPhotonZ1Z2(const Particle* gamma, const std::vector<double>& daughterIndices)
389 {
390 //Do basic checks
391 int errFlag = convertedPhotonErrorChecks(gamma, daughterIndices);
392 if (errFlag == -1) {return std::pair<double, double>(Const::doubleNaN, Const::doubleNaN);}
393
394 //Load helix parameters
395 double Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02, Omega2, Z02, TanLambda2;
396 int daughterIndex1 = int(daughterIndices[0]);
397 int daughterIndex2 = int(daughterIndices[1]);
398 errFlag = convertedPhotonLoadHelixParams(gamma, daughterIndex1, daughterIndex2, Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02,
399 Omega2, Z02, TanLambda2);
400 if (errFlag == -1) {
401 B2ERROR("First track provided has curvature zero. Calculation of convertedPhotonZ1Z2 failed.");
402 return std::pair<double, double>(Const::doubleNaN, Const::doubleNaN);
403 }
404 if (errFlag == -2) {
405 B2ERROR("Second track provided has curvature zero. Calculation of convertedPhotonZ1Z2 failed.");
406 return std::pair<double, double>(Const::doubleNaN, Const::doubleNaN);
407 }
408
409 //Delta-Z
410 //Radial unit vectors
411 double radius1 = 1 / Omega1;
412 double radius2 = 1 / Omega2;
413
414 ROOT::Math::XYVector center1((radius1 + D01) * sin(Phi01), -1 * (radius1 + D01) * cos(Phi01));
415 ROOT::Math::XYVector center2((radius2 + D02) * sin(Phi02), -1 * (radius2 + D02) * cos(Phi02));
416
417 ROOT::Math::XYVector n1 = center1 - center2; n1 = n1.Unit();
418 ROOT::Math::XYVector n2 = -1 * n1;
419 n1 = copysign(1.0, Omega1) * n1;
420 n2 = copysign(1.0, Omega2) * n2;
421
422 //Getting running parameter phi at nominal vertex
423 double phiN1 = atan2(n1.X(), -n1.Y());
424 double phiN2 = atan2(n2.X(), -n2.Y());
425 double Phi01Intersect = phiN1 - Phi01;
426 double Phi02Intersect = phiN2 - Phi02;
427
428 double z1 = Z01 - (radius1 * TanLambda1 * Phi01Intersect);
429 double z2 = Z02 - (radius2 * TanLambda2 * Phi02Intersect);
430 std::pair<double, double> z1z2(z1, z2);
431 return z1z2;
432 }
433
434 double convertedPhotonDelZ(const Particle* gamma, const std::vector<double>& daughterIndices)
435 {
436 std::pair<double, double> z1z2 = convertedPhotonZ1Z2(gamma, daughterIndices);
437 double z1 = z1z2.first; double z2 = z1z2.second;
438 return (z1 - z2);
439 }
440
441 double convertedPhotonZ(const Particle* gamma, const std::vector<double>& daughterIndices)
442 {
443 std::pair<double, double> z1z2 = convertedPhotonZ1Z2(gamma, daughterIndices);
444 double z1 = z1z2.first; double z2 = z1z2.second;
445 return (z1 + z2) * 0.5;
446 }
447
448 ROOT::Math::XYVector convertedPhotonXY(const Particle* gamma, const std::vector<double>& daughterIndices)
449 {
450 //Do basic checks
451 int errFlag = convertedPhotonErrorChecks(gamma, daughterIndices);
452 if (errFlag == -1) {return ROOT::Math::XYVector(Const::doubleNaN, Const::doubleNaN);}
453
454 //Load helix parameters
455 double Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02, Omega2, Z02, TanLambda2;
456 int daughterIndex1 = int(daughterIndices[0]);
457 int daughterIndex2 = int(daughterIndices[1]);
458 errFlag = convertedPhotonLoadHelixParams(gamma, daughterIndex1, daughterIndex2, Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02,
459 Omega2, Z02, TanLambda2);
460 if (errFlag == -1) {
461 B2ERROR("First track provided has curvature zero. Calculation of convertedPhotonXY failed.");
462 return ROOT::Math::XYVector(Const::doubleNaN, Const::doubleNaN);
463 }
464 if (errFlag == -2) {
465 B2ERROR("Second track provided has curvature zero. Calculation of convertedPhotonXY failed.");
466 return ROOT::Math::XYVector(Const::doubleNaN, Const::doubleNaN);
467 }
468
469 //Radial unit vectors
470 double radius1 = 1 / Omega1;
471 double radius2 = 1 / Omega2;
472
473 ROOT::Math::XYVector center1((radius1 + D01) * sin(Phi01), -1 * (radius1 + D01) * cos(Phi01));
474 ROOT::Math::XYVector center2((radius2 + D02) * sin(Phi02), -1 * (radius2 + D02) * cos(Phi02));
475 ROOT::Math::XYVector cenDiff = center2 - center1;
476 double delR = fabs(radius1) + fabs(radius2) - cenDiff.R();
477
478 //Calculate transverse vertex
479 ROOT::Math::XYVector n1 = cenDiff.Unit();
480 ROOT::Math::XYVector vtxXY = center1 + ((fabs(radius1) - (delR / 2)) * n1);
481 return vtxXY;
482 }
483
484 double convertedPhotonX(const Particle* gamma, const std::vector<double>& daughterIndices)
485 {
486 auto vtxXY = convertedPhotonXY(gamma, daughterIndices);
487 return vtxXY.X();
488 }
489
490 double convertedPhotonY(const Particle* gamma, const std::vector<double>& daughterIndices)
491 {
492 auto vtxXY = convertedPhotonXY(gamma, daughterIndices);
493 return vtxXY.Y();
494 }
495
496 double convertedPhotonRho(const Particle* gamma, const std::vector<double>& daughterIndices)
497 {
498 auto vtxXY = convertedPhotonXY(gamma, daughterIndices);
499 return vtxXY.R();
500 }
501
502 ROOT::Math::XYZVector convertedPhoton3Momentum(const Particle* gamma, const std::vector<double>& daughterIndices)
503 {
504 //Do basic checks
505 int errFlag = convertedPhotonErrorChecks(gamma, daughterIndices);
506 if (errFlag == -1) {return ROOT::Math::XYZVector(Const::doubleNaN, Const::doubleNaN, Const::doubleNaN);}
507
508 //Load helix parameters
509 double Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02, Omega2, Z02, TanLambda2;
510 int daughterIndex1 = int(daughterIndices[0]);
511 int daughterIndex2 = int(daughterIndices[1]);
512 errFlag = convertedPhotonLoadHelixParams(gamma, daughterIndex1, daughterIndex2, Phi01, D01, Omega1, Z01, TanLambda1, Phi02, D02,
513 Omega2, Z02,
514 TanLambda2);
515 if (errFlag == -1) {
516 B2ERROR("First track provided has curvature zero. Calculation of convertedPhoton3Momentum failed.");
517 return ROOT::Math::XYZVector(Const::doubleNaN, Const::doubleNaN, Const::doubleNaN);
518 }
519 if (errFlag == -2) {
520 B2ERROR("Second track provided has curvature zero. Calculation of convertedPhoton3Momentum failed.");
521 return ROOT::Math::XYZVector(Const::doubleNaN, Const::doubleNaN, Const::doubleNaN);
522 }
523
524 //Delta-Z
525 //Radial unit vectors
526 double radius1 = 1 / Omega1;
527 double radius2 = 1 / Omega2;
528
529 ROOT::Math::XYVector center1((radius1 + D01) * sin(Phi01), -1 * (radius1 + D01) * cos(Phi01));
530 ROOT::Math::XYVector center2((radius2 + D02) * sin(Phi02), -1 * (radius2 + D02) * cos(Phi02));
531 ROOT::Math::XYVector n1 = center1 - center2; n1 = n1.Unit();
532 ROOT::Math::XYVector n2 = -1 * n1;
533 n1 = copysign(1.0, Omega1) * n1;
534 n2 = copysign(1.0, Omega2) * n2;
535
536 //Getting running parameter phi at nominal vertex
537 double phiN1 = atan2(n1.X(), -n1.Y());
538 double phiN2 = atan2(n2.X(), -n2.Y());
539
540 //Sine and cosine Lambda
541 double sinlam1 = TanLambda1 / sqrt(1 + (TanLambda1 * TanLambda1));
542 double coslam1 = 1 / sqrt(1 + (TanLambda1 * TanLambda1));
543 double sinlam2 = TanLambda2 / sqrt(1 + (TanLambda2 * TanLambda2));
544 double coslam2 = 1 / sqrt(1 + (TanLambda2 * TanLambda2));
545
546 //Photon 3-momentum
547 double p1 = gamma->getDaughter(daughterIndex1)->getMomentumMagnitude();
548 ROOT::Math::XYZVector e1Momentum(coslam1 * cos(phiN1), coslam1 * sin(phiN1), sinlam1);
549 double p2 = gamma->getDaughter(daughterIndex2)->getMomentumMagnitude();
550 ROOT::Math::XYZVector e2Momentum(coslam2 * cos(phiN2), coslam2 * sin(phiN2), sinlam2);
551 ROOT::Math::XYZVector gammaMomentum = (e1Momentum * p1) + (e2Momentum * p2);
552
553 return gammaMomentum;
554 }
555
556 double convertedPhotonPx(const Particle* gamma, const std::vector<double>& daughterIndices)
557 {
558 auto gammaMomentum = convertedPhoton3Momentum(gamma, daughterIndices);
559 return gammaMomentum.X();
560 }
561
562 double convertedPhotonPy(const Particle* gamma, const std::vector<double>& daughterIndices)
563 {
564 auto gammaMomentum = convertedPhoton3Momentum(gamma, daughterIndices);
565 return gammaMomentum.Y();
566 }
567
568 double convertedPhotonPz(const Particle* gamma, const std::vector<double>& daughterIndices)
569 {
570 auto gammaMomentum = convertedPhoton3Momentum(gamma, daughterIndices);
571 return gammaMomentum.Z();
572 }
573
574 int v0DaughtersShareInnermostHit(const Particle* part)
575 {
576 if (!part)
577 return -1;
578 auto daughterPlus = part->getDaughter(0);
579 auto daughterMinus = part->getDaughter(1);
580 if (!daughterPlus || !daughterMinus)
581 return -1;
582 auto trackFitPlus = daughterPlus->getTrackFitResult();
583 auto trackFitMinus = daughterMinus->getTrackFitResult();
584 if (!trackFitPlus || !trackFitMinus)
585 return -1;
586 int flagPlus = trackFitPlus->getHitPatternVXD().getInnermostHitShareStatus();
587 int flagMinus = trackFitMinus->getHitPatternVXD().getInnermostHitShareStatus();
588 if (flagPlus != flagMinus)
589 return -1;
590 return flagPlus;
591 }
592
593 bool v0DaughtersShareInnermostUHit(const Particle* part)
594 {
595 return ((v0DaughtersShareInnermostHit(part) / 2) == 1);
596 }
597
598 bool v0DaughtersShareInnermostVHit(const Particle* part)
599 {
600 return ((v0DaughtersShareInnermostHit(part) % 2) == 1);
601 }
602
603 VARIABLE_GROUP("V0Daughter");
604
605 REGISTER_VARIABLE("v0DaughterNRemovedHits(i)", v0DaughterTrackNRemovedHits,
606 "The number of the i-th daughter track hits removed in V0Finder. Returns 0 if called for something other than V0 daughters.");
608 REGISTER_VARIABLE("V0d0(id)", v0DaughterD0,
609 "Return the d0 impact parameter of a V0's daughter with daughterID index with the V0 vertex point as a pivot for the track.\n\n",
610 "cm");
611 REGISTER_VARIABLE("V0Deltad0", v0DaughterD0Diff,
612 "Return the difference between d0 impact parameters of V0's daughters with the V0 vertex point as a pivot for the track.\n\n",
613 "cm");
614 REGISTER_VARIABLE("V0z0(id)", v0DaughterZ0,
615 "Return the z0 impact parameter of a V0's daughter with daughterID index with the V0 vertex point as a pivot for the track.\n\n",
616 "cm");
617 REGISTER_VARIABLE("V0Deltaz0", v0DaughterZ0Diff,
618 "Return the difference between z0 impact parameters of V0's daughters with the V0 vertex point as a pivot for the track.\n\n",
619 "cm");
620
622 REGISTER_VARIABLE("v0DaughterD0PullWithTrueVertexAsPivot(i)", v0DaughterHelixWithTrueVertexAsPivotD0Pull,
623 "d0 pull of the i-th daughter track with the true V0 vertex as the track pivot");
624 REGISTER_VARIABLE("v0DaughterPhi0PullWithTrueVertexAsPivot(i)", v0DaughterHelixWithTrueVertexAsPivotPhi0Pull,
625 "phi0 pull of the i-th daughter track with the true V0 vertex as the track pivot");
626 REGISTER_VARIABLE("v0DaughterOmegaPullWithTrueVertexAsPivot(i)", v0DaughterHelixWithTrueVertexAsPivotOmegaPull,
627 "omega pull of the i-th daughter track with the true V0 vertex as the track pivot");
628 REGISTER_VARIABLE("v0DaughterZ0PullWithTrueVertexAsPivot(i)", v0DaughterHelixWithTrueVertexAsPivotZ0Pull,
629 "z0 pull of the i-th daughter track with the true V0 vertex as the track pivot");
630 REGISTER_VARIABLE("v0DaughterTanLambdaPullWithTrueVertexAsPivot(i)", v0DaughterHelixWithTrueVertexAsPivotTanLambdaPull,
631 "tan(lambda) pull of the i-th daughter track with the true V0 vertex as the track pivot");
633 REGISTER_VARIABLE("v0DaughterTau(i,j)", v0DaughterTrackParam5AtIPPerigee,
634 "j-th track parameter (at IP perigee) of the i-th daughter track. "
635 "j: 0:d0, 1:phi0, 2:omega, 3:z0, 4:tanLambda\n\n", "cm, rad, :math:`\\text{cm}^{-1}`, cm, unitless");
636 REGISTER_VARIABLE("v0DaughterCov(i,j)", v0DaughterTrackParamCov5x5AtIPPerigee,
637 "j-th element of the 15 covariance matrix elements (at IP perigee) of the i-th daughter track. "
638 "(0,0), (0,1) ... (1,1), (1,2) ... (2,2) ..."
639 "index order is: 0:d0, 1:phi0, 2:omega, 3:z0, 4:tanLambda\n\n", "cm, rad, :math:`\\text{cm}^{-1}`, cm, unitless");
641 REGISTER_VARIABLE("convertedPhotonInvariantMass(i,j)", convertedPhotonInvariantMass,
642 "Invariant mass of the i-j daughter system as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
643 "GeV/:math:`\\text{c}^2`");
644 REGISTER_VARIABLE("convertedPhotonDelTanLambda(i,j)", convertedPhotonDelTanLambda,
645 "Discriminating variable Delta-TanLambda calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon");
646 REGISTER_VARIABLE("convertedPhotonDelR(i,j)", convertedPhotonDelR,
647 "Discriminating variable Delta-R calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
648 "cm");
649 REGISTER_VARIABLE("convertedPhotonDelZ(i,j)", convertedPhotonDelZ,
650 "Discriminating variable Delta-Z calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
651 "cm");
652 REGISTER_VARIABLE("convertedPhotonX(i,j)", convertedPhotonX,
653 "Estimate of vertex X coordinate calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
654 "cm");
655 REGISTER_VARIABLE("convertedPhotonY(i,j)", convertedPhotonY,
656 "Estimate of vertex Y coordinate calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
657 "cm");
658 REGISTER_VARIABLE("convertedPhotonZ(i,j)", convertedPhotonZ,
659 "Estimate of vertex Z coordinate calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
660 "cm");
661 REGISTER_VARIABLE("convertedPhotonRho(i,j)", convertedPhotonRho,
662 "Estimate of vertex Rho calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
663 "cm");
664 REGISTER_VARIABLE("convertedPhotonPx(i,j)", convertedPhotonPx,
665 "Estimate of x-component of photon momentum calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
666 "GeV/c");
667 REGISTER_VARIABLE("convertedPhotonPy(i,j)", convertedPhotonPy,
668 "Estimate of y-component of photon momentum calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
669 "GeV/c");
670 REGISTER_VARIABLE("convertedPhotonPz(i,j)", convertedPhotonPz,
671 "Estimate of z-component of photon momentum calculated for daughters (i,j) as defined in https://indico.belle2.org/event/3644/contributions/18622/attachments/9401/14443/Photon_vertexin_B2GM.pdf, assuming it's a converted photon\n\n",
672 "GeV/c");
674 REGISTER_VARIABLE("v0DaughtersShare1stHit", v0DaughtersShareInnermostHit,
675 "flag for V0 daughters sharing the first(innermost) VXD hit. 0x1(0x2) bit represents V/z(U/r-phi)-hit share.");
676 REGISTER_VARIABLE("v0DaughtersShare1stUHit", v0DaughtersShareInnermostUHit,
677 "flag for V0 daughters sharing the first(innermost) VXD U-side hit.");
678 REGISTER_VARIABLE("v0DaughtersShare1stVHit", v0DaughtersShareInnermostVHit,
679 "flag for V0 daughters sharing the first(innermost) VXD V-side hit.");
680 }
682}
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
EDetector
Enum for identifying the detector components (detector and subdetector).
Definition Const.h:42
static const double electronMass
electron mass
Definition Const.h:685
static const double doubleNaN
quiet_NaN
Definition Const.h:703
Abstract base class for different kinds of events.
STL namespace.