9 #include <alignment/modules/MillepedeCollector/MillepedeCollectorModule.h>
11 #include <alignment/dataobjects/MilleData.h>
12 #include <alignment/GblMultipleScatteringController.h>
13 #include <alignment/GlobalDerivatives.h>
14 #include <alignment/GlobalLabel.h>
15 #include <alignment/GlobalParam.h>
16 #include <alignment/GlobalTimeLine.h>
17 #include <alignment/Manager.h>
18 #include <alignment/reconstruction/AlignableCDCRecoHit.h>
19 #include <alignment/reconstruction/AlignablePXDRecoHit.h>
20 #include <alignment/reconstruction/AlignableSVDRecoHit.h>
21 #include <alignment/reconstruction/AlignableSVDRecoHit2D.h>
22 #include <alignment/reconstruction/AlignableBKLMRecoHit.h>
23 #include <alignment/reconstruction/AlignableEKLMRecoHit.h>
24 #include <analysis/dataobjects/ParticleList.h>
25 #include <analysis/utility/ReferenceFrame.h>
26 #include <framework/core/FileCatalog.h>
27 #include <framework/database/DBObjPtr.h>
28 #include <framework/dataobjects/EventT0.h>
29 #include <framework/dataobjects/FileMetaData.h>
30 #include <framework/datastore/StoreArray.h>
31 #include <framework/datastore/StoreObjPtr.h>
32 #include <framework/dbobjects/BeamParameters.h>
33 #include <framework/particledb/EvtGenDatabasePDG.h>
34 #include <framework/pcore/ProcHandler.h>
35 #include <mdst/dbobjects/BeamSpot.h>
36 #include <mdst/dataobjects/Track.h>
37 #include <tracking/trackFitting/fitter/base/TrackFitter.h>
38 #include <tracking/trackFitting/measurementCreator/adder/MeasurementAdder.h>
40 #include <genfit/FullMeasurement.h>
41 #include <genfit/GblFitter.h>
42 #include <genfit/KalmanFitterInfo.h>
43 #include <genfit/PlanarMeasurement.h>
44 #include <genfit/Track.h>
49 #include <TDecompSVD.h>
53 using namespace alignment;
66 setPropertyFlags(c_ParallelProcessingCertified);
67 setDescription(
"Calibration data collector for Millepede Algorithm");
70 addParam(
"tracks", m_tracks,
"Names of collections of RecoTracks (already fitted with DAF) for calibration", vector<string>({
""}));
71 addParam(
"particles", m_particles,
"Names of particle list of single particles", vector<string>());
72 addParam(
"vertices", m_vertices,
73 "Name of particle list of (mother) particles with daughters for calibration using vertex constraint", vector<string>());
74 addParam(
"primaryVertices", m_primaryVertices,
75 "Name of particle list of (mother) particles with daughters for calibration using vertex + IP profile constraint",
77 addParam(
"twoBodyDecays", m_twoBodyDecays,
78 "Name of particle list of (mother) particles with daughters for calibration using vertex + mass constraint",
80 addParam(
"primaryTwoBodyDecays", m_primaryTwoBodyDecays,
81 "Name of particle list of (mother) particles with daughters for calibration using vertex + IP profile + kinematics constraint",
83 addParam(
"primaryMassTwoBodyDecays", m_primaryMassTwoBodyDecays,
84 "Name of particle list of (mother) particles with daughters for calibration using vertex + mass constraint",
86 addParam(
"primaryMassVertexTwoBodyDecays", m_primaryMassVertexTwoBodyDecays,
87 "Name of particle list of (mother) particles with daughters for calibration using vertex + IP profile + mass constraint",
90 addParam(
"stableParticleWidth", m_stableParticleWidth,
91 "Width (in GeV/c/c) to use for invariant mass constraint for 'stable' particles (like K short). Temporary until proper solution is found.",
94 addParam(
"doublePrecision", m_doublePrecision,
"Use double (=true) or single/float (=false) precision for writing binary files",
96 addParam(
"useGblTree", m_useGblTree,
"Store GBL trajectories in a tree instead of output to binary files",
98 addParam(
"absFilePaths", m_absFilePaths,
"Use absolute paths to remember binary files. Only applies if useGblTree=False",
102 addParam(
"components", m_components,
103 "Specify which DB objects are calibrated, like ['BeamSpot', 'CDCTimeWalks'] or leave empty to use all components available.",
105 addParam(
"calibrateVertex", m_calibrateVertex,
106 "For primary vertices / two body decays, beam spot vertex calibration derivatives are added",
108 addParam(
"calibrateKinematics", m_calibrateKinematics,
109 "For primary two body decays, beam spot kinematics calibration derivatives are added",
113 addParam(
"externalIterations", m_externalIterations,
"Number of external iterations of GBL fitter",
115 addParam(
"internalIterations", m_internalIterations,
"String defining internal GBL iterations for outlier down-weighting",
117 addParam(
"recalcJacobians", m_recalcJacobians,
"Up to which external iteration propagation Jacobians should be re-calculated",
120 addParam(
"minPValue", m_minPValue,
"Minimum p-value to write out a (combined) trajectory. Set <0 to write out all.",
124 addParam(
"fitTrackT0", m_fitTrackT0,
"Add local parameter for track T0 fit in GBL",
126 addParam(
"updateCDCWeights", m_updateCDCWeights,
"Update L/R weights from previous DAF fit result",
128 addParam(
"minCDCHitWeight", m_minCDCHitWeight,
"Minimum (DAF) CDC hit weight for usage by GBL",
130 addParam(
"minUsedCDCHitFraction", m_minUsedCDCHitFraction,
"Minimum used CDC hit fraction to write out a trajectory",
133 addParam(
"hierarchyType", m_hierarchyType,
"Type of (VXD only now) hierarchy: 0 = None, 1 = Flat, 2 = Half-Shells, 3 = Full",
135 addParam(
"enablePXDHierarchy", m_enablePXDHierarchy,
"Enable PXD in hierarchy (flat or full)",
137 addParam(
"enableSVDHierarchy", m_enableSVDHierarchy,
"Enable SVD in hierarchy (flat or full)",
140 addParam(
"enableWireByWireAlignment", m_enableWireByWireAlignment,
"Enable global derivatives for wire-by-wire alignment",
142 addParam(
"enableWireSagging", m_enableWireSagging,
"Enable global derivatives for wire sagging",
146 addParam(
"events", m_eventNumbers,
147 "List of (event, run, exp) with event numbers at which payloads can change for timedep calibration.",
150 addParam(
"timedepConfig", m_timedepConfig,
151 "list{ {list{param1, param2, ...}, list{(ev1, run1, exp1), ...}}, ... }.",
155 addParam(
"customMassConfig", m_customMassConfig,
156 "dict{ list_name: (mass, width), ... } with custom mass and width to use as external measurement.",
160 void MillepedeCollectorModule::prepare()
168 if (m_tracks.empty() &&
169 m_particles.empty() &&
170 m_vertices.empty() &&
171 m_primaryVertices.empty() &&
172 m_twoBodyDecays.empty() &&
173 m_primaryTwoBodyDecays.empty() &&
174 m_primaryMassTwoBodyDecays.empty() &&
175 m_primaryMassVertexTwoBodyDecays.empty())
176 B2ERROR(
"You have to specify either arrays of single tracks or particle lists of single single particles or mothers with vertex constrained daughters.");
178 if (!m_tracks.empty()) {
179 for (
auto arrayName : m_tracks)
184 if (!m_particles.empty() || !m_vertices.empty() || !m_primaryVertices.empty()) {
194 for (
auto listName : m_particles) {
199 for (
auto listName : m_vertices) {
204 for (
auto listName : m_primaryVertices) {
210 registerObject<MilleData>(
"mille",
new MilleData(m_doublePrecision, m_absFilePaths));
212 auto gblDataTree =
new TTree(
"GblDataTree",
"GblDataTree");
213 gblDataTree->Branch<std::vector<gbl::GblData>>(
"GblData", &m_currentGblData, 32000, 99);
214 registerObject<TTree>(
"GblDataTree", gblDataTree);
216 registerObject<TH1I>(
"ndf",
new TH1I(
"ndf",
"ndf", 200, 0, 200));
217 registerObject<TH1F>(
"chi2_per_ndf",
new TH1F(
"chi2_per_ndf",
"chi2 divided by ndf", 200, 0., 50.));
218 registerObject<TH1F>(
"pval",
new TH1F(
"pval",
"pval", 100, 0., 1.));
220 registerObject<TH1F>(
"cdc_hit_fraction",
new TH1F(
"cdc_hit_fraction",
"cdc_hit_fraction", 100, 0., 1.));
221 registerObject<TH1F>(
"evt0",
new TH1F(
"evt0",
"evt0", 400, -100., 100.));
224 if (m_hierarchyType == 0)
226 else if (m_hierarchyType == 1)
228 else if (m_hierarchyType == 2)
230 else if (m_hierarchyType == 3)
236 std::vector<EventMetaData> events;
237 for (
auto& ev_run_exp : m_eventNumbers) {
238 events.push_back(
EventMetaData(std::get<0>(ev_run_exp), std::get<1>(ev_run_exp), std::get<2>(ev_run_exp)));
242 if (!m_timedepConfig.empty() && m_eventNumbers.empty()) {
243 auto autoEvents = Belle2::alignment::timeline::setupTimedepGlobalLabels(m_timedepConfig);
245 }
else if (m_timedepConfig.empty() && !m_eventNumbers.empty()) {
247 }
else if (m_timedepConfig.empty() && m_eventNumbers.empty()) {
250 B2ERROR(
"Cannot set both, event list and timedep config.");
255 AlignableCDCRecoHit::s_enableTrackT0LocalDerivative = m_fitTrackT0;
256 AlignableCDCRecoHit::s_enableWireSaggingGlobalDerivative = m_enableWireSagging;
257 AlignableCDCRecoHit::s_enableWireByWireAlignmentGlobalDerivatives = m_enableWireByWireAlignment;
260 void MillepedeCollectorModule::collect()
263 alignment::GlobalCalibrationManager::getInstance().preCollect(*emd);
268 auto mille = getObjectPtr<MilleData>(
"mille");
269 if (!mille->isOpen())
270 mille->open(getUniqueMilleName());
275 double lostWeight = -1.;
279 for (
auto arrayName : m_tracks) {
284 for (
auto& recoTrack : recoTracks) {
286 if (!fitRecoTrack(recoTrack))
289 auto& track = RecoTrackGenfitAccess::getGenfitTrack(recoTrack);
290 if (!track.hasFitStatus())
296 if (!fs->isFittedWithReferenceTrack())
300 GblTrajectory trajectory(
gbl->collectGblPoints(&track, track.getCardinalRep()), fs->hasCurvature());
302 trajectory.
fit(chi2, ndf, lostWeight);
303 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
304 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
305 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
306 if (eventT0.isValid() && eventT0->hasEventT0()) {
307 evt0 = eventT0->getEventT0();
308 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
311 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(trajectory);
317 for (
auto listName : m_particles) {
322 for (
unsigned int iParticle = 0; iParticle < list->getListSize(); ++iParticle) {
323 for (
auto& track : getParticlesTracks({list->getParticle(iParticle)},
false)) {
326 gbl::GblTrajectory trajectory(
gbl->collectGblPoints(track, track->getCardinalRep()), gblfs->hasCurvature());
328 trajectory.
fit(chi2, ndf, lostWeight);
329 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
330 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
331 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
332 if (eventT0.isValid() && eventT0->hasEventT0()) {
333 evt0 = eventT0->getEventT0();
334 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
337 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(trajectory);
343 for (
auto listName : m_vertices) {
348 for (
unsigned int iParticle = 0; iParticle < list->getListSize(); ++iParticle) {
349 auto mother = list->getParticle(iParticle);
350 std::vector<std::pair<std::vector<gbl::GblPoint>, TMatrixD> > daughters;
352 for (
auto& track : getParticlesTracks(mother->getDaughters()))
353 daughters.push_back({
354 gbl->collectGblPoints(track, track->getCardinalRep()),
355 getGlobalToLocalTransform(track->getFittedState()).GetSub(0, 4, 0, 2)
358 if (daughters.size() > 1) {
361 combined.
fit(chi2, ndf, lostWeight);
362 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
363 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
364 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
365 if (eventT0.isValid() && eventT0->hasEventT0()) {
366 evt0 = eventT0->getEventT0();
367 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
371 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(combined);
373 B2RESULT(
"Vertex-constrained fit NDF = " << ndf <<
" Chi2/NDF = " << chi2 /
double(ndf));
379 for (
auto listName : m_primaryVertices) {
384 for (
unsigned int iParticle = 0; iParticle < list->getListSize(); ++iParticle) {
385 auto mother = list->getParticle(iParticle);
386 std::vector<std::pair<std::vector<gbl::GblPoint>, TMatrixD> > daughters;
388 TMatrixD extProjection(5, 3);
389 TMatrixD locProjection(3, 5);
392 for (
auto& track : getParticlesTracks(mother->getDaughters())) {
395 extProjection = getGlobalToLocalTransform(track->getFittedState()).GetSub(0, 4, 0, 2);
396 locProjection = getLocalToGlobalTransform(track->getFittedState()).GetSub(0, 2, 0, 4);
399 daughters.push_back({
400 gbl->collectGblPoints(track, track->getCardinalRep()),
401 getGlobalToLocalTransform(track->getFittedState()).GetSub(0, 4, 0, 2)
405 if (daughters.size() > 1) {
406 auto beam = getPrimaryVertexAndCov();
408 TMatrixDSym vertexCov(get<TMatrixDSym>(beam));
409 TMatrixDSym vertexPrec(get<TMatrixDSym>(beam).Invert());
410 B2Vector3D vertexResidual = - (mother->getVertex() - get<B2Vector3D>(beam));
412 TVectorD extMeasurements(3);
413 extMeasurements[0] = vertexResidual[0];
414 extMeasurements[1] = vertexResidual[1];
415 extMeasurements[2] = vertexResidual[2];
417 TMatrixD extDeriv(3, 3);
424 if (m_calibrateVertex) {
425 TMatrixD derivatives(3, 3);
427 derivatives(0, 0) = 1.;
428 derivatives(1, 1) = 1.;
429 derivatives(2, 2) = 1.;
431 std::vector<int> labels;
432 GlobalLabel label = GlobalLabel::construct<BeamSpot>(0, 0);
433 labels.push_back(label.setParameterId(1));
434 labels.push_back(label.setParameterId(2));
435 labels.push_back(label.setParameterId(3));
442 std::vector<int> lab(globals); TMatrixD der(globals);
468 TMatrixD dLocal_dExt = extProjection;
469 TMatrixD dExt_dLocal = locProjection;
471 TVectorD locRes = dLocal_dExt * extMeasurements;
473 TMatrixD locCov = dLocal_dExt * vertexCov * dExt_dLocal;
475 TMatrixD locPrec = locCov.GetSub(3, 4, 3, 4).Invert();
476 TMatrixDSym locPrec2D(2); locPrec2D.Zero();
477 for (
int i = 0; i < 2; ++i)
478 for (
int j = 0; j < 2; ++j)
479 locPrec2D(i, j) = locPrec(i, j);
484 TVectorD locRes2D = locRes.GetSub(3, 4);
485 TMatrixD locDerivs2D = (extProjection * der).GetSub(3, 4, 0, 2);
489 daughters[0].first[0].addMeasurement(locRes2D, locPrec2D);
491 daughters[0].first[0].addGlobals(lab, locDerivs2D);
498 combined.
fit(chi2, ndf, lostWeight);
499 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
500 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
501 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
502 if (eventT0.isValid() && eventT0->hasEventT0()) {
503 evt0 = eventT0->getEventT0();
504 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
507 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(combined);
508 B2RESULT(
"Beam vertex constrained fit results NDF = " << ndf <<
" Chi2/NDF = " << chi2 /
double(ndf));
514 combined.
fit(chi2, ndf, lostWeight);
515 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
516 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
517 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
518 if (eventT0.isValid() && eventT0->hasEventT0()) {
519 evt0 = eventT0->getEventT0();
520 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
523 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(combined);
525 B2RESULT(
"Beam vertex constrained fit results NDF = " << ndf <<
" Chi2/NDF = " << chi2 /
double(ndf));
532 for (
auto listName : m_twoBodyDecays) {
537 for (
unsigned int iParticle = 0; iParticle < list->getListSize(); ++iParticle) {
539 auto mother = list->getParticle(iParticle);
540 auto track12 = getParticlesTracks(mother->getDaughters());
541 if (track12.size() != 2) {
542 B2ERROR(
"Did not get 2 fitted tracks. Skipping this mother.");
546 auto pdgdb = EvtGenDatabasePDG::Instance();
547 double motherMass = mother->getPDGMass();
548 double motherWidth = pdgdb->GetParticle(mother->getPDGCode())->Width();
550 updateMassWidthIfSet(listName, motherMass, motherWidth);
553 if (motherWidth == 0.) {
554 motherWidth = m_stableParticleWidth * Unit::GeV;
555 B2WARNING(
"Using artificial width for " << pdgdb->GetParticle(mother->getPDGCode())->GetName() <<
" : " << motherWidth <<
" GeV");
558 auto dfdextPlusMinus = getTwoBodyToLocalTransform(*mother, motherMass);
559 std::vector<std::pair<std::vector<gbl::GblPoint>, TMatrixD> > daughters;
561 daughters.push_back({
gbl->collectGblPoints(track12[0], track12[0]->getCardinalRep()), dfdextPlusMinus.first});
562 daughters.push_back({
gbl->collectGblPoints(track12[1], track12[1]->getCardinalRep()), dfdextPlusMinus.second});
564 TMatrixDSym massPrec(1); massPrec(0, 0) = 1. / motherWidth / motherWidth;
565 TVectorD massResidual(1); massResidual = - (mother->getMass() - motherMass);
567 TVectorD extMeasurements(1);
568 extMeasurements[0] = massResidual[0];
570 TMatrixD extDeriv(1, 9);
576 combined.
fit(chi2, ndf, lostWeight);
579 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
580 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
581 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
582 if (eventT0.isValid() && eventT0->hasEventT0()) {
583 evt0 = eventT0->getEventT0();
584 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
588 B2RESULT(
"Mass(PDG) + vertex constrained fit results NDF = " << ndf <<
" Chi2/NDF = " << chi2 /
double(ndf));
590 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(combined);
595 for (
auto listName : m_primaryMassTwoBodyDecays) {
602 double motherMass = beam->getMass();
603 double motherWidth = sqrt((beam->getCovHER() + beam->getCovLER())(0, 0));
605 updateMassWidthIfSet(listName, motherMass, motherWidth);
607 for (
unsigned int iParticle = 0; iParticle < list->getListSize(); ++iParticle) {
609 auto mother = list->getParticle(iParticle);
610 auto track12 = getParticlesTracks(mother->getDaughters());
611 if (track12.size() != 2) {
612 B2ERROR(
"Did not get 2 fitted tracks. Skipping this mother.");
616 auto dfdextPlusMinus = getTwoBodyToLocalTransform(*mother, motherMass);
617 std::vector<std::pair<std::vector<gbl::GblPoint>, TMatrixD> > daughters;
619 daughters.push_back({
gbl->collectGblPoints(track12[0], track12[0]->getCardinalRep()), dfdextPlusMinus.first});
620 daughters.push_back({
gbl->collectGblPoints(track12[1], track12[1]->getCardinalRep()), dfdextPlusMinus.second});
622 TMatrixDSym massPrec(1); massPrec(0, 0) = 1. / motherWidth / motherWidth;
623 TVectorD massResidual(1); massResidual = - (mother->getMass() - motherMass);
625 TVectorD extMeasurements(1);
626 extMeasurements[0] = massResidual[0];
628 TMatrixD extDeriv(1, 9);
634 combined.
fit(chi2, ndf, lostWeight);
635 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
636 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
637 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
638 if (eventT0.isValid() && eventT0->hasEventT0()) {
639 evt0 = eventT0->getEventT0();
640 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
644 B2RESULT(
"Mass constrained fit results NDF = " << ndf <<
" Chi2/NDF = " << chi2 /
double(ndf));
646 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(combined);
651 for (
auto listName : m_primaryMassVertexTwoBodyDecays) {
658 double motherMass = beam->getMass();
659 double motherWidth = sqrt((beam->getCovHER() + beam->getCovLER())(0, 0));
661 updateMassWidthIfSet(listName, motherMass, motherWidth);
663 for (
unsigned int iParticle = 0; iParticle < list->getListSize(); ++iParticle) {
665 auto mother = list->getParticle(iParticle);
666 auto track12 = getParticlesTracks(mother->getDaughters());
667 if (track12.size() != 2) {
668 B2ERROR(
"Did not get 2 fitted tracks. Skipping this mother.");
672 auto dfdextPlusMinus = getTwoBodyToLocalTransform(*mother, motherMass);
673 std::vector<std::pair<std::vector<gbl::GblPoint>, TMatrixD> > daughters;
675 daughters.push_back({
gbl->collectGblPoints(track12[0], track12[0]->getCardinalRep()), dfdextPlusMinus.first});
676 daughters.push_back({
gbl->collectGblPoints(track12[1], track12[1]->getCardinalRep()), dfdextPlusMinus.second});
678 TMatrixDSym vertexPrec(get<TMatrixDSym>(getPrimaryVertexAndCov()).Invert());
679 B2Vector3D vertexResidual = - (mother->getVertex() - get<B2Vector3D>(getPrimaryVertexAndCov()));
681 TMatrixDSym massPrec(1); massPrec(0, 0) = 1. / motherWidth / motherWidth;
682 TVectorD massResidual(1); massResidual = - (mother->getMass() - motherMass);
684 TMatrixDSym extPrec(4); extPrec.Zero();
685 extPrec.SetSub(0, 0, vertexPrec);
686 extPrec(3, 3) = massPrec(0, 0);
688 TVectorD extMeasurements(4);
689 extMeasurements[0] = vertexResidual[0];
690 extMeasurements[1] = vertexResidual[1];
691 extMeasurements[2] = vertexResidual[2];
692 extMeasurements[3] = massResidual[0];
694 TMatrixD extDeriv(4, 9);
703 combined.
fit(chi2, ndf, lostWeight);
704 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
705 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
706 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
707 if (eventT0.isValid() && eventT0->hasEventT0()) {
708 evt0 = eventT0->getEventT0();
709 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
713 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(combined);
715 B2RESULT(
"Mass + vertex constrained fit results NDF = " << ndf <<
" Chi2/NDF = " << chi2 /
double(ndf));
720 for (
auto listName : m_primaryTwoBodyDecays) {
721 B2WARNING(
"This should NOT be used for production of calibration constants for the real detector (yet)!");
730 double M = beam->getMass();
731 double E_HER = beam->getHER().E();
732 double E_LER = beam->getLER().E();
734 double pz = (beam->getHER().Vect() + beam->getLER().Vect())[2];
735 double E = (beam->getHER() + beam->getLER()).E();
737 double motherMass = beam->getMass();
738 double motherWidth = sqrt((E_HER / M) * (E_HER / M) * beam->getCovLER()(0, 0) + (E_LER / M) * (E_LER / M) * beam->getCovHER()(0,
741 updateMassWidthIfSet(listName, motherMass, motherWidth);
743 for (
unsigned int iParticle = 0; iParticle < list->getListSize(); ++iParticle) {
745 B2WARNING(
"Two body decays with full kinematic constraint not yet correct - need to resolve strange covariance provided by BeamParameters!");
747 auto mother = list->getParticle(iParticle);
749 auto track12 = getParticlesTracks(mother->getDaughters());
750 if (track12.size() != 2) {
751 B2ERROR(
"Did not get exactly 2 fitted tracks. Skipping this mother in list " << listName);
755 auto dfdextPlusMinus = getTwoBodyToLocalTransform(*mother, motherMass);
756 std::vector<std::pair<std::vector<gbl::GblPoint>, TMatrixD> > daughters;
758 daughters.push_back({
gbl->collectGblPoints(track12[0], track12[0]->getCardinalRep()), dfdextPlusMinus.first});
759 daughters.push_back({
gbl->collectGblPoints(track12[1], track12[1]->getCardinalRep()), dfdextPlusMinus.second});
761 TMatrixDSym extCov(7); extCov.Zero();
764 extCov.SetSub(0, 0, get<TMatrixDSym>(getPrimaryVertexAndCov()));
770 TMatrixD dBoost_dVect(3, 3);
771 dBoost_dVect(0, 0) = 0.; dBoost_dVect(0, 1) = 1. / pz; dBoost_dVect(0, 2) = 0.;
772 dBoost_dVect(1, 0) = 0.; dBoost_dVect(1, 1) = 0.; dBoost_dVect(1, 2) = 1. / pz;
773 dBoost_dVect(2, 0) = pz / E; dBoost_dVect(2, 1) = 0.; dBoost_dVect(2, 2) = 0.;
775 TMatrixD dVect_dBoost(3, 3);
776 dVect_dBoost(0, 0) = 0.; dVect_dBoost(0, 1) = 0.; dVect_dBoost(0, 2) = E / pz;
777 dVect_dBoost(1, 0) = pz; dVect_dBoost(1, 1) = 0.; dVect_dBoost(1, 2) = 0.;
778 dVect_dBoost(2, 0) = 0.; dVect_dBoost(2, 1) = pz; dVect_dBoost(2, 2) = 0.;
780 TMatrixD covBoost(3, 3);
781 for (
int i = 0; i < 3; ++i) {
782 for (
int j = i; j < 3; ++j) {
783 covBoost(j, i) = covBoost(i, j) = (beam->getCovHER() + beam->getCovLER())(i, j);
789 if (covBoost(1, 1) == 0.) covBoost(1, 1) = 1.e-4;
790 if (covBoost(2, 2) == 0.) covBoost(2, 2) = 1.e-4;
792 TMatrixD covVect = dBoost_dVect * covBoost * dVect_dBoost;
794 extCov.SetSub(3, 3, covVect);
796 extCov(6, 6) = motherWidth * motherWidth;
797 auto extPrec = extCov; extPrec.Invert();
799 TVectorD extMeasurements(7);
800 extMeasurements[0] = - (mother->getVertex() - get<B2Vector3D>(getPrimaryVertexAndCov()))[0];
801 extMeasurements[1] = - (mother->getVertex() - get<B2Vector3D>(getPrimaryVertexAndCov()))[1];
802 extMeasurements[2] = - (mother->getVertex() - get<B2Vector3D>(getPrimaryVertexAndCov()))[2];
803 extMeasurements[3] = - (mother->getMomentum() - (beam->getHER().Vect() + beam->getLER().Vect()))[0];
804 extMeasurements[4] = - (mother->getMomentum() - (beam->getHER().Vect() + beam->getLER().Vect()))[1];
805 extMeasurements[5] = - (mother->getMomentum() - (beam->getHER().Vect() + beam->getLER().Vect()))[2];
806 extMeasurements[6] = - (mother->getMass() - motherMass);
808 B2INFO(
"mother mass = " << mother->getMass() <<
" and beam mass = " << beam->getMass());
810 TMatrixD extDeriv(7, 9);
823 if (m_calibrateVertex || m_calibrateKinematics) {
824 B2WARNING(
"Primary vertex+kinematics calibration not (yet?) fully implemented!");
825 B2WARNING(
"This code is highly experimental and has (un)known issues!");
828 TMatrixD derivatives(9, 6);
829 std::vector<int> labels;
832 if (m_calibrateVertex) {
833 derivatives(0, 0) = 1.;
834 derivatives(1, 1) = 1.;
835 derivatives(2, 2) = 1.;
836 GlobalLabel label = GlobalLabel::construct<BeamSpot>(0, 0);
837 labels.push_back(label.setParameterId(1));
838 labels.push_back(label.setParameterId(2));
839 labels.push_back(label.setParameterId(3));
846 if (m_calibrateKinematics) {
847 derivatives(3, 3) = mother->getMomentumMagnitude();
848 derivatives(4, 4) = mother->getMomentumMagnitude();
849 derivatives(8, 5) = (beam->getLER().E() + beam->getHER().E()) / beam->getMass();
851 GlobalLabel label = GlobalLabel::construct<BeamSpot>(0, 0);
852 labels.push_back(label.setParameterId(4));
853 labels.push_back(label.setParameterId(5));
854 labels.push_back(label.setParameterId(6));
868 std::vector<int> lab(globals); TMatrixD der(globals);
871 TMatrixD dTwoBody_dExt(9, 7);
872 dTwoBody_dExt.Zero();
874 dTwoBody_dExt(0, 0) = 1.;
875 dTwoBody_dExt(1, 1) = 1.;
876 dTwoBody_dExt(2, 2) = 1.;
878 dTwoBody_dExt(3, 3) = 1.;
879 dTwoBody_dExt(4, 4) = 1.;
880 dTwoBody_dExt(5, 5) = 1.;
882 dTwoBody_dExt(8, 6) = 1.;
884 const TMatrixD dLocal_dExt = dfdextPlusMinus.first * dTwoBody_dExt;
885 TMatrixD dLocal_dExt_T = dLocal_dExt; dLocal_dExt_T.T();
894 TDecompSVD svd(dLocal_dExt_T);
895 TMatrixD dExt_dLocal = svd.Invert().T();
912 for (
int i = 0; i < 7; ++i) {
913 for (
int j = 0; j < 5; ++j) {
914 if (fabs(dExt_dLocal(i, j)) < 1.e-6)
915 dExt_dLocal(i, j) = 0.;
918 const TVectorD locRes = dLocal_dExt * extMeasurements;
919 const TMatrixD locPrec = dLocal_dExt * extPrec * dExt_dLocal;
921 TMatrixDSym locPrecSym(5); locPrecSym.Zero();
922 for (
int i = 0; i < 5; ++i) {
923 for (
int j = i; j < 5; ++j) {
925 locPrecSym(j, i) = locPrecSym(i, j) = (fabs(locPrec(i, j)) > 1.e-6) ? locPrec(i, j) : 0.;
929 daughters[0].first[0].addMeasurement(locRes, locPrecSym);
931 daughters[0].first[0].addGlobals(lab, dfdextPlusMinus.first * der);
943 combined.
fit(chi2, ndf, lostWeight);
944 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
945 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
946 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
947 if (eventT0.isValid() && eventT0->hasEventT0()) {
948 evt0 = eventT0->getEventT0();
949 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
953 B2RESULT(
"Full kinematic-constrained fit (calibration version) results NDF = " << ndf <<
" Chi2/NDF = " << chi2 /
double(ndf));
955 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(combined);
963 combined.
fit(chi2, ndf, lostWeight);
964 getObjectPtr<TH1I>(
"ndf")->Fill(ndf);
965 getObjectPtr<TH1F>(
"chi2_per_ndf")->Fill(chi2 /
double(ndf));
966 getObjectPtr<TH1F>(
"pval")->Fill(TMath::Prob(chi2, ndf));
967 if (eventT0.isValid() && eventT0->hasEventT0()) {
968 evt0 = eventT0->getEventT0();
969 getObjectPtr<TH1F>(
"evt0")->Fill(evt0);
973 B2RESULT(
"Full kinematic-constrained fit results NDF = " << ndf <<
" Chi2/NDF = " << chi2 /
double(ndf));
975 if (TMath::Prob(chi2, ndf) > m_minPValue) storeTrajectory(combined);
981 void MillepedeCollectorModule::closeRun()
986 auto mille = getObjectPtr<MilleData>(
"mille");
991 void MillepedeCollectorModule::finish()
997 B2ERROR(
"Cannot register binaries in FileCatalog.");
1002 const std::vector<string> parents = {fileMetaData->getLfn()};
1003 for (
auto binary : getObjectPtr<MilleData>(
"mille")->getFiles()) {
1006 milleMetaData.
setLfn(
"");
1008 FileCatalog::Instance().registerFile(binary, milleMetaData);
1017 m_currentGblData = trajectory.getData();
1019 m_currentGblData.clear();
1021 if (!m_currentGblData.empty())
1022 getObjectPtr<TTree>(
"GblDataTree")->Fill();
1024 getObjectPtr<MilleData>(
"mille")->fill(trajectory);
1028 std::string MillepedeCollectorModule::getUniqueMilleName()
1031 string name = getName();
1033 name +=
"-e" + to_string(emd->getExperiment());
1034 name +=
"-r" + to_string(emd->getRun());
1035 name +=
"-ev" + to_string(emd->getEvent());
1037 if (ProcHandler::parallelProcessingUsed())
1038 name +=
"-pid" + to_string(ProcHandler::EvtProcID());
1053 auto relatedRecoHitInformation =
1058 if (recoHitInformation.getFlag() == RecoHitInformation::c_pruned) {
1059 B2FATAL(
"Found pruned point in RecoTrack. Pruned tracks cannot be used in MillepedeCollector.");
1062 if (recoHitInformation.getTrackingDetector() != RecoHitInformation::c_CDC)
continue;
1069 if (not kalmanFitterInfo) {
1072 std::vector<double> weights = kalmanFitterInfo->getWeights();
1073 if (weights.size() == 2) {
1074 if (weights.at(0) > weights.at(1))
1075 recoHitInformation.setRightLeftInformation(RecoHitInformation::c_left);
1076 else if (weights.at(0) < weights.at(1))
1077 recoHitInformation.setRightLeftInformation(RecoHitInformation::c_right);
1079 double weightLR = weights.at(0) + weights.at(1);
1080 if (weightLR < m_minCDCHitWeight) recoHitInformation.setUseInFit(
false);
1081 sumCDCWeights += weightLR - 1.;
1088 getObjectPtr<TH1F>(
"cdc_hit_fraction")->Fill(usedCDCHitFraction);
1089 if (usedCDCHitFraction < m_minUsedCDCHitFraction)
1093 B2ERROR(
"Error in checking DAF weights from previous fit to resolve hit ambiguity. Why? Failed fit points in DAF? Skip track to be sure.");
1098 gbl->setOptions(m_internalIterations,
true,
true, m_externalIterations, m_recalcJacobians);
1117 genfitMeasurementFactory.
addProducer(Const::PXD, PXDProducer);
1123 genfitMeasurementFactory.
addProducer(Const::SVD, SVDProducer);
1129 genfitMeasurementFactory.
addProducer(Const::CDC, CDCProducer);
1135 genfitMeasurementFactory.
addProducer(Const::BKLM, BKLMProducer);
1141 genfitMeasurementFactory.
addProducer(Const::EKLM, EKLMProducer);
1146 std::vector<std::shared_ptr<PXDBaseMeasurementCreator>> pxdMeasurementCreators = { std::shared_ptr<PXDBaseMeasurementCreator>(
new PXDCoordinateMeasurementCreator(genfitMeasurementFactory)) };
1147 std::vector<std::shared_ptr<SVDBaseMeasurementCreator>> svdMeasurementCreators = { std::shared_ptr<SVDBaseMeasurementCreator>(
new SVDCoordinateMeasurementCreator(genfitMeasurementFactory)) };
1150 std::vector<std::shared_ptr<CDCBaseMeasurementCreator>> cdcMeasurementCreators = { std::shared_ptr<CDCBaseMeasurementCreator>(
new CDCCoordinateMeasurementCreator(genfitMeasurementFactory)) };
1151 std::vector<std::shared_ptr<BKLMBaseMeasurementCreator>> bklmMeasurementCreators = { std::shared_ptr<BKLMBaseMeasurementCreator>(
new BKLMCoordinateMeasurementCreator(genfitMeasurementFactory)) };
1152 std::vector<std::shared_ptr<EKLMBaseMeasurementCreator>> eklmMeasurementCreators = { std::shared_ptr<EKLMBaseMeasurementCreator>(
new EKLMCoordinateMeasurementCreator(genfitMeasurementFactory)) };
1155 std::vector<std::shared_ptr<BaseMeasurementCreator>> additionalMeasurementCreators = {};
1156 factory.
resetMeasurementCreators(pxdMeasurementCreators, svdMeasurementCreators, cdcMeasurementCreators, bklmMeasurementCreators,
1157 eklmMeasurementCreators, additionalMeasurementCreators);
1160 auto& gfTrack = RecoTrackGenfitAccess::getGenfitTrack(recoTrack);
1162 int currentPdgCode = TrackFitter::createCorrectPDGCodeForChargedStable(Const::muon, recoTrack);
1164 currentPdgCode = particle->getPDGCode();
1166 genfit::AbsTrackRep* trackRep = RecoTrackGenfitAccess::createOrReturnRKTrackRep(recoTrack, currentPdgCode);
1167 gfTrack.setCardinalRep(gfTrack.getIdForRep(trackRep));
1170 B2Vector3D vertexPos = particle->getVertex();
1171 B2Vector3D vertexMom = particle->getMomentum();
1172 gfTrack.setStateSeed(vertexPos, vertexMom);
1175 B2Vector3D vertexRPhiDir(vertexPos[0], vertexPos[1], 0);
1182 vertexSOP.setPlane(vertexPlane);
1183 vertexSOP.setPosMom(vertexPos, vertexMom);
1184 TMatrixDSym vertexCov(5);
1185 vertexCov.UnitMatrix();
1191 gfTrack.insertMeasurement(vertex, 0);
1195 for (
unsigned int i = 0; i < gfTrack.getNumPoints() - 1; ++i) {
1199 i)->getRawMeasurement(0));
1201 i + 1)->getRawMeasurement(0));
1203 if (planarMeas1 != NULL && planarMeas2 != NULL &&
1204 planarMeas1->getDetId() == planarMeas2->getDetId() &&
1205 planarMeas1->getPlaneId() != -1 &&
1206 planarMeas1->getPlaneId() == planarMeas2->getPlaneId()) {
1213 if (hit1->
isU() && !hit2->
isU()) {
1216 }
else if (!hit1->
isU() && hit2->
isU()) {
1224 gfTrack.insertMeasurement(hit, i);
1226 gfTrack.deletePoint(i + 1);
1227 gfTrack.deletePoint(i + 1);
1231 }
catch (std::exception& e) {
1233 B2ERROR(
"SVD Cluster combination failed. This is symptomatic of pruned tracks. MillepedeCollector cannot process pruned tracks.");
1238 gbl->processTrackWithRep(&gfTrack, gfTrack.getCardinalRep(),
true);
1243 B2ERROR(
"GBL fit failed.");
1250 std::vector< genfit::Track* > MillepedeCollectorModule::getParticlesTracks(std::vector<Particle*> particles,
bool addVertexPoint)
1252 std::vector< genfit::Track* > tracks;
1253 for (
auto particle : particles) {
1254 auto belle2Track = particle->getTrack();
1256 B2WARNING(
"No Belle2::Track for particle (particle->X");
1265 auto recoTrack = belle2Track->getRelatedTo<
RecoTrack>();
1268 B2WARNING(
"No related RecoTrack for Belle2::Track (particle->Track->X)");
1273 if (!fitRecoTrack(*recoTrack, (addVertexPoint) ? particle :
nullptr))
1276 auto& track = RecoTrackGenfitAccess::getGenfitTrack(*recoTrack);
1278 if (!track.hasFitStatus()) {
1279 B2WARNING(
"Track has no fit status");
1284 B2WARNING(
"Track FitStatus is not GblFitStatus.");
1287 if (!fs->isFittedWithReferenceTrack()) {
1288 B2WARNING(
"Track is not fitted with reference track.");
1292 tracks.push_back(&track);
1298 std::pair<TMatrixD, TMatrixD> MillepedeCollectorModule::getTwoBodyToLocalTransform(
Particle& mother,
1301 std::vector<TMatrixD> result;
1303 double px = mother.getMomentum()[0];
1304 double py = mother.getMomentum()[1];
1305 double pz = mother.getMomentum()[2];
1306 double pt = sqrt(px * px + py * py);
1307 double p = mother.getMomentumMagnitude();
1308 double M = motherMass;
1309 double m = mother.getDaughter(0)->getPDGMass();
1311 if (mother.getNDaughters() != 2
1312 || m != mother.getDaughter(1)->getPDGMass()) B2FATAL(
"Only two same-mass daughters (V0->f+f- decays) allowed.");
1315 TMatrixD mother2lab(3, 3);
1316 mother2lab(0, 0) = px * pz / pt / p; mother2lab(0, 1) = - py / pt; mother2lab(0, 2) = px / p;
1317 mother2lab(1, 0) = py * pz / pt / p; mother2lab(1, 1) = px / pt; mother2lab(1, 2) = py / p;
1318 mother2lab(2, 0) = - pt / p; mother2lab(2, 1) = 0; mother2lab(2, 2) = pz / p;
1319 auto lab2mother = mother2lab; lab2mother.Invert();
1324 TLorentzVector fourVector1 = mother.getDaughter(0)->get4Vector();
1325 TLorentzVector fourVector2 = mother.getDaughter(1)->get4Vector();
1327 auto mom1 = lab2mother * boostedFrame.
getMomentum(fourVector1).Vect();
1328 auto mom2 = lab2mother * boostedFrame.
getMomentum(fourVector2).Vect();
1331 auto avgMom = 0.5 * (mom1 - mom2);
1332 if (avgMom[2] < 0.) {
1338 double theta = atan2(avgMom.Perp(), avgMom[2]);
1339 double phi = atan2(avgMom[1], avgMom[0]);
1340 if (phi < 0.) phi += 2. * TMath::Pi();
1342 double alpha = M / 2. / m;
1343 double c1 = m * sqrt(alpha * alpha - 1.);
1344 double c2 = 0.5 * sqrt((alpha * alpha - 1.) / alpha / alpha * (p * p + M * M));
1346 double p3 = p * p * p;
1347 double pt3 = pt * pt * pt;
1350 for (
auto& track : getParticlesTracks(mother.getDaughters())) {
1353 TMatrixD R = mother2lab;
1354 B2Vector3D P(sign * c1 * sin(theta) * cos(phi),
1355 sign * c1 * sin(theta) * sin(phi),
1356 p / 2. + sign * c2 * cos(theta));
1358 TMatrixD dRdpx(3, 3);
1359 dRdpx(0, 0) = - pz * (pow(px, 4.) - pow(py, 4.) - py * py * pz * pz) / pt3 / p3;
1360 dRdpx(0, 1) = px * py / pt3;
1361 dRdpx(0, 2) = (py * py + pz * pz) / p3;
1363 dRdpx(1, 0) = - px * py * pz * (2. * px * px + 2. * py * py + pz * pz) / pt3 / p3;
1364 dRdpx(1, 1) = - py * py / pt3;
1365 dRdpx(1, 2) = px * py / p3;
1367 dRdpx(2, 0) = - px * pz * pz / pt / p3;
1369 dRdpx(2, 2) = - px * pz / p3;
1371 TMatrixD dRdpy(3, 3);
1372 dRdpy(0, 0) = - px * py * pz * (2. * px * px + 2. * py * py + pz * pz) / pt3 / p3;
1373 dRdpy(0, 1) = - px * px / pt3;
1374 dRdpy(0, 2) = px * pz / p3;
1376 dRdpy(1, 0) = - pz * (- pow(px, 4.) - px * px * pz * pz + pow(py, 4.)) / pt3 / p3;
1377 dRdpy(1, 1) = px * py / pt3;
1378 dRdpy(1, 2) = (px * px + pz * pz) / p3;
1380 dRdpy(2, 0) = - py * pz * pz / pt / p3;
1382 dRdpy(2, 2) = - py * pz / p3;
1384 TMatrixD dRdpz(3, 3);
1385 dRdpz(0, 0) = px * pt / p3;
1387 dRdpz(0, 2) = - px * pz / p3;
1389 dRdpz(1, 0) = py * pt / p3;
1391 dRdpz(1, 2) = py * pz / p3;
1393 dRdpz(2, 0) = pz * pt / p3;
1395 dRdpz(2, 2) = (px * px + py * py) / p3;
1397 auto K = 1. / 2. / p + sign * cos(theta) * m * m * (M * M / 4. / m / m - 1.) / M / M / sqrt(m * m * (M * M / 4. / m / m - 1.) *
1398 (M * M + p * p) / M / M);
1405 sign * c1 * cos(theta) * sin(phi),
1406 sign * c2 * (- sin(theta)));
1410 sign * c1 * sin(theta) * cos(phi),
1413 double dc1dM = m * M / (2. * sqrt(M * M - 4. * m * m));
1414 double dc2dM = M * (4. * m * m * p * p + pow(M, 4)) / (2 * M * M * M * sqrt((M * M - 4. * m * m) * (p * p + M * M)));
1417 sign * sin(theta) * sin(phi) * dc1dM,
1418 sign * cos(theta) * dc2dM);
1420 TMatrixD dpdz(3, 6);
1421 dpdz(0, 0) = dpdpx(0); dpdz(0, 1) = dpdpy(0); dpdz(0, 2) = dpdpz(0); dpdz(0, 3) = dpdtheta(0); dpdz(0, 4) = dpdphi(0);
1422 dpdz(0, 5) = dpdM(0);
1423 dpdz(1, 0) = dpdpx(1); dpdz(1, 1) = dpdpy(1); dpdz(1, 2) = dpdpz(1); dpdz(1, 3) = dpdtheta(1); dpdz(1, 4) = dpdphi(1);
1424 dpdz(1, 5) = dpdM(1);
1425 dpdz(2, 0) = dpdpx(2); dpdz(2, 1) = dpdpy(2); dpdz(2, 2) = dpdpz(2); dpdz(2, 3) = dpdtheta(2); dpdz(2, 4) = dpdphi(2);
1426 dpdz(2, 5) = dpdM(2);
1428 TMatrixD dqdv = getGlobalToLocalTransform(track->getFittedState()).GetSub(0, 4, 0, 2);
1429 TMatrixD dqdp = getGlobalToLocalTransform(track->getFittedState()).GetSub(0, 4, 3, 5);
1430 TMatrixD dfdvz(5, 9);
1431 dfdvz.SetSub(0, 0, dqdv);
1432 dfdvz.SetSub(0, 3, dqdp * dpdz);
1434 result.push_back(dfdvz);
1440 return {result[0], result[1]};
1446 const B2Vector3D& U(state.getPlane()->getU());
1447 const B2Vector3D& V(state.getPlane()->getV());
1448 const B2Vector3D& O(state.getPlane()->getO());
1449 const B2Vector3D& W(state.getPlane()->getNormal());
1451 const double* state5 = state.getState().GetMatrixArray();
1455 const TVectorD& auxInfo = state.getAuxInfo();
1456 if (auxInfo.GetNrows() == 2
1457 || auxInfo.GetNrows() == 1)
1458 spu = state.getAuxInfo()(0);
1462 state7[0] = O.
X() + state5[3] * U.
X() + state5[4] * V.
X();
1463 state7[1] = O.
Y() + state5[3] * U.
Y() + state5[4] * V.
Y();
1464 state7[2] = O.
Z() + state5[3] * U.
Z() + state5[4] * V.
Z();
1466 state7[3] = spu * (W.
X() + state5[1] * U.
X() + state5[2] * V.
X());
1467 state7[4] = spu * (W.
Y() + state5[1] * U.
Y() + state5[2] * V.
Y());
1468 state7[5] = spu * (W.
Z() + state5[1] * U.
Z() + state5[2] * V.
Z());
1471 double norm = 1. / sqrt(state7[3] * state7[3] + state7[4] * state7[4] + state7[5] * state7[5]);
1472 for (
unsigned int i = 3; i < 6; ++i) state7[i] *= norm;
1474 state7[6] = state5[0];
1476 const double AtU = state7[3] * U.
X() + state7[4] * U.
Y() + state7[5] * U.
Z();
1477 const double AtV = state7[3] * V.
X() + state7[4] * V.
Y() + state7[5] * V.
Z();
1478 const double AtW = state7[3] * W.
X() + state7[4] * W.
Y() + state7[5] * W.
Z();
1482 const double qop = state7[6];
1483 const double p = state.getCharge() / qop;
1485 TMatrixD J_Mp_6x5(6, 5);
1489 J_Mp_6x5(0, 3) = U.
X();
1490 J_Mp_6x5(1, 3) = U.
Y();
1491 J_Mp_6x5(2, 3) = U.
Z();
1493 J_Mp_6x5(0, 4) = V.
X();
1494 J_Mp_6x5(1, 4) = V.
Y();
1495 J_Mp_6x5(2, 4) = V.
Z();
1498 double fact = (-1.) * qop / p;
1499 J_Mp_6x5(3, 0) = fact * state7[3];
1500 J_Mp_6x5(4, 0) = fact * state7[4];
1501 J_Mp_6x5(5, 0) = fact * state7[5];
1503 fact = 1. / (p * AtW * AtW);
1504 J_Mp_6x5(3, 1) = fact * (U.
X() * AtW - W.
X() * AtU);
1505 J_Mp_6x5(4, 1) = fact * (U.
Y() * AtW - W.
Y() * AtU);
1506 J_Mp_6x5(5, 1) = fact * (U.
Z() * AtW - W.
Z() * AtU);
1508 J_Mp_6x5(3, 2) = fact * (V.
X() * AtW - W.
X() * AtV);
1509 J_Mp_6x5(4, 2) = fact * (V.
Y() * AtW - W.
Y() * AtV);
1510 J_Mp_6x5(5, 2) = fact * (V.
Z() * AtW - W.
Z() * AtV);
1512 return J_Mp_6x5.T();
1519 const B2Vector3D& U(state.getPlane()->getU());
1520 const B2Vector3D& V(state.getPlane()->getV());
1521 const B2Vector3D& W(state.getPlane()->getNormal());
1523 const TVectorD& state5(state.getState());
1526 const TVectorD& auxInfo = state.getAuxInfo();
1527 if (auxInfo.GetNrows() == 2
1528 || auxInfo.GetNrows() == 1)
1529 spu = state.getAuxInfo()(0);
1532 pTilde[0] = spu * (W.
X() + state5(1) * U.
X() + state5(2) * V.
X());
1533 pTilde[1] = spu * (W.
Y() + state5(1) * U.
Y() + state5(2) * V.
Y());
1534 pTilde[2] = spu * (W.
Z() + state5(1) * U.
Z() + state5(2) * V.
Z());
1536 const double pTildeMag = sqrt(pTilde[0] * pTilde[0] + pTilde[1] * pTilde[1] + pTilde[2] * pTilde[2]);
1537 const double pTildeMag2 = pTildeMag * pTildeMag;
1539 const double utpTildeOverpTildeMag2 = (U.
X() * pTilde[0] + U.
Y() * pTilde[1] + U.
Z() * pTilde[2]) / pTildeMag2;
1540 const double vtpTildeOverpTildeMag2 = (V.
X() * pTilde[0] + V.
Y() * pTilde[1] + V.
Z() * pTilde[2]) / pTildeMag2;
1544 const double qop = state5(0);
1545 const double p = state.getCharge() / qop;
1547 TMatrixD J_pM_5x6(5, 6);
1551 double fact = -1. * p / (pTildeMag * qop);
1552 J_pM_5x6(0, 3) = fact * pTilde[0];
1553 J_pM_5x6(0, 4) = fact * pTilde[1];
1554 J_pM_5x6(0, 5) = fact * pTilde[2];
1556 fact = p * spu / pTildeMag;
1557 J_pM_5x6(1, 3) = fact * (U.
X() - pTilde[0] * utpTildeOverpTildeMag2);
1558 J_pM_5x6(1, 4) = fact * (U.
Y() - pTilde[1] * utpTildeOverpTildeMag2);
1559 J_pM_5x6(1, 5) = fact * (U.
Z() - pTilde[2] * utpTildeOverpTildeMag2);
1561 J_pM_5x6(2, 3) = fact * (V.
X() - pTilde[0] * vtpTildeOverpTildeMag2);
1562 J_pM_5x6(2, 4) = fact * (V.
Y() - pTilde[1] * vtpTildeOverpTildeMag2);
1563 J_pM_5x6(2, 5) = fact * (V.
Z() - pTilde[2] * vtpTildeOverpTildeMag2);
1565 J_pM_5x6(3, 0) = U.
X();
1566 J_pM_5x6(3, 1) = U.
Y();
1567 J_pM_5x6(3, 2) = U.
Z();
1569 J_pM_5x6(4, 0) = V.
X();
1570 J_pM_5x6(4, 1) = V.
Y();
1571 J_pM_5x6(4, 2) = V.
Z();
1573 return J_pM_5x6.T();
1577 tuple<B2Vector3D, TMatrixDSym> MillepedeCollectorModule::getPrimaryVertexAndCov()
const
1580 return {beam->getIPPosition(), beam->getSizeCovMatrix()};
1583 void MillepedeCollectorModule::updateMassWidthIfSet(
string listName,
double& mass,
double& width)
1585 if (m_customMassConfig.find(listName) != m_customMassConfig.end()) {
1586 auto massWidth = m_customMassConfig.at(listName);
1587 mass = std::get<0>(massWidth);
1588 width = std::get<1>(massWidth);
This class is used to transfer CDC information to the track fit and Millepede.
This class is used to transfer PXD information to the track fit.
This class is used to transfer SVD information to the track fit.
This class is used to transfer SVD information to the track fit.
DataType Z() const
access variable Z (= .at(2) without boundary check)
DataType X() const
access variable X (= .at(0) without boundary check)
DataType Y() const
access variable Y (= .at(1) without boundary check)
Store one BKLM strip hit as a ROOT object.
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Calibration collector module base class.
Class for accessing objects in the database.
This dataobject is used only for EKLM alignment.
TrackSegmentController for use with GblFitter in Belle2.
Class to convert to/from global labels for Millepede II to/from detector & parameter identificators.
Algorithm class to translate the added detector hits (e.g.
void resetMeasurementCreators(const std::vector< std::shared_ptr< PXDBaseMeasurementCreator >> &pxdMeasurementCreators, const std::vector< std::shared_ptr< SVDBaseMeasurementCreator >> &svdMeasurementCreators, const std::vector< std::shared_ptr< CDCBaseMeasurementCreator >> &cdcMeasurementCreators, const std::vector< std::shared_ptr< BKLMBaseMeasurementCreator >> &bklmMeasurementCreators, const std::vector< std::shared_ptr< EKLMBaseMeasurementCreator >> &eklmMeasurementCreators, const std::vector< std::shared_ptr< BaseMeasurementCreator >> &additionalMeasurementCreators)
If you want to use non-default settings for the store arrays, you can create your own instances of th...
bool addMeasurements(RecoTrack &recoTrack) const
After you have filled the internal storage with measurement creators (either by providing your own or...
Mergeable class holding list of so far opened mille binaries and providing the binaries.
Calibration data collector for Millepede Algorithm.
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Class to store reconstructed particles.
This is the Reconstruction Event-Data Model Track.
const genfit::FitStatus * getTrackFitStatus(const genfit::AbsTrackRep *representation=nullptr) const
Return the track fit status for the given representation or for the cardinal one. You are not allowed...
unsigned int getNumberOfCDCHits() const
Return the number of cdc hits.
const genfit::TrackPoint * getCreatedTrackPoint(const RecoHitInformation *recoHitInformation) const
Get a pointer to the TrackPoint that was created from this hit.
genfit::AbsTrackRep * getCardinalRepresentation() const
Get a pointer to the cardinal track representation. You are not allowed to modify or delete it!
const std::string & getStoreArrayNameOfRecoHitInformation() const
Name of the store array of the reco hit informations.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
Rest frame of a particle.
virtual TLorentzVector getMomentum(const TLorentzVector &vector) const override
Get Lorentz vector in rest frame System.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
bool isU() const
Is the coordinate u or v?
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
Accessor to arrays stored in the data store.
bool isValid() const
Check wether the array was registered.
TClonesArray * getPtr() const
Raw access to the underlying TClonesArray.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
void writeConstraints(std::string txtFilename)
Write-out complete hierarchy to a text file.
void initialize(const std::vector< std::string > &components={}, const std::vector< EventMetaData > &timeSlices={})
Initialize the manager with given configuration (from MillepedeCollector)
static GlobalCalibrationManager & getInstance()
Get instance of the Manager auto& gcm = GlobalCalibrationManager::getInstance();.
Class for easier manipulation with global derivatives (and their labels)
static bool s_enablePXD
Enable PXD in hierarchy?
static bool s_enableSVD
Enable SVD in hierarchy?
static E_VXDHierarchyType s_hierarchyType
What type of hierarchy to use for VXD?
unsigned int fit(double &Chi2, int &Ndf, double &lostWeight, std::string optionList="")
Perform fit of (valid) trajectory.
bool isValid() const
Retrieve validity of trajectory.
Abstract base class for a track representation.
Exception class for error handling in GENFIT (provides storage for diagnostic information)
bool isFitted() const
Has the track been fitted?
Measurement class implementing a measurement of all track parameters.
FitStatus for use with GblFitter.
Generic GBL implementation.
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
#StateOnPlane with additional covariance matrix.
void addProducer(int detID, AbsMeasurementProducer< measurement_T > *hitProd)
Register a producer module to the factory.
Template class for a measurement producer module.
Measurement class implementing a planar hit geometry (1 or 2D).
A state with arbitrary dimension defined in a DetPlane.
Object containing AbsMeasurement and AbsFitterInfo objects.
AbsFitterInfo * getFitterInfo(const AbsTrackRep *rep=nullptr) const
Get fitterInfo for rep. Per default, use cardinal rep.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
B2Vector3< double > B2Vector3D
typedef for common usage with double
CoordinateMeasurementCreator< RecoHitInformation::UsedSVDHit, Const::SVD > SVDCoordinateMeasurementCreator
Hit to reco hit measurement creator for the SVD.
CoordinateMeasurementCreator< RecoHitInformation::UsedPXDHit, Const::PXD > PXDCoordinateMeasurementCreator
Hit to reco hit measurement creator for the PXD.
CoordinateMeasurementCreator< RecoHitInformation::UsedBKLMHit, Const::BKLM > BKLMCoordinateMeasurementCreator
Hit to reco hit measurement creator for the BKLM.
CoordinateMeasurementCreator< RecoHitInformation::UsedCDCHit, Const::CDC > CDCCoordinateMeasurementCreator
Needed for templating.
CoordinateMeasurementCreator< RecoHitInformation::UsedEKLMHit, Const::EKLM > EKLMCoordinateMeasurementCreator
Hit to reco hit measurement creator for the EKLM.
Abstract base class for different kinds of events.
Namespace for the general broken lines package.
std::shared_ptr< genfit::DetPlane > SharedPlanePtr
Shared Pointer to a DetPlane.