10#include <tracking/trackExtrapolateG4e/TrackExtrapolateG4e.h>
13#include <ecl/geometry/ECLGeometryPar.h>
14#include <framework/datastore/StoreArray.h>
15#include <framework/datastore/StoreObjPtr.h>
16#include <framework/geometry/BFieldManager.h>
17#include <framework/logging/Logger.h>
18#include <genfit/Exception.h>
19#include <klm/dataobjects/bklm/BKLMElementNumbers.h>
20#include <klm/dataobjects/bklm/BKLMStatus.h>
21#include <klm/bklm/geometry/GeometryPar.h>
22#include <klm/bklm/geometry/Module.h>
23#include <klm/dataobjects/KLMChannelIndex.h>
24#include <klm/dataobjects/KLMMuidLikelihood.h>
25#include <klm/dataobjects/KLMMuidHit.h>
26#include <klm/dataobjects/eklm/EKLMAlignmentHit.h>
27#include <klm/muid/MuidBuilder.h>
28#include <klm/muid/MuidElementNumbers.h>
29#include <mdst/dataobjects/ECLCluster.h>
30#include <mdst/dataobjects/KLMCluster.h>
31#include <mdst/dataobjects/Track.h>
32#include <simulation/kernel/ExtCylSurfaceTarget.h>
33#include <simulation/kernel/ExtManager.h>
36#include <CLHEP/Matrix/Vector.h>
37#include <CLHEP/Units/PhysicalConstants.h>
38#include <CLHEP/Units/SystemOfUnits.h>
41#include <G4ErrorFreeTrajState.hh>
42#include <G4ErrorMatrix.hh>
43#include <G4ErrorPropagatorData.hh>
44#include <G4ErrorSymMatrix.hh>
45#include <G4ParticleTable.hh>
46#include <G4PhysicalVolumeStore.hh>
47#include <G4Point3D.hh>
48#include <G4StateManager.hh>
50#include <G4StepPoint.hh>
51#include <G4ThreeVector.hh>
52#include <G4TouchableHandle.hh>
54#include <G4UImanager.hh>
55#include <G4VPhysicalVolume.hh>
56#include <G4VTouchable.hh>
63#define TWOPI (2.0*M_PI)
64#define PI_8 (0.125*M_PI)
139 std::vector<Const::ChargedStable>& hypotheses)
153 m_MinPt = std::max(0.0, minPt) * CLHEP::GeV;
154 m_MinKE = std::max(0.0, minKE) * CLHEP::GeV;
169 B2FATAL(
"Coil geometry data are not available.");
179 G4ErrorPropagatorData::GetErrorPropagatorData()->SetTarget(
m_TargetExt);
182 B2FATAL(
"Beam pipe geometry data are not available.");
183 double beampipeRadius =
m_BeamPipeGeo->getParameter(
"Lv2OutBe.R2") * CLHEP::cm;
185 beampipeRadius =
m_BeamPipeGeo->getParameter(
"Lv2OutBe.R2") * CLHEP::cm;
192 double maxKLMTrackClusterDistance,
double maxECLTrackClusterDistance,
193 double minPt,
double minKE,
bool addHitsToRecoTrack,
194 std::vector<Const::ChargedStable>& hypotheses)
232 m_MinPt = std::max(0.0, minPt) * CLHEP::GeV;
233 m_MinKE = std::max(0.0, minKE) * CLHEP::GeV;
248 B2FATAL(
"Coil geometry data are not available.");
258 G4ErrorPropagatorData::GetErrorPropagatorData()->SetTarget(
m_TargetExt);
261 B2FATAL(
"Beam pipe geometry data are not available.");
262 double beampipeRadius =
m_BeamPipeGeo->getParameter(
"Lv2OutBe.R2") * CLHEP::cm;
264 beampipeRadius =
m_BeamPipeGeo->getParameter(
"Lv2OutBe.R2") * CLHEP::cm;
279 G4ErrorPropagatorData::GetErrorPropagatorData()->SetTarget(
m_TargetMuid);
298 width =
module->getPhiStripWidth();
300 width =
module->getZStripWidth();
307 double phi = M_PI_4 * (sector - 1);
315 bklmGeometry->
getActiveMiddleRadius(klmLayer.getSection(), klmLayer.getSector(), klmLayer.getLayer());
335 B2DEBUG(20, (byMuid ?
"muid" :
"ext"));
338 B2FATAL(
"KLM channel status data are not available.");
340 B2FATAL(
"KLM strip efficiency data are not available.");
342 B2FATAL(
"KLM likelihood parameters are not available.");
347 delete muidBuilder.second;
352 for (
int pdg : muidPdgCodes)
361 if (G4StateManager::GetStateManager()->GetCurrentState() == G4State_Idle) {
362 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
365 G4ThreeVector directionAtIP, positionG4e, momentumG4e;
366 G4ErrorTrajErr covG4e(5);
371 G4ErrorPropagatorData::GetErrorPropagatorData()->SetTarget(
m_TargetMuid);
372 std::vector<std::pair<ECLCluster*, G4ThreeVector> > eclClusterInfo(
m_eclClusters.getEntries());
375 eclClusterInfo[c].second = G4ThreeVector(
m_eclClusters[c]->getClusterPosition().X(),
379 std::vector<std::pair<KLMCluster*, G4ThreeVector> > klmClusterInfo(
m_klmClusters.getEntries());
382 klmClusterInfo[c].second = G4ThreeVector(
m_klmClusters[c]->getClusterPosition().X(),
387 std::vector<std::map<const Track*, double> > bklmHitUsed(
m_klmHit2ds.getEntries());
390 int pdgCode = hypothesis.getPDGCode();
393 G4ErrorFreeTrajState g4eState(
"g4e_mu+", G4ThreeVector(), G4ThreeVector());
395 swim(extState, g4eState, &eclClusterInfo, &klmClusterInfo, &bklmHitUsed);
399 G4ErrorPropagatorData::GetErrorPropagatorData()->SetTarget(
m_TargetExt);
402 int pdgCode = hypothesis.getPDGCode();
404 G4ErrorFreeTrajState g4eState(
"g4e_mu+", G4ThreeVector(), G4ThreeVector());
406 swim(extState, g4eState);
427 delete muidBuilder.second;
445 const G4ThreeVector& position,
446 const G4ThreeVector& momentum,
447 const G4ErrorSymMatrix& covariance)
449 bool isCosmic =
false;
454 extMgr->
Initialize(
"Ext",
"default", 0.0, 0.25,
false, 0, std::vector<std::string>());
459 G4UImanager::GetUIpointer()->ApplyCommand(
"/geant4e/limits/stepLength 250 mm");
460 G4UImanager::GetUIpointer()->ApplyCommand(
"/geant4e/limits/magField 0.001");
461 G4UImanager::GetUIpointer()->ApplyCommand(
"/geant4e/limits/energyLoss 0.05");
467 if (G4StateManager::GetStateManager()->GetCurrentState() == G4State_Idle) {
468 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
471 G4ErrorPropagatorData::GetErrorPropagatorData()->SetTarget(
m_TargetExt);
476 G4ThreeVector positionG4e = position * CLHEP::cm;
477 G4ThreeVector momentumG4e = momentum * CLHEP::GeV;
479 momentumG4e = -momentumG4e;
480 G4ErrorSymMatrix covarianceG4e(5, 0);
482 G4String nameG4e(
"g4e_" + G4ParticleTable::GetParticleTable()->FindParticle(pdgCode)->GetParticleName());
483 G4ErrorFreeTrajState g4eState(nameG4e, positionG4e, momentumG4e, covarianceG4e);
484 ExtState extState = {
nullptr, pdgCode, isCosmic, tof, 0.0,
485 momentumG4e.unit(), 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
false
487 swim(extState, g4eState);
492 const std::vector<std::pair<ECLCluster*, G4ThreeVector> >* eclClusterInfo,
493 const std::vector<std::pair<KLMCluster*, G4ThreeVector> >* klmClusterInfo,
494 std::vector<std::map<const Track*, double> >* bklmHitUsed)
498 if (g4eState.GetMomentum().perp() <=
m_MinPt)
500 if (
m_TargetMuid->GetDistanceFromPoint(g4eState.GetPosition()) < 0.0)
502 G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable()->FindParticle(extState.
pdgCode);
503 double mass = particle->GetPDGMass();
504 double minPSq = (mass +
m_MinKE) * (mass +
m_MinKE) - mass * mass;
506 std::vector<double> eclClusterDistance;
507 std::vector<ExtHit> eclHit1, eclHit2, eclHit3;
508 if (eclClusterInfo !=
nullptr) {
509 eclClusterDistance.resize(eclClusterInfo->size(), 1.0E10);
510 ExtHit tempExtHit(.0, extState.
pdgCode, Const::EDetector::ECL, 0, EXT_FIRST,
512 G4ThreeVector(), G4ThreeVector(), G4ErrorSymMatrix(6));
513 eclHit1.resize(eclClusterInfo->size(), tempExtHit);
514 eclHit2.resize(eclClusterInfo->size(), tempExtHit);
515 eclHit3.resize(eclClusterInfo->size(), tempExtHit);
518 std::vector<TrackClusterSeparation> klmHit;
519 if (klmClusterInfo !=
nullptr) {
520 klmHit.resize(klmClusterInfo->size());
524 if (extState.
track !=
nullptr)
526 G4ErrorMode propagationMode = (extState.
isCosmic ? G4ErrorMode_PropBackwards : G4ErrorMode_PropForwards);
527 m_ExtMgr->InitTrackPropagation(propagationMode);
529 const G4int errCode =
m_ExtMgr->PropagateOneStep(&g4eState, propagationMode);
530 G4Track* track = g4eState.GetG4Track();
531 const G4Step* step = track->GetStep();
532 const G4StepPoint* preStepPoint = step->GetPreStepPoint();
533 const G4StepPoint* postStepPoint = step->GetPostStepPoint();
534 G4TouchableHandle preTouch = preStepPoint->GetTouchableHandle();
535 G4VPhysicalVolume* pVol = preTouch->GetVolume();
536 const G4int preStatus = preStepPoint->GetStepStatus();
537 const G4int postStatus = postStepPoint->GetStepStatus();
538 G4ThreeVector pos = track->GetPosition();
539 G4ThreeVector mom = track->GetMomentum();
542 if (step->GetStepLength() > 0.0) {
543 double dt = step->GetDeltaTime();
544 double dl = step->GetStepLength() / track->GetMaterial()->GetRadlen();
545 if (preStatus == fGeomBoundary) {
546 if (
m_TargetExt->GetDistanceFromPoint(pos) < 0.0) {
548 createExtHit(EXT_ENTER, extState, g4eState, preStepPoint, preTouch);
559 if (postStatus == fGeomBoundary) {
560 if (
m_TargetExt->GetDistanceFromPoint(pos) < 0.0) {
562 createExtHit(EXT_EXIT, extState, g4eState, postStepPoint, preTouch);
566 if (
createMuidHit(extState, g4eState, klmMuidLikelihood, bklmHitUsed)) {
568 m_ExtMgr->GetPropagator()->SetStepN(0);
570 if (eclClusterInfo !=
nullptr) {
571 for (
unsigned int c = 0; c < eclClusterInfo->size(); ++c) {
572 G4ThreeVector eclPos((*eclClusterInfo)[c].second);
573 G4ThreeVector prePos(preStepPoint->GetPosition());
574 G4ThreeVector diff(prePos - eclPos);
575 double distance = diff.mag();
578 if (distance < eclClusterDistance[c]) {
579 eclClusterDistance[c] = distance;
580 G4ErrorSymMatrix covariance(6, 0);
582 eclHit3[c].update(EXT_ECLNEAR, extState.
tof, pos / CLHEP::cm, mom / CLHEP::GeV, covariance);
585 if (eclHit1[c].getStatus() == EXT_FIRST) {
586 if (pos.mag2() >= eclPos.mag2()) {
587 double r = eclPos.mag();
588 double preD = prePos.mag() - r;
589 double postD = pos.mag() - r;
590 double f = postD / (postD - preD);
591 G4ThreeVector midPos = pos + (prePos - pos) * f;
592 double tof = extState.
tof + dt * f * (extState.
isCosmic ? +1 : -1);
593 G4ErrorSymMatrix covariance(6, 0);
595 eclHit1[c].update(EXT_ECLCROSS, tof, midPos / CLHEP::cm, mom / CLHEP::GeV, covariance);
600 if (eclHit2[c].getStatus() == EXT_FIRST) {
601 G4ThreeVector delta(pos - prePos);
602 G4ThreeVector perp(eclPos.cross(delta));
603 double perpMag2 = perp.mag2();
604 if (perpMag2 > 1.0E-10) {
605 double dist = std::fabs(diff * perp) / std::sqrt(perpMag2);
607 double f = eclPos * (prePos.cross(perp)) / perpMag2;
608 if ((f > -0.5) && (f <= 1.0)) {
609 G4ThreeVector midPos(prePos + f * delta);
610 double length = extState.
length + dl * (1.0 - f) * (extState.
isCosmic ? +1 : -1);
611 G4ErrorSymMatrix covariance(6, 0);
613 eclHit2[c].update(EXT_ECLDL, length, midPos / CLHEP::cm, mom / CLHEP::GeV, covariance);
620 if (klmClusterInfo !=
nullptr) {
621 for (
unsigned int c = 0; c < klmClusterInfo->size(); ++c) {
622 G4ThreeVector klmPos = (*klmClusterInfo)[c].second;
623 G4ThreeVector separation = klmPos - pos;
624 double distance = separation.mag();
625 if (distance < klmHit[c].getDistance()) {
626 klmHit[c].setDistance(distance);
627 klmHit[c].setTrackClusterAngle(mom.angle(separation));
628 klmHit[c].setTrackClusterSeparationAngle(mom.angle(klmPos));
629 klmHit[c].setTrackRotationAngle(extState.
directionAtIP.angle(mom));
630 klmHit[c].setTrackClusterInitialSeparationAngle(extState.
directionAtIP.angle(klmPos));
636 if (errCode || (mom.mag2() < minPSq)) {
649 m_ExtMgr->EventTermination(propagationMode);
653 if (eclClusterInfo !=
nullptr) {
654 for (
unsigned int c = 0; c < eclClusterInfo->size(); ++c) {
655 if (eclHit1[c].getStatus() != EXT_FIRST) {
657 (*eclClusterInfo)[c].first->addRelationTo(h);
658 if (extState.
track !=
nullptr) {
662 if (eclHit2[c].getStatus() != EXT_FIRST) {
664 (*eclClusterInfo)[c].first->addRelationTo(h);
665 if (extState.
track !=
nullptr) {
669 if (eclHit3[c].getStatus() != EXT_FIRST) {
671 (*eclClusterInfo)[c].first->addRelationTo(h);
672 if (extState.
track !=
nullptr) {
679 if (klmClusterInfo !=
nullptr) {
683 unsigned int closestCluster = 0;
684 for (
unsigned int c = 0; c < klmClusterInfo->size(); ++c) {
685 if (klmHit[c].getDistance() > 1.0E9) {
690 (*klmClusterInfo)[c].first->addRelationTo(h);
691 if (extState.
track !=
nullptr) {
695 if (klmHit[c].getDistance() < minDistance) {
697 minDistance = klmHit[c].getDistance();
703 if (extState.
track !=
nullptr) {
704 extState.
track->
addRelationTo((*klmClusterInfo)[closestCluster].first, 1. / (minDistance / CLHEP::cm));
716 if (trackClusterSeparations.size() == 0) {
724 const auto closestSeparationIterator = std::min_element(trackClusterSeparations.begin(), trackClusterSeparations.end(),
725 [](
const auto & a,
const auto & b) {
726 return a.getDistance() < b.getDistance();
730 const auto& closestSeparation = *closestSeparationIterator;
731 klmCluster.setClusterTrackSeparation(closestSeparation.getDistance() / CLHEP::cm);
732 klmCluster.setClusterTrackSeparationAngle(closestSeparation.getTrackClusterSeparationAngle());
733 klmCluster.setClusterTrackRotationAngle(closestSeparation.getTrackRotationAngle());
742 if (g4eState.GetMomentum().perp() <=
m_MinPt)
744 if (
m_TargetExt->GetDistanceFromPoint(g4eState.GetPosition()) < 0.0)
746 G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable()->FindParticle(extState.
pdgCode);
747 double mass = particle->GetPDGMass();
748 double minPSq = (mass +
m_MinKE) * (mass +
m_MinKE) - mass * mass;
749 G4ErrorMode propagationMode = (extState.
isCosmic ? G4ErrorMode_PropBackwards : G4ErrorMode_PropForwards);
750 m_ExtMgr->InitTrackPropagation(propagationMode);
752 const G4int errCode =
m_ExtMgr->PropagateOneStep(&g4eState, propagationMode);
753 G4Track* track = g4eState.GetG4Track();
754 const G4Step* step = track->GetStep();
755 const G4StepPoint* preStepPoint = step->GetPreStepPoint();
756 const G4StepPoint* postStepPoint = step->GetPostStepPoint();
757 G4TouchableHandle preTouch = preStepPoint->GetTouchableHandle();
758 G4VPhysicalVolume* pVol = preTouch->GetVolume();
759 const G4int preStatus = preStepPoint->GetStepStatus();
760 const G4int postStatus = postStepPoint->GetStepStatus();
761 G4ThreeVector pos = track->GetPosition();
762 G4ThreeVector mom = track->GetMomentum();
766 if (preStatus == fUndefined) {
768 createExtHit(EXT_FIRST, extState, g4eState, preStepPoint, preTouch);
772 if (step->GetStepLength() > 0.0) {
773 double dt = step->GetDeltaTime();
774 double dl = step->GetStepLength() / track->GetMaterial()->GetRadlen();
775 if (preStatus == fGeomBoundary) {
777 createExtHit(EXT_ENTER, extState, g4eState, preStepPoint, preTouch);
788 if (postStatus == fGeomBoundary) {
790 createExtHit(EXT_EXIT, extState, g4eState, postStepPoint, preTouch);
795 if (errCode || (mom.mag2() < minPSq)) {
797 createExtHit(EXT_STOP, extState, g4eState, postStepPoint, preTouch);
802 if (
m_TargetExt->GetDistanceFromPoint(pos) < 0.0) {
804 createExtHit(EXT_ESCAPE, extState, g4eState, postStepPoint, preTouch);
814 m_ExtMgr->EventTermination(propagationMode);
821 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
822 if (pvStore->size() == 0) {
823 B2FATAL(
"No geometry defined. Please create the geometry first.");
827 m_EnterExit =
new std::map<G4VPhysicalVolume*, enum VolTypes>;
829 for (std::vector<G4VPhysicalVolume*>::iterator iVol = pvStore->begin();
830 iVol != pvStore->end(); ++iVol) {
831 const G4String name = (*iVol)->GetName();
834 if (name.find(
"TOPModule") != std::string::npos) {
838 else if (name.find(
"_TOPPrism_") != std::string::npos ||
839 name.find(
"_TOPBarSegment") != std::string::npos ||
840 name.find(
"_TOPMirrorSegment") != std::string::npos) {
844 else if (name.find(
"TOPBarSegment1Glue") != std::string::npos ||
845 name.find(
"TOPBarSegment2Glue") != std::string::npos ||
846 name.find(
"TOPMirrorSegmentGlue") != std::string::npos) {
849 }
else if (name ==
"ARICH.AerogelSupportPlate") {
851 }
else if (name ==
"ARICH.AerogelImgPlate") {
853 }
else if (name.find(
"ARICH.HAPDWindow") != std::string::npos) {
857 else if (name.find(
"lv_barrel_crystal_") != std::string::npos ||
858 name.find(
"lv_forward_crystal_") != std::string::npos ||
859 name.find(
"lv_backward_crystal_") != std::string::npos) {
864 else if (name.compare(0, 5,
"BKLM.") == 0) {
865 if (name.find(
"GasPhysical") != std::string::npos) {
867 }
else if (name.find(
"ScintActiveType") != std::string::npos) {
869 }
else if ((name.find(
"ScintType") != std::string::npos) ||
870 (name.find(
"ElectrodePhysical") != std::string::npos)) {
875 else if (name.compare(0, 14,
"StripSensitive") == 0) {
887 detID = Const::EDetector::invalidDetector;
890 G4VPhysicalVolume* pv = touch->GetVolume(0);
891 std::map<G4VPhysicalVolume*, enum VolTypes>::iterator it =
m_EnterExit->find(pv);
895 switch (it->second) {
897 detID = Const::EDetector::CDC;
898 copyID = pv->GetCopyNo();
901 detID = Const::EDetector::TOP;
902 copyID = -(pv->GetCopyNo());
905 detID = Const::EDetector::TOP;
906 if (touch->GetHistoryDepth() >= 1)
907 copyID = touch->GetVolume(1)->GetCopyNo();
910 detID = Const::EDetector::TOP;
911 if (touch->GetHistoryDepth() >= 2)
912 copyID = touch->GetVolume(2)->GetCopyNo();
915 detID = Const::EDetector::ARICH;
919 detID = Const::EDetector::ARICH;
923 detID = Const::EDetector::ARICH;
924 if (touch->GetHistoryDepth() >= 2)
925 copyID = touch->GetVolume(2)->GetCopyNo();
928 detID = Const::EDetector::ECL;
932 detID = Const::EDetector::BKLM;
933 if (touch->GetHistoryDepth() == DEPTH_RPC) {
935 int layer = touch->GetCopyNumber(4);
936 int sector = touch->GetCopyNumber(6);
937 int section = touch->GetCopyNumber(7);
942 detID = Const::EDetector::BKLM;
943 if (touch->GetHistoryDepth() == DEPTH_SCINT) {
944 int strip = touch->GetCopyNumber(1);
945 int plane = (touch->GetCopyNumber(2) == BKLM_INNER) ?
948 int layer = touch->GetCopyNumber(6);
949 int sector = touch->GetCopyNumber(8);
950 int section = touch->GetCopyNumber(9);
952 section, sector, layer, plane, strip);
957 detID = Const::EDetector::EKLM;
959 touch->GetVolume(7)->GetCopyNo(),
960 touch->GetVolume(6)->GetCopyNo(),
961 touch->GetVolume(5)->GetCopyNo(),
962 touch->GetVolume(4)->GetCopyNo(),
963 touch->GetVolume(1)->GetCopyNo());
971 ExtState extState = {&b2track, pdgCode,
false, 0.0, 0.0,
972 G4ThreeVector(0, 0, 1), 0.0, 0, 0, 0, -1, -1, -1, -1, 0, 0,
false
975 if (recoTrack ==
nullptr) {
976 B2WARNING(
"Track without associated RecoTrack: skipping extrapolation for this track.");
983 B2WARNING(
"RecoTrack fit failed for cardinal representation: skipping extrapolation for this track.");
987 int charge = int(trackRep->getPDGCharge());
993 TVector3 firstPosition, firstMomentum, lastPosition, lastMomentum;
994 TMatrixDSym firstCov(6), lastCov(6);
997 trackRep->getPosMomCov(firstState, firstPosition, firstMomentum, firstCov);
999 trackRep->getPosMomCov(lastState, lastPosition, lastMomentum, lastCov);
1001 extState.
tof = lastState.getTime();
1002 if (lastPosition.Mag2() < firstPosition.Mag2()) {
1003 firstPosition = lastPosition;
1004 firstMomentum = -lastMomentum;
1006 trackRep->getPosMomCov(firstState, lastPosition, lastMomentum, lastCov);
1007 lastMomentum *= -1.0;
1009 extState.
tof = firstState.getTime();
1012 G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable()->FindParticle(extState.
pdgCode);
1013 if (extState.
pdgCode != trackRep->getPDG()) {
1014 double pSq = lastMomentum.Mag2();
1015 double mass = particle->GetPDGMass() / CLHEP::GeV;
1016 extState.
tof *= std::sqrt((pSq + mass * mass) / (pSq + lastState.getMass() * lastState.getMass()));
1019 extState.
directionAtIP.set(firstMomentum.Unit().X(), firstMomentum.Unit().Y(), firstMomentum.Unit().Z());
1021 double radius = (firstMomentum.Perp() * CLHEP::GeV / CLHEP::eV) / (CLHEP::c_light * charge *
m_MagneticField);
1023 double centerX = firstPosition.X() + radius * std::cos(centerPhi);
1024 double centerY = firstPosition.Y() + radius * std::sin(centerPhi);
1025 double pocaPhi = atan2(charge * centerY, charge * centerX) + M_PI;
1035 lastCov[0][0] = 5.0E-5;
1036 lastCov[1][1] = 1.0E-7;
1037 lastCov[2][2] = 5.0E-4;
1038 lastCov[3][3] = 3.5E-3;
1039 lastCov[4][4] = 3.5E-3;
1040 lastMomentum = lastMomentum.Unit() * 10.0;
1043 G4ThreeVector posG4e(lastPosition.X() * CLHEP::cm, lastPosition.Y() * CLHEP::cm,
1044 lastPosition.Z() * CLHEP::cm);
1045 G4ThreeVector momG4e(lastMomentum.X() * CLHEP::GeV, lastMomentum.Y() * CLHEP::GeV,
1046 lastMomentum.Z() * CLHEP::GeV);
1047 G4ErrorSymMatrix covG4e(5, 0);
1049 g4eState.SetData(
"g4e_" + particle->GetParticleName(), posG4e, momG4e);
1050 g4eState.SetParameters(posG4e, momG4e);
1051 g4eState.SetError(covG4e);
1052 }
catch (
const genfit::Exception&) {
1053 B2WARNING(
"genfit::MeasuredStateOnPlane() exception: skipping extrapolation for this track. initial momentum = ("
1054 << firstMomentum.X() <<
"," << firstMomentum.Y() <<
"," << firstMomentum.Z() <<
")");
1074 G4ErrorFreeTrajParam param = g4eState.GetParameters();
1075 double p = 1.0 / (param.GetInvP() * CLHEP::GeV);
1077 double lambda = param.GetLambda();
1078 double sinLambda = std::sin(lambda);
1079 double cosLambda = std::cos(lambda);
1080 double phi = param.GetPhi();
1081 double sinPhi = std::sin(phi);
1082 double cosPhi = std::cos(phi);
1086 G4ErrorMatrix jacobian(6, 5, 0);
1088 jacobian(4, 1) = -pSq * cosLambda * cosPhi;
1089 jacobian(5, 1) = -pSq * cosLambda * sinPhi;
1090 jacobian(6, 1) = -pSq * sinLambda;
1092 jacobian(4, 2) = -p * sinLambda * cosPhi;
1093 jacobian(5, 2) = -p * sinLambda * sinPhi;
1094 jacobian(6, 2) = p * cosLambda;
1096 jacobian(4, 3) = -p * cosLambda * sinPhi;
1097 jacobian(5, 3) = p * cosLambda * cosPhi;
1099 jacobian(1, 4) = -sinPhi;
1100 jacobian(2, 4) = cosPhi;
1102 jacobian(1, 5) = -sinLambda * cosPhi;
1103 jacobian(2, 5) = -sinLambda * sinPhi;
1104 jacobian(3, 5) = cosLambda;
1106 G4ErrorTrajErr g4eCov = g4eState.GetError();
1107 covariance.assign(g4eCov.similarity(jacobian));
1123 G4ErrorSymMatrix temp(6, 0);
1124 for (
int k = 0; k < 6; ++k) {
1125 for (
int j = k; j < 6; ++j) {
1126 temp[j][k] = covariance[j][k];
1130 double pInvSq = 1.0 / momentum.Mag2();
1131 double pInv = std::sqrt(pInvSq);
1132 double pPerpInv = 1.0 / momentum.Perp();
1133 double sinLambda = momentum.CosTheta();
1134 double cosLambda = std::sqrt(1.0 - sinLambda * sinLambda);
1135 double phi = momentum.Phi();
1136 double cosPhi = std::cos(phi);
1137 double sinPhi = std::sin(phi);
1140 G4ErrorMatrix jacobian(5, 6, 0);
1142 jacobian(1, 4) = -pInvSq * cosLambda * cosPhi;
1143 jacobian(1, 5) = -pInvSq * cosLambda * sinPhi;
1144 jacobian(1, 6) = -pInvSq * sinLambda;
1146 jacobian(2, 4) = -pInv * sinLambda * cosPhi;
1147 jacobian(2, 5) = -pInv * sinLambda * sinPhi;
1148 jacobian(2, 6) = pInv * cosLambda;
1150 jacobian(3, 4) = -pPerpInv * sinPhi;
1151 jacobian(3, 5) = pPerpInv * cosPhi;
1153 jacobian(4, 1) = -sinPhi;
1154 jacobian(4, 2) = cosPhi;
1156 jacobian(5, 1) = -sinLambda * cosPhi;
1157 jacobian(5, 2) = -sinLambda * sinPhi;
1158 jacobian(5, 3) = cosLambda;
1160 covG4e = temp.similarity(jacobian);
1165 G4ErrorTrajErr& covG4e)
1177 G4ErrorSymMatrix temp(covariance);
1179 double pInvSq = 1.0 / momentum.mag2();
1180 double pInv = std::sqrt(pInvSq);
1181 double pPerpInv = 1.0 / momentum.perp();
1182 double sinLambda = momentum.cosTheta();
1183 double cosLambda = std::sqrt(1.0 - sinLambda * sinLambda);
1184 double phi = momentum.phi();
1185 double cosPhi = std::cos(phi);
1186 double sinPhi = std::sin(phi);
1189 G4ErrorMatrix jacobian(5, 6, 0);
1191 jacobian(1, 4) = -pInvSq * cosLambda * cosPhi;
1192 jacobian(1, 5) = -pInvSq * cosLambda * sinPhi;
1193 jacobian(1, 6) = -pInvSq * sinLambda;
1195 jacobian(2, 4) = -pInv * sinLambda * cosPhi;
1196 jacobian(2, 5) = -pInv * sinLambda * sinPhi;
1197 jacobian(2, 6) = pInv * cosLambda;
1199 jacobian(3, 4) = -pPerpInv * sinPhi;
1200 jacobian(3, 5) = pPerpInv * cosPhi;
1202 jacobian(4, 1) = -sinPhi;
1203 jacobian(4, 2) = cosPhi;
1205 jacobian(5, 1) = -sinLambda * cosPhi;
1206 jacobian(5, 2) = -sinLambda * sinPhi;
1207 jacobian(5, 3) = cosLambda;
1208 covG4e = temp.similarity(jacobian);
1214 const G4ErrorFreeTrajState& g4eState,
1215 const G4StepPoint* stepPoint,
const G4TouchableHandle& touch)
1220 G4ThreeVector pos(stepPoint->GetPosition() / CLHEP::cm);
1221 G4ThreeVector mom(stepPoint->GetMomentum() / CLHEP::GeV);
1224 G4ErrorSymMatrix covariance(6, 0);
1228 pos, mom, covariance);
1230 if (extState.
track !=
nullptr)
1238 std::vector<std::map<const Track*, double> >* bklmHitUsed)
1242 intersection.
hit = -1;
1243 intersection.
chi2 = -1.0;
1244 intersection.
position = g4eState.GetPosition() / CLHEP::cm;
1245 intersection.
momentum = g4eState.GetMomentum() / CLHEP::GeV;
1246 G4ThreeVector prePos = g4eState.GetG4Track()->GetStep()->GetPreStepPoint()->GetPosition() / CLHEP::cm;
1247 G4ThreeVector oldPosition(prePos.x(), prePos.y(), prePos.z());
1248 double r = intersection.
position.perp();
1257 (*bklmHitUsed)[intersection.
hit].insert(std::pair<const Track*, double>(extState.
track, intersection.
chi2));
1259 float layerBarrelEfficiency = 1.;
1263 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1277 intersection.
chi2 = -1.0;
1282 g4eState.GetG4Track()->GetVolume());
1288 int sector = intersection.
sector + 1;
1289 int layer = intersection.
layer + 1;
1292 const CLHEP::Hep3Vector localPosition = m->globalToLocal(intersection.
position);
1293 int zStrip = m->getZStripNumber(localPosition);
1294 int phiStrip = m->getPhiStripNumber(localPosition);
1295 if (zStrip >= 0 && phiStrip >= 0) {
1296 uint16_t channel1, channel2;
1298 section, sector, layer,
1301 section, sector, layer,
1308 B2ERROR(
"No KLM channel status data."
1309 <<
LogVar(
"Section", section)
1310 <<
LogVar(
"Sector", sector)
1311 <<
LogVar(
"Layer", layer)
1312 <<
LogVar(
"Z strip", zStrip)
1313 <<
LogVar(
"Phi strip", phiStrip));
1320 float layerBarrelEfficiency = 1.;
1324 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1345 float layerEndcapEfficiency = 1.;
1349 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1363 intersection.
chi2 = -1.0;
1367 int result, strip1, strip2;
1369 intersection.
position, &strip1, &strip2);
1371 uint16_t channel1, channel2;
1379 B2ERROR(
"Incomplete KLM channel status data.");
1385 float layerEndcapEfficiency = 1.;
1389 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1404 if (intersection.
chi2 >= 0.0) {
1405 ROOT::Math::XYZVector tpos(intersection.
position.x(),
1414 tpos, tposAtHitPlane,
1415 extState.
tof, intersection.
time,
1418 G4Point3D newPos(intersection.
position.x() * CLHEP::cm,
1419 intersection.
position.y() * CLHEP::cm,
1420 intersection.
position.z() * CLHEP::cm);
1421 g4eState.SetPosition(newPos);
1422 G4Vector3D newMom(intersection.
momentum.x() * CLHEP::GeV,
1423 intersection.
momentum.y() * CLHEP::GeV,
1424 intersection.
momentum.z() * CLHEP::GeV);
1425 g4eState.SetMomentum(newMom);
1426 G4ErrorTrajErr covG4e;
1428 g4eState.SetError(covG4e);
1429 extState.
chi2 += intersection.
chi2;
1445 double phi = intersection.
position.phi();
1448 if (phi > TWOPI - PI_8)
1450 int sector = (int)((phi + PI_8) / M_PI_4);
1463 intersection.
layer = layer;
1464 intersection.
sector = sector;
1480 double oldZ = std::fabs(oldPosition.z() -
m_OffsetZ);
1485 for (
int layer = extState.
firstEndcapLayer; layer <= outermostLayer; ++layer) {
1494 intersection.
layer = layer;
1496 isForward ? 2 : 1, intersection.
position) - 1;
1506 G4ThreeVector extPos0(intersection.
position);
1507 double diffBestMagSq = 1.0E60;
1509 int matchingLayer = intersection.
layer + 1;
1511 for (
int h = 0; h <
m_klmHit2ds.getEntries(); ++h) {
1515 if (hit->getLayer() != matchingLayer)
1517 if (hit->isOutOfTime())
1521 G4ThreeVector diff(hit->getPositionX() - intersection.
position.x(),
1522 hit->getPositionY() - intersection.
position.y(),
1523 hit->getPositionZ() - intersection.
position.z());
1524 double dn = diff * n;
1525 if (std::fabs(dn) < 2.0) {
1528 if (diff.mag2() < diffBestMagSq) {
1529 diffBestMagSq = diff.mag2();
1535 if (std::fabs(dn) > 50.0)
1537 int sector = hit->getSector() - 1;
1538 int dSector = abs(intersection.
sector - sector);
1547 dn = diff * nHit + dn2;
1548 if (std::fabs(dn) > 1.0)
1551 G4ThreeVector extDir(intersection.
momentum.unit());
1552 double extDirA = extDir * nHit;
1553 if (std::fabs(extDirA) < 1.0E-6)
1555 G4ThreeVector projection = extDir * (dn2 / extDirA);
1556 if (projection.mag() > 15.0)
1558 diff += projection - nHit * dn;
1559 if (diff.mag2() < diffBestMagSq) {
1560 diffBestMagSq = diff.mag2();
1562 extPos0 = intersection.
position - projection;
1569 intersection.
isForward = (hit->getSection() == 1);
1570 intersection.
sector = hit->getSector() - 1;
1571 intersection.
time = hit->getTime();
1574 int nStrips = hit->getPhiStripMax() - hit->getPhiStripMin() + 1;
1575 double dn = nStrips - 1.5;
1576 double factor = std::pow((0.9 + 0.4 * dn * dn), 1.5) * 0.60;
1578 nStrips = hit->getZStripMax() - hit->getZStripMin() + 1;
1580 factor = std::pow((0.9 + 0.4 * dn * dn), 1.5) * 0.55;
1583 int nStrips = hit->getPhiStripMax() - hit->getPhiStripMin() + 1;
1584 localVariance[0] *= (nStrips * nStrips);
1585 nStrips = hit->getZStripMax() - hit->getZStripMin() + 1;
1586 localVariance[1] *= (nStrips * nStrips);
1588 G4ThreeVector hitPos(hit->getPositionX(), hit->getPositionY(),
1589 hit->getPositionZ());
1591 if (intersection.
chi2 >= 0.0) {
1592 intersection.
hit = bestHit;
1593 hit->isOnTrack(
true);
1594 if (track !=
nullptr) {
1595 track->addRelationTo(hit, intersection.
chi2);
1603 return intersection.
chi2 >= 0.0;
1609 double diffBestMagSq = 1.0E60;
1611 int matchingLayer = intersection.
layer + 1;
1612 int matchingEndcap = (intersection.
isForward ? 2 : 1);
1613 G4ThreeVector n(0.0, 0.0, (intersection.
isForward ? 1.0 : -1.0));
1614 for (
int h = 0; h <
m_klmHit2ds.getEntries(); ++h) {
1618 if (hit->getLayer() != matchingLayer)
1620 if (hit->getSection() != matchingEndcap)
1626 G4ThreeVector diff(hit->getPositionX() - intersection.
position.x(),
1627 hit->getPositionY() - intersection.
position.y(),
1628 hit->getPositionZ() - intersection.
position.z());
1629 double dn = diff * n;
1630 if (std::fabs(dn) > 2.0)
1633 if (diff.mag2() < diffBestMagSq) {
1634 diffBestMagSq = diff.mag2();
1641 intersection.
hit = bestHit;
1642 intersection.
isForward = (hit->getSection() == 2);
1643 intersection.
sector = hit->getSector() - 1;
1644 intersection.
time = hit->getTime();
1646 int nStrips = hit->getXStripMax() - hit->getXStripMin() + 1;
1647 localVariance[0] *= (nStrips * nStrips);
1648 nStrips = hit->getYStripMax() - hit->getYStripMin() + 1;
1649 localVariance[1] *= (nStrips * nStrips);
1650 G4ThreeVector hitPos(hit->getPositionX(), hit->getPositionY(), hit->getPositionZ());
1652 if (intersection.
chi2 >= 0.0) {
1655 if (track !=
nullptr) {
1656 track->addRelationTo(hit, intersection.
chi2);
1666 return intersection.
chi2 >= 0.0;
1671 const G4ThreeVector& hitPos,
const G4ThreeVector& extPos0)
1691 G4ThreeVector extPos(extPos0);
1692 G4ThreeVector extMom(intersection.
momentum);
1693 G4ThreeVector extDir(extMom.unit());
1694 G4ThreeVector diffPos(hitPos - extPos);
1695 G4ErrorSymMatrix extCov(intersection.
covariance);
1697 G4ErrorMatrix extPar(6, 1);
1698 extPar[0][0] = extPos.x();
1699 extPar[1][0] = extPos.y();
1700 extPar[2][0] = extPos.z();
1701 extPar[3][0] = extMom.x();
1702 extPar[4][0] = extMom.y();
1703 extPar[5][0] = extMom.z();
1710 nC = G4ThreeVector(0.0, 0.0, 1.0);
1712 double out = (intersection.
isForward ? 1.0 : -1.0);
1713 nA = G4ThreeVector(0.0, 0.0, out);
1714 nB = G4ThreeVector(out, 0.0, 0.0);
1715 nC = G4ThreeVector(0.0, out, 0.0);
1718 double extDirA = extDir * nA;
1719 if (std::fabs(extDirA) < 1.0E-6)
1721 double extDirBA = extDir * nB / extDirA;
1722 double extDirCA = extDir * nC / extDirA;
1725 G4ThreeVector move = extDir * ((diffPos * nA) / extDirA);
1730 G4ErrorMatrix jacobian(2, 6);
1731 jacobian[0][0] = nB.x() - nA.x() * extDirBA;
1732 jacobian[0][1] = nB.y() - nA.y() * extDirBA;
1733 jacobian[0][2] = nB.z() - nA.z() * extDirBA;
1734 jacobian[1][0] = nC.x() - nA.x() * extDirCA;
1735 jacobian[1][1] = nC.y() - nA.y() * extDirCA;
1736 jacobian[1][2] = nC.z() - nA.z() * extDirCA;
1738 G4ErrorMatrix residual(2, 1);
1739 residual[0][0] = diffPos.x() * jacobian[0][0] + diffPos.y() * jacobian[0][1] + diffPos.z() * jacobian[0][2];
1740 residual[1][0] = diffPos.x() * jacobian[1][0] + diffPos.y() * jacobian[1][1] + diffPos.z() * jacobian[1][2];
1742 G4ErrorSymMatrix hitCov(2, 0);
1743 hitCov[0][0] = localVariance[0];
1744 hitCov[1][1] = localVariance[1];
1747 hitCov[0][0] *= 10.0;
1748 hitCov[1][1] *= 10.0;
1752 G4ErrorSymMatrix correction(extCov.similarity(jacobian) + hitCov);
1759 correction.invert(fail);
1765 intersection.
chi2 = (correction.similarityT(residual))[0][0];
1767 G4ErrorMatrix gain((extCov * jacobian.T()) * correction);
1768 G4ErrorSymMatrix HRH(correction.similarityT(jacobian));
1769 extCov -= HRH.similarity(extCov);
1770 extPar += gain * residual;
1771 extPos.set(extPar[0][0], extPar[1][0], extPar[2][0]);
1772 extMom.set(extPar[3][0], extPar[4][0], extPar[5][0]);
1774 correction = hitCov - extCov.similarity(jacobian);
1775 correction.invert(fail);
1778 diffPos = hitPos - extPos;
1779 residual[0][0] = diffPos.x() * jacobian[0][0] + diffPos.y() * jacobian[0][1] + diffPos.z() * jacobian[0][2];
1780 residual[1][0] = diffPos.x() * jacobian[1][0] + diffPos.y() * jacobian[1][1] + diffPos.z() * jacobian[1][2];
1781 intersection.
chi2 = (correction.similarityT(residual))[0][0];
1788 intersection.
position = extPos + extDir * (((intersection.
position - extPos) * nA) / extDirA);
1814 if (outcome != MuidElementNumbers::c_NotReached) {
1816 int charge = klmMuidLikelihood->
getCharge();
1818 std::map<int, double> mapPdgPDF;
1819 for (
int pdg : signedPdgVector) {
1822 B2FATAL(
"Something went wrong: PDF for PDG code " << pdg <<
" not found!");
1823 double pdf = (search->second)->getPDF(klmMuidLikelihood);
1825 mapPdgPDF.insert(std::pair<int, double>(std::abs(pdg), pdf));
1827 if (denom < 1.0E-20)
1830 for (
auto const& [pdg, pdf] : mapPdgPDF) {
1831 klmMuidLikelihood->
setPDFValue(pdf, std::abs(pdg));
1833 klmMuidLikelihood->
setLogL(std::log(pdf), std::abs(pdg));
static KLMChannelNumber channelNumber(int section, int sector, int layer, int plane, int strip)
Get channel number.
static constexpr int getMaximalLayerNumber()
Get maximal layer number (1-based).
@ c_ForwardSection
Forward.
@ c_BackwardSection
Backward.
static constexpr int getMaximalSectorNumber()
Get maximal sector number (1-based).
static KLMModuleNumber moduleNumber(int section, int sector, int layer, bool fatalError=true)
Get module number.
static constexpr int getMaximalPlaneNumber()
Get maximal plane number (0-based).
static void setMaximalStrip(int &module, int strip)
Set maximal strip number.
static const ChargedStable muon
muon particle
EDetector
Enum for identifying the detector components (detector and subdetector).
static const double doubleNaN
quiet_NaN
static const ChargedStable electron
electron particle
static ECLGeometryPar * Instance()
Static method to get a reference to the ECLGeometryPar instance.
int ECLVolumeToCellID(const G4VTouchable *)
Get Cell Id (LEP: new way)
This dataobject is used only for EKLM alignment.
static const EKLMElementNumbers & Instance()
Instantiation.
int stripNumber(int section, int layer, int sector, int plane, int strip) const
Get strip number.
static constexpr int getMaximalLayerNumber()
Get maximal layer number.
@ c_ForwardSection
Forward.
@ c_BackwardSection
Backward.
static constexpr int getMaximalPlaneNumber()
Get maximal plane number.
double getOuterR() const
Get outer radius.
double getInnerR() const
Get inner radius.
double getZ() const
Get Z coordinate.
double getLength() const
Get length.
double getWidth() const
Get width.
const ElementPosition * getLayerPosition() const
Get position data for layers.
double getLayerShiftZ() const
Get Z distance between two layers.
const StripGeometry * getStripGeometry() const
Get strip geometry data.
const ElementPosition * getSectionPosition() const
Get position data for sections.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
Store one Ext hit as a ROOT object.
@ c_IndexLevelLayer
Layer.
ChannelStatus
Channel status.
@ c_Dead
Dead channel (no signal).
@ c_Unknown
Unknown status (no data).
static const KLMElementNumbers & Instance()
Instantiation.
Store one muon-identification hit in the KLM as a ROOT object.
Class to store the likelihoods from KLM with additional information related to the extrapolation.
void setExtLayer(int layer)
Set the outermost EKLM layer crossed in the extrapolation.
void setExtLayerPattern(unsigned int pattern)
Set the pattern of the layers crossed in the extrapolation.
void setLogL(double logL, int pdg)
Set the log-likelihood.
void setExtEKLMEfficiencyValue(int layer, float efficiency)
Set the efficiency of a given EKLM layer.
void setExtBKLMEfficiencyValue(int layer, float efficiency)
Set the efficiency of a given BKLM layer.
void setChiSquared(double chiSquared)
Set the chi-squared of the extrapolation.
void setHitLayerPattern(unsigned int pattern)
Set the pattern of the layers actually crossed by the track.
void setBarrelExtLayer(int layer)
Set the outermost BKLM layer crossed in the extrapolation.
void setIsForward(bool isForward)
Set if this extrapolation is in forward or backward B/EKLM.
void setJunkPDFValue(bool flag)
Set the junk flag (1 if junk, 0 if not).
void setPDGCode(int pdg)
Set the PDG code of the particle hypothesis used during the extrapolation.
void setDegreesOfFreedom(int dof)
Set the number of degrees of freedom (= 2 times the number of KLM hits) for the chi-square computatio...
int getCharge() const
Get the charge of the particle hypothesis used during the extrapolation.
void setPDFValue(double pdfValue, int pdg)
Set the normalized PDF.
void setEndcapExtLayer(int layer)
Set the outermost EKLM layer crossed in the extrapolation.
void setBarrelHitLayer(int layer)
Set the outermost BKLM layer actually crossed by the track.
void setOutcome(unsigned int outcome)
Set the outcome of this extrapolation.
void setHitLayer(int layer)
Set the outermost KLM layer actually crossed by the track.
void setEndcapHitLayer(int layer)
Set the outermost EKLM layer actually crossed by the track.
Build the Muid likelihoods starting from the hit pattern and the transverse scattering in the KLM.
static unsigned int calculateExtrapolationOutcome(bool isForward, bool escaped, int lastBarrelLayer, int lastEndcapLayer)
Calculate the track extrapolation outcome.
static std::vector< int > getPDGVector()
Get a vector with all the hypothesis PDG codes used for Muid.
This is the Reconstruction Event-Data Model Track.
bool addBKLMHit(const UsedBKLMHit *bklmHit, const unsigned int sortingParameter, OriginTrackFinder foundByTrackFinder=OriginTrackFinder::c_undefinedTrackFinder)
Adds a bklm hit with the given information to the reco track.
bool wasFitSuccessful(const genfit::AbsTrackRep *representation=nullptr) const
Returns true if the last fit with the given representation was successful.
bool addEKLMHit(const UsedEKLMHit *eklmHit, const unsigned int sortingParameter, OriginTrackFinder foundByTrackFinder=OriginTrackFinder::c_undefinedTrackFinder)
Adds an eklm hit with the given information to the reco track.
genfit::AbsTrackRep * getCardinalRepresentation() const
Get a pointer to the cardinal track representation. You are not allowed to modify or delete it!
const genfit::MeasuredStateOnPlane & getMeasuredStateOnPlaneFromLastHit(const genfit::AbsTrackRep *representation=nullptr) const
Return genfit's MeasuredStateOnPlane for the last hit in a fit useful for extrapolation of measuremen...
static void registerRequiredRelations(StoreArray< RecoTrack > &recoTracks, std::string const &pxdHitsStoreArrayName="", std::string const &svdHitsStoreArrayName="", std::string const &cdcHitsStoreArrayName="", std::string const &bklmHitsStoreArrayName="", std::string const &eklmHitsStoreArrayName="", std::string const &recoHitInformationStoreArrayName="")
Convenience method which registers all relations required to fully use a RecoTrack.
const genfit::MeasuredStateOnPlane & getMeasuredStateOnPlaneFromFirstHit(const genfit::AbsTrackRep *representation=nullptr) const
Return genfit's MeasuredStateOnPlane for the first hit in a fit useful for extrapolation of measureme...
unsigned int getNumberOfTotalHits() const
Return the number of cdc + svd + pxd + bklm + eklm hits.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
TO * getRelatedTo(const std::string &name="", const std::string &namedRelation="") const
Get the object to which this object has a relation.
Defines a closed cylinder for the geant4e "target", the surface that encloses the volume within which...
It is the main interface for the user to define the setup and start the propagation.
static ExtManager * GetManager()
Get pointer to the instance of this singleton class (create if needed)
void Initialize(const char[], const std::string &, double, double, bool, int, const std::vector< std::string > &)
Initialize Geant4 and Geant4e.
Store one Track-KLMCluster separation as a ROOT object.
Class that bundles various TrackFitResults.
static const double T
[tesla]
Provides BKLM geometry parameters for simulation, reconstruction etc (from Gearbox or DataBase)
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
double getScintHalfWidth(void) const
Get the height of the entire volume of a scintillator strip (including TiO2 coating)
double getGap1InnerRadius(void) const
Get the radius of the inner tangent circle of gap 0 (innermost)
double getOuterRadius(void) const
Get the radius of the inscribed circle of the outer polygon.
double getOffsetZ(void) const
Get the global shift along a of the entire BKLM.
int getNSector(void) const
Get the number of sectors of the BKLM.
double getHalfLength(void) const
Get the half-length along z of the BKLM.
double getActiveMiddleRadius(int section, int sector, int layer) const
Get the radial midpoint of the detector module's active volume of specified layer.
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
Define the geometry of a BKLM module Each sector [octant] contains Modules.
Class to store variables with their name which were sent to the logging service.
static void getField(const double *pos, double *field)
return the magnetic field at a given position.
ExtHitStatus
Define state of extrapolation for each recorded hit.
@ VOLTYPE_ARICH2
ARICH Img plate.
@ VOLTYPE_TOP2
TOP quartz.
@ VOLTYPE_ARICH3
ARICH HAPD window.
@ VOLTYPE_BKLM2
BKLM scintillator.
@ VOLTYPE_ARICH1
ARICH aerogel.
@ VOLTYPE_TOP1
TOP container.
Abstract base class for different kinds of events.
Data structure to define extrapolation state.
int lastEndcapExtLayer
MUID: outermost endcap layer crossed by the extrapolated track.
double chi2
MUID: accumulated chi-squared of all in-plane transverse deviations between extrapolation and matchin...
G4ThreeVector directionAtIP
MUID: initial direction of track, used for KLID.
int nPoint
MUID: accumulated number of points with matching 2D hits.
int lastEndcapHitLayer
MUID: outermost endcap layer with a matching hit.
bool isCosmic
True for back-propagation of a cosmic ray.
int firstEndcapLayer
MUID: outermost barrel layer encountered by the extrapolated track in the prior steps.
int extLayerPattern
MUID: accumulated bit pattern of layers crossed by the extrapolated track.
int pdgCode
Particle hypothesis that is being extrapolated.
double length
Length from start of extrapolation (rad lengths), updated during extrapolation.
bool escaped
MUID: flag to indicate that the extrapolated track escaped from the KLM.
int firstBarrelLayer
MUID: outermost barrel layer encountered by the extrapolated track in the prior steps.
int lastBarrelHitLayer
MUID: outermost barrel layer with a matching hit.
int hitLayerPattern
MUID: accumulated bit pattern of layers with matching hits.
int lastBarrelExtLayer
MUID: outermost barrel layer crossed by the extrapolated track.
double tof
Time of flight from IP (ns), updated during extrapolation.
const Track * track
Pointer to the reconstructed track.
intersection of muid-extrapolated track with a KLM layer
int sector
sector number (0..7 for barrel, 0..3 for endcap) of this point
G4ThreeVector momentum
extrapolated-track momentum (GeV/c) at this intersection
double chi2
chi-squared value of transverse deviation between extrapolated and measured hit positions
bool inBarrel
flag to indicate if this point is in the barrel (true) or endcap (false)
int hit
index in {B,E}KLMHit2ds of matching hit
G4ThreeVector positionAtHitPlane
extrapolated-track position (cm) projected to the 2D hit's midplane
G4ThreeVector position
extrapolated-track global position (cm) of this intersection
G4ErrorSymMatrix covariance
extrapolated-track phase-space covariance matrix at this intersection
bool isForward
flag to indicate if this point is in the forward (true) or backward (false) end
double time
time (ns) of matching BKLMHit2d
int layer
layer number (0..14 for barrel, 0..13 for endcap) of this point