9#include <tracking/dataobjects/RecoTrack.h>
10#include <mdst/dataobjects/Track.h>
11#include <analysis/dataobjects/Particle.h>
12#include <svd/variables/SVDClusterVariables.h>
13#include <svd/dataobjects/SVDTrueHit.h>
14#include <vxd/dataobjects/VxdID.h>
15#include <vxd/geometry/GeoCache.h>
16#include <vxd/geometry/SensorInfoBase.h>
17#include <framework/dataobjects/EventT0.h>
18#include <framework/datastore/StoreObjPtr.h>
34 const std::vector<Belle2::SVDCluster*> svdClusters = recoTrack->
getSVDHitList();
35 if (clusterIndex >= svdClusters.size()) {
38 return svdClusters[clusterIndex];
44 return getSVDCluster(recoTrack, clusterIndex);
48namespace Belle2::Variable {
50 double SVDClusterCharge(
const Particle* particle,
const std::vector<double>& indices)
55 if (indices.size() != 1) {
56 B2FATAL(
"Exactly one parameter (cluster index) is required.");
58 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
60 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
64 double SVDClusterSNR(
const Particle* particle,
const std::vector<double>& indices)
70 if (indices.size() != 1) {
71 B2FATAL(
"Exactly one parameter (cluster index) is required.");
73 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
75 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
79 int SVDClusterSize(
const Particle* particle,
const std::vector<double>& indices)
85 if (indices.size() != 1) {
86 B2FATAL(
"Exactly one parameter (cluster index) is required.");
88 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
90 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
91 return svdCluster ? svdCluster->getSize() : -1;
94 double SVDClusterTime(
const Particle* particle,
const std::vector<double>& indices)
99 if (indices.size() != 1) {
100 B2FATAL(
"Exactly one parameter (cluster index) is required.");
102 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
104 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
108 double SVDTrackPrime(
const Particle* particle,
const std::vector<double>& indices)
113 if (indices.size() != 1) {
114 B2FATAL(
"Exactly one parameter (cluster index) is required.");
116 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
118 const RecoTrack* recoTrack = getRecoTrack(particle);
122 const SVDCluster* svdCluster = getSVDCluster(recoTrack, clusterIndex);
126 const RecoHitInformation* recoHitInformation = recoTrack->getRecoHitInformation(svdCluster);
127 if (!recoHitInformation) {
131 genfit::MeasuredStateOnPlane measuredState = recoTrack->getMeasuredStateOnPlaneFromRecoHit(recoHitInformation);
132 return svdCluster->isUCluster()
133 ? measuredState.getState()[1]
134 : measuredState.getState()[2];
135 }
catch (
const NoTrackFitResult&) {
136 B2WARNING(
"No track fit result available for this hit!");
141 double SVDTrackPositionErrorUnbiased(
const Particle* particle,
const std::vector<double>& indices)
146 if (indices.size() != 1) {
147 B2FATAL(
"Exactly one parameter (cluster index) is required.");
149 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
151 const RecoTrack* recoTrack = getRecoTrack(particle);
155 const SVDCluster* svdCluster = getSVDCluster(recoTrack, clusterIndex);
159 const RecoHitInformation* recoHitInformation = recoTrack->getRecoHitInformation(svdCluster);
160 if (!recoHitInformation) {
163 const genfit::TrackPoint* trackPoint = recoTrack->getCreatedTrackPoint(recoHitInformation);
167 const genfit::AbsFitterInfo* fitterInfo = trackPoint->getFitterInfo();
172 genfit::MeasuredStateOnPlane unbiasedState = fitterInfo->getFittedState(
false);
173 return svdCluster->isUCluster()
174 ?
sqrt(unbiasedState.getCov()[3][3])
175 :
sqrt(unbiasedState.getCov()[4][4]);
177 B2WARNING(
"Could not compute SVDTrackPositionErrorUnbiased.");
182 double SVDTruePosition(
const Particle* particle,
const std::vector<double>& indices)
187 if (indices.size() != 1) {
188 B2FATAL(
"Exactly one parameter (cluster index) is required.");
190 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
192 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
197 const auto trueHit = svdCluster->getRelatedTo<Belle2::SVDTrueHit>();
202 return svdCluster->isUCluster()
207 double SVDResidual(
const Particle* particle,
const std::vector<double>& indices)
212 if (indices.size() != 1) {
213 B2FATAL(
"Exactly one parameter (cluster index) is required.");
215 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
217 const RecoTrack* recoTrack = getRecoTrack(particle);
221 const SVDCluster* svdCluster = getSVDCluster(recoTrack, clusterIndex);
225 const RecoHitInformation* recoHitInformation = recoTrack->getRecoHitInformation(svdCluster);
226 if (!recoHitInformation) {
229 const genfit::TrackPoint* trackPoint = recoTrack->getCreatedTrackPoint(recoHitInformation);
233 const genfit::AbsFitterInfo* fitterInfo = trackPoint->getFitterInfo();
238 const TVectorD residualMeasurement = fitterInfo->getResidual(0,
false).getState();
241 B2WARNING(
"Could not get track residual.");
246 int SVDLayer(
const Particle* particle,
const std::vector<double>& indices)
251 if (indices.size() != 1) {
252 B2FATAL(
"Exactly one parameter (cluster index) is required.");
254 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
256 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
260 const VxdID vxdId = svdCluster->getSensorID();
261 return vxdId ? vxdId.getLayerNumber() : -1;
264 int SVDLadder(
const Particle* particle,
const std::vector<double>& indices)
269 if (indices.size() != 1) {
270 B2FATAL(
"Exactly one parameter (cluster index) is required.");
272 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
274 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
278 const VxdID vxdId = svdCluster->getSensorID();
279 return vxdId ? vxdId.getLadderNumber() : -1;
282 int SVDSensor(
const Particle* particle,
const std::vector<double>& indices)
287 if (indices.size() != 1) {
288 B2FATAL(
"Exactly one parameter (cluster index) is required.");
290 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
292 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
296 const VxdID vxdId = svdCluster->getSensorID();
297 return vxdId ? vxdId.getSensorNumber() : -1;
300 bool SVDSide(
const Particle* particle,
const std::vector<double>& indices)
305 if (indices.size() != 1) {
306 B2FATAL(
"Exactly one parameter (cluster index) is required.");
308 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
310 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
311 return svdCluster ? svdCluster->isUCluster() :
false;
314 double SVDClusterTimeMinusEventT0(
const Particle* particle,
const std::vector<double>& indices)
319 if (indices.size() != 1) {
320 B2FATAL(
"Exactly one parameter (cluster index) is required.");
322 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
324 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
329 StoreObjPtr<EventT0> evtT0;
330 if (!evtT0.isValid()) {
331 B2WARNING(
"StoreObjPtr<EventT0> does not exist, are you running over cDST data?");
334 if (!evtT0->hasEventT0()) {
338 return svdCluster->getClsTime() - evtT0->getEventT0();
341 double SVDClusterChargeNormTrkLength(
const Particle* particle,
const std::vector<double>& indices)
346 if (indices.size() != 1) {
347 B2FATAL(
"Exactly one parameter (cluster index) is required.");
349 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
351 const RecoTrack* recoTrack = getRecoTrack(particle);
355 const SVDCluster* svdCluster = getSVDCluster(recoTrack, clusterIndex);
359 const RecoHitInformation* recoHitInformation = recoTrack->getRecoHitInformation(svdCluster);
360 if (!recoHitInformation) {
363 if (!recoTrack->wasFitSuccessful()) {
366 if (!recoHitInformation->useInFit()) {
372 genfit::MeasuredStateOnPlane measuredState = recoTrack->getMeasuredStateOnPlaneFromRecoHit(recoHitInformation);
373 const TVectorD& state = measuredState.getState();
377 const double trackPrime = state[1];
378 const double trackPrimeOS = state[2];
380 const double normTrkLength =
sqrt(1.0 + trackPrime * trackPrime + trackPrimeOS * trackPrimeOS);
383 const double clusterCharge = svdCluster->getCharge();
385 return clusterCharge / normTrkLength;
386 }
catch (
const NoTrackFitResult&) {
387 B2WARNING(
"No track fit result available for this hit!");
390 B2WARNING(
"Could not compute SVDClusterChargeNormTrkLength.");
395 double SVDClusterTimeMinusCDCEventT0(
const Particle* particle,
const std::vector<double>& indices)
400 if (indices.size() != 1) {
401 B2FATAL(
"Exactly one parameter (cluster index) is required.");
403 const auto clusterIndex =
static_cast<unsigned int>(indices[0]);
405 SVDCluster* svdCluster = getSVDCluster(particle, clusterIndex);
410 StoreObjPtr<EventT0> evtT0;
411 if (!evtT0.isValid()) {
412 B2WARNING(
"StoreObjPtr<EventT0> does not exist, are you running over cDST data?");
415 auto cdcT0 = evtT0->getBestCDCTemporaryEventT0();
420 return svdCluster->getClsTime() - cdcT0->eventT0;
423 double CDCEventT0(
const Particle* ,
const std::vector<double>& )
425 StoreObjPtr<EventT0> evtT0;
426 if (!evtT0.isValid()) {
427 B2WARNING(
"StoreObjPtr<EventT0> does not exist, are you running over cDST data?");
430 auto cdcT0 = evtT0->getBestCDCTemporaryEventT0();
434 return cdcT0->eventT0;
437 double SVDEventT0(
const Particle* ,
const std::vector<double>& )
439 StoreObjPtr<EventT0> evtT0;
440 if (!evtT0.isValid()) {
441 B2WARNING(
"StoreObjPtr<EventT0> does not exist, are you running over cDST data?");
444 auto svdT0 = evtT0->getBestSVDTemporaryEventT0();
448 return svdT0->eventT0;
451 VARIABLE_GROUP(
"SVD Validation");
453 REGISTER_VARIABLE(
"SVDClusterCharge(i)", SVDClusterCharge,
454 "Returns the charge of the i-th SVD cluster related to the Particle.");
455 REGISTER_VARIABLE(
"SVDClusterSNR(i)", SVDClusterSNR,
456 "Returns the SNR of the i-th SVD cluster related to the Particle.");
457 REGISTER_VARIABLE(
"SVDClusterSize(i)", SVDClusterSize,
458 "Returns the size of the i-th SVD cluster related to the Particle.");
459 REGISTER_VARIABLE(
"SVDClusterTime(i)", SVDClusterTime,
460 "Returns the time of the i-th SVD cluster related to the Particle.");
461 REGISTER_VARIABLE(
"SVDTrackPrime(i)", SVDTrackPrime,
462 "Returns the tan of the incident angle projected on U/V of the i-th SVD cluster related to the Particle.");
463 REGISTER_VARIABLE(
"SVDResidual(i)", SVDResidual,
464 "Returns the track residual of the i-th SVD cluster related to the Particle.");
465 REGISTER_VARIABLE(
"SVDTrackPositionErrorUnbiased(i)", SVDTrackPositionErrorUnbiased,
466 "Returns the unbiased track position error of the i-th SVD cluster related to the Particle.");
467 REGISTER_VARIABLE(
"SVDTruePosition(i)", SVDTruePosition,
468 "Returns the true position of the i-th SVD cluster related to the Particle.");
469 REGISTER_VARIABLE(
"SVDClusterChargeNormTrkLength(i)", SVDClusterChargeNormTrkLength,
470 "Returns the cluster charge normalized to track length in SVD for the i-th SVD cluster related to the Particle.");
471 REGISTER_VARIABLE(
"SVDClusterTimeMinusEventT0(i)", SVDClusterTimeMinusEventT0,
472 "Returns the cluster time minus the event T0 for the i-th SVD cluster related to the Particle.");
473 REGISTER_VARIABLE(
"SVDLayer(i)", SVDLayer,
474 "Returns the layer number of the i-th SVD cluster related to the Particle. If no SVD cluster is found, returns -1.");
475 REGISTER_VARIABLE(
"SVDLadder(i)", SVDLadder,
476 "Returns the ladder number of the i-th SVD cluster related to the Particle. If no SVD cluster is found, returns -1.");
477 REGISTER_VARIABLE(
"SVDSensor(i)", SVDSensor,
478 "Returns the sensor number of the i-th SVD cluster related to the Particle. If no SVD cluster is found, returns -1.");
479 REGISTER_VARIABLE(
"SVDSide(i)", SVDSide,
480 "Returns true if the i-th SVD cluster related to the Particle is a U cluster.");
481 REGISTER_VARIABLE(
"SVDClusterTimeMinusCDCEventT0(i)", SVDClusterTimeMinusCDCEventT0,
482 "Returns the cluster time minus the best CDC-based event T0 for the i-th SVD cluster related to the Particle.");
483 REGISTER_VARIABLE(
"CDCEventT0", CDCEventT0,
484 "Returns the best CDC-based event T0.");
485 REGISTER_VARIABLE(
"SVDEventT0", SVDEventT0,
486 "Returns the best SVD-based event T0.");
static const double doubleNaN
quiet_NaN
Class to store reconstructed particles.
This is the Reconstruction Event-Data Model Track.
std::vector< Belle2::RecoTrack::UsedSVDHit * > getSVDHitList() const
Return an unsorted list of svd hits.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Class that bundles various TrackFitResults.
static double convertValueToUnit(double value, const std::string &unitString)
Converts a floating point value from the standard framework unit to the given unit.
double sqrt(double a)
sqrt for double