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);
424 delete muidBuilder.second;
442 const G4ThreeVector& position,
443 const G4ThreeVector& momentum,
444 const G4ErrorSymMatrix& covariance)
446 bool isCosmic =
false;
451 extMgr->
Initialize(
"Ext",
"default", 0.0, 0.25,
false, 0, std::vector<std::string>());
456 G4UImanager::GetUIpointer()->ApplyCommand(
"/geant4e/limits/stepLength 250 mm");
457 G4UImanager::GetUIpointer()->ApplyCommand(
"/geant4e/limits/magField 0.001");
458 G4UImanager::GetUIpointer()->ApplyCommand(
"/geant4e/limits/energyLoss 0.05");
464 if (G4StateManager::GetStateManager()->GetCurrentState() == G4State_Idle) {
465 G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
468 G4ErrorPropagatorData::GetErrorPropagatorData()->SetTarget(
m_TargetExt);
473 G4ThreeVector positionG4e = position * CLHEP::cm;
474 G4ThreeVector momentumG4e = momentum * CLHEP::GeV;
476 momentumG4e = -momentumG4e;
477 G4ErrorSymMatrix covarianceG4e(5, 0);
479 G4String nameG4e(
"g4e_" + G4ParticleTable::GetParticleTable()->FindParticle(pdgCode)->GetParticleName());
480 G4ErrorFreeTrajState g4eState(nameG4e, positionG4e, momentumG4e, covarianceG4e);
481 ExtState extState = {
nullptr, pdgCode, isCosmic, tof, 0.0,
482 momentumG4e.unit(), 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
false
484 swim(extState, g4eState);
489 const std::vector<std::pair<ECLCluster*, G4ThreeVector> >* eclClusterInfo,
490 const std::vector<std::pair<KLMCluster*, G4ThreeVector> >* klmClusterInfo,
491 std::vector<std::map<const Track*, double> >* bklmHitUsed)
495 if (g4eState.GetMomentum().perp() <=
m_MinPt)
497 if (
m_TargetMuid->GetDistanceFromPoint(g4eState.GetPosition()) < 0.0)
499 G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable()->FindParticle(extState.
pdgCode);
500 double mass = particle->GetPDGMass();
501 double minPSq = (mass +
m_MinKE) * (mass +
m_MinKE) - mass * mass;
503 std::vector<double> eclClusterDistance;
504 std::vector<ExtHit> eclHit1, eclHit2, eclHit3;
505 if (eclClusterInfo !=
nullptr) {
506 eclClusterDistance.resize(eclClusterInfo->size(), 1.0E10);
507 ExtHit tempExtHit(.0, extState.
pdgCode, Const::EDetector::ECL, 0, EXT_FIRST,
509 G4ThreeVector(), G4ThreeVector(), G4ErrorSymMatrix(6));
510 eclHit1.resize(eclClusterInfo->size(), tempExtHit);
511 eclHit2.resize(eclClusterInfo->size(), tempExtHit);
512 eclHit3.resize(eclClusterInfo->size(), tempExtHit);
515 std::vector<TrackClusterSeparation> klmHit;
516 if (klmClusterInfo !=
nullptr) {
517 klmHit.resize(klmClusterInfo->size());
521 if (extState.
track !=
nullptr)
523 G4ErrorMode propagationMode = (extState.
isCosmic ? G4ErrorMode_PropBackwards : G4ErrorMode_PropForwards);
524 m_ExtMgr->InitTrackPropagation(propagationMode);
526 const G4int errCode =
m_ExtMgr->PropagateOneStep(&g4eState, propagationMode);
527 G4Track* track = g4eState.GetG4Track();
528 const G4Step* step = track->GetStep();
529 const G4StepPoint* preStepPoint = step->GetPreStepPoint();
530 const G4StepPoint* postStepPoint = step->GetPostStepPoint();
531 G4TouchableHandle preTouch = preStepPoint->GetTouchableHandle();
532 G4VPhysicalVolume* pVol = preTouch->GetVolume();
533 const G4int preStatus = preStepPoint->GetStepStatus();
534 const G4int postStatus = postStepPoint->GetStepStatus();
535 G4ThreeVector pos = track->GetPosition();
536 G4ThreeVector mom = track->GetMomentum();
539 if (step->GetStepLength() > 0.0) {
540 double dt = step->GetDeltaTime();
541 double dl = step->GetStepLength() / track->GetMaterial()->GetRadlen();
542 if (preStatus == fGeomBoundary) {
543 if (
m_TargetExt->GetDistanceFromPoint(pos) < 0.0) {
545 createExtHit(EXT_ENTER, extState, g4eState, preStepPoint, preTouch);
556 if (postStatus == fGeomBoundary) {
557 if (
m_TargetExt->GetDistanceFromPoint(pos) < 0.0) {
559 createExtHit(EXT_EXIT, extState, g4eState, postStepPoint, preTouch);
563 if (
createMuidHit(extState, g4eState, klmMuidLikelihood, bklmHitUsed)) {
565 m_ExtMgr->GetPropagator()->SetStepN(0);
567 if (eclClusterInfo !=
nullptr) {
568 for (
unsigned int c = 0; c < eclClusterInfo->size(); ++c) {
569 G4ThreeVector eclPos((*eclClusterInfo)[c].second);
570 G4ThreeVector prePos(preStepPoint->GetPosition());
571 G4ThreeVector diff(prePos - eclPos);
572 double distance = diff.mag();
575 if (distance < eclClusterDistance[c]) {
576 eclClusterDistance[c] = distance;
577 G4ErrorSymMatrix covariance(6, 0);
579 eclHit3[c].update(EXT_ECLNEAR, extState.
tof, pos / CLHEP::cm, mom / CLHEP::GeV, covariance);
582 if (eclHit1[c].getStatus() == EXT_FIRST) {
583 if (pos.mag2() >= eclPos.mag2()) {
584 double r = eclPos.mag();
585 double preD = prePos.mag() - r;
586 double postD = pos.mag() - r;
587 double f = postD / (postD - preD);
588 G4ThreeVector midPos = pos + (prePos - pos) * f;
589 double tof = extState.
tof + dt * f * (extState.
isCosmic ? +1 : -1);
590 G4ErrorSymMatrix covariance(6, 0);
592 eclHit1[c].update(EXT_ECLCROSS, tof, midPos / CLHEP::cm, mom / CLHEP::GeV, covariance);
597 if (eclHit2[c].getStatus() == EXT_FIRST) {
598 G4ThreeVector delta(pos - prePos);
599 G4ThreeVector perp(eclPos.cross(delta));
600 double perpMag2 = perp.mag2();
601 if (perpMag2 > 1.0E-10) {
602 double dist = std::fabs(diff * perp) / std::sqrt(perpMag2);
604 double f = eclPos * (prePos.cross(perp)) / perpMag2;
605 if ((f > -0.5) && (f <= 1.0)) {
606 G4ThreeVector midPos(prePos + f * delta);
607 double length = extState.
length + dl * (1.0 - f) * (extState.
isCosmic ? +1 : -1);
608 G4ErrorSymMatrix covariance(6, 0);
610 eclHit2[c].update(EXT_ECLDL, length, midPos / CLHEP::cm, mom / CLHEP::GeV, covariance);
617 if (klmClusterInfo !=
nullptr) {
618 for (
unsigned int c = 0; c < klmClusterInfo->size(); ++c) {
619 G4ThreeVector klmPos = (*klmClusterInfo)[c].second;
620 G4ThreeVector separation = klmPos - pos;
621 double distance = separation.mag();
622 if (distance < klmHit[c].getDistance()) {
623 klmHit[c].setDistance(distance);
624 klmHit[c].setTrackClusterAngle(mom.angle(separation));
625 klmHit[c].setTrackClusterSeparationAngle(mom.angle(klmPos));
626 klmHit[c].setTrackRotationAngle(extState.
directionAtIP.angle(mom));
627 klmHit[c].setTrackClusterInitialSeparationAngle(extState.
directionAtIP.angle(klmPos));
633 if (errCode || (mom.mag2() < minPSq)) {
646 m_ExtMgr->EventTermination(propagationMode);
650 if (eclClusterInfo !=
nullptr) {
651 for (
unsigned int c = 0; c < eclClusterInfo->size(); ++c) {
652 if (eclHit1[c].getStatus() != EXT_FIRST) {
654 (*eclClusterInfo)[c].first->addRelationTo(h);
655 if (extState.
track !=
nullptr) {
659 if (eclHit2[c].getStatus() != EXT_FIRST) {
661 (*eclClusterInfo)[c].first->addRelationTo(h);
662 if (extState.
track !=
nullptr) {
666 if (eclHit3[c].getStatus() != EXT_FIRST) {
668 (*eclClusterInfo)[c].first->addRelationTo(h);
669 if (extState.
track !=
nullptr) {
676 if (klmClusterInfo !=
nullptr) {
680 unsigned int closestCluster = 0;
681 for (
unsigned int c = 0; c < klmClusterInfo->size(); ++c) {
682 if (klmHit[c].getDistance() > 1.0E9) {
689 (*klmClusterInfo)[c].first->addRelationTo(h);
690 (*klmClusterInfo)[c].first->setClusterTrackSeparation(h->getDistance() / CLHEP::cm);
691 (*klmClusterInfo)[c].first->setClusterTrackSeparationAngle(h->getTrackClusterSeparationAngle());
692 (*klmClusterInfo)[c].first->setClusterTrackRotationAngle(h->getTrackRotationAngle());
693 if (extState.
track !=
nullptr) {
698 (*klmClusterInfo)[c].first->setClusterTrackSeparationAngle(
Const::doubleNaN);
701 if (klmHit[c].getDistance() < minDistance) {
703 minDistance = klmHit[c].getDistance();
709 if (extState.
track !=
nullptr) {
710 extState.
track->
addRelationTo((*klmClusterInfo)[closestCluster].first, 1. / (minDistance / CLHEP::cm));
721 if (g4eState.GetMomentum().perp() <=
m_MinPt)
723 if (
m_TargetExt->GetDistanceFromPoint(g4eState.GetPosition()) < 0.0)
725 G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable()->FindParticle(extState.
pdgCode);
726 double mass = particle->GetPDGMass();
727 double minPSq = (mass +
m_MinKE) * (mass +
m_MinKE) - mass * mass;
728 G4ErrorMode propagationMode = (extState.
isCosmic ? G4ErrorMode_PropBackwards : G4ErrorMode_PropForwards);
729 m_ExtMgr->InitTrackPropagation(propagationMode);
731 const G4int errCode =
m_ExtMgr->PropagateOneStep(&g4eState, propagationMode);
732 G4Track* track = g4eState.GetG4Track();
733 const G4Step* step = track->GetStep();
734 const G4StepPoint* preStepPoint = step->GetPreStepPoint();
735 const G4StepPoint* postStepPoint = step->GetPostStepPoint();
736 G4TouchableHandle preTouch = preStepPoint->GetTouchableHandle();
737 G4VPhysicalVolume* pVol = preTouch->GetVolume();
738 const G4int preStatus = preStepPoint->GetStepStatus();
739 const G4int postStatus = postStepPoint->GetStepStatus();
740 G4ThreeVector pos = track->GetPosition();
741 G4ThreeVector mom = track->GetMomentum();
745 if (preStatus == fUndefined) {
747 createExtHit(EXT_FIRST, extState, g4eState, preStepPoint, preTouch);
751 if (step->GetStepLength() > 0.0) {
752 double dt = step->GetDeltaTime();
753 double dl = step->GetStepLength() / track->GetMaterial()->GetRadlen();
754 if (preStatus == fGeomBoundary) {
756 createExtHit(EXT_ENTER, extState, g4eState, preStepPoint, preTouch);
767 if (postStatus == fGeomBoundary) {
769 createExtHit(EXT_EXIT, extState, g4eState, postStepPoint, preTouch);
774 if (errCode || (mom.mag2() < minPSq)) {
776 createExtHit(EXT_STOP, extState, g4eState, postStepPoint, preTouch);
781 if (
m_TargetExt->GetDistanceFromPoint(pos) < 0.0) {
783 createExtHit(EXT_ESCAPE, extState, g4eState, postStepPoint, preTouch);
793 m_ExtMgr->EventTermination(propagationMode);
800 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
801 if (pvStore->size() == 0) {
802 B2FATAL(
"No geometry defined. Please create the geometry first.");
806 m_EnterExit =
new std::map<G4VPhysicalVolume*, enum VolTypes>;
808 for (std::vector<G4VPhysicalVolume*>::iterator iVol = pvStore->begin();
809 iVol != pvStore->end(); ++iVol) {
810 const G4String name = (*iVol)->GetName();
813 if (name.find(
"TOPModule") != std::string::npos) {
817 else if (name.find(
"_TOPPrism_") != std::string::npos ||
818 name.find(
"_TOPBarSegment") != std::string::npos ||
819 name.find(
"_TOPMirrorSegment") != std::string::npos) {
823 else if (name.find(
"TOPBarSegment1Glue") != std::string::npos ||
824 name.find(
"TOPBarSegment2Glue") != std::string::npos ||
825 name.find(
"TOPMirrorSegmentGlue") != std::string::npos) {
828 }
else if (name ==
"ARICH.AerogelSupportPlate") {
830 }
else if (name ==
"ARICH.AerogelImgPlate") {
832 }
else if (name.find(
"ARICH.HAPDWindow") != std::string::npos) {
836 else if (name.find(
"lv_barrel_crystal_") != std::string::npos ||
837 name.find(
"lv_forward_crystal_") != std::string::npos ||
838 name.find(
"lv_backward_crystal_") != std::string::npos) {
843 else if (name.compare(0, 5,
"BKLM.") == 0) {
844 if (name.find(
"GasPhysical") != std::string::npos) {
846 }
else if (name.find(
"ScintActiveType") != std::string::npos) {
848 }
else if ((name.find(
"ScintType") != std::string::npos) ||
849 (name.find(
"ElectrodePhysical") != std::string::npos)) {
854 else if (name.compare(0, 14,
"StripSensitive") == 0) {
866 detID = Const::EDetector::invalidDetector;
869 G4VPhysicalVolume* pv = touch->GetVolume(0);
870 std::map<G4VPhysicalVolume*, enum VolTypes>::iterator it =
m_EnterExit->find(pv);
874 switch (it->second) {
876 detID = Const::EDetector::CDC;
877 copyID = pv->GetCopyNo();
880 detID = Const::EDetector::TOP;
881 copyID = -(pv->GetCopyNo());
884 detID = Const::EDetector::TOP;
885 if (touch->GetHistoryDepth() >= 1)
886 copyID = touch->GetVolume(1)->GetCopyNo();
889 detID = Const::EDetector::TOP;
890 if (touch->GetHistoryDepth() >= 2)
891 copyID = touch->GetVolume(2)->GetCopyNo();
894 detID = Const::EDetector::ARICH;
898 detID = Const::EDetector::ARICH;
902 detID = Const::EDetector::ARICH;
903 if (touch->GetHistoryDepth() >= 2)
904 copyID = touch->GetVolume(2)->GetCopyNo();
907 detID = Const::EDetector::ECL;
911 detID = Const::EDetector::BKLM;
912 if (touch->GetHistoryDepth() == DEPTH_RPC) {
914 int layer = touch->GetCopyNumber(4);
915 int sector = touch->GetCopyNumber(6);
916 int section = touch->GetCopyNumber(7);
921 detID = Const::EDetector::BKLM;
922 if (touch->GetHistoryDepth() == DEPTH_SCINT) {
923 int strip = touch->GetCopyNumber(1);
924 int plane = (touch->GetCopyNumber(2) == BKLM_INNER) ?
927 int layer = touch->GetCopyNumber(6);
928 int sector = touch->GetCopyNumber(8);
929 int section = touch->GetCopyNumber(9);
931 section, sector, layer, plane, strip);
936 detID = Const::EDetector::EKLM;
938 touch->GetVolume(7)->GetCopyNo(),
939 touch->GetVolume(6)->GetCopyNo(),
940 touch->GetVolume(5)->GetCopyNo(),
941 touch->GetVolume(4)->GetCopyNo(),
942 touch->GetVolume(1)->GetCopyNo());
950 ExtState extState = {&b2track, pdgCode,
false, 0.0, 0.0,
951 G4ThreeVector(0, 0, 1), 0.0, 0, 0, 0, -1, -1, -1, -1, 0, 0,
false
954 if (recoTrack ==
nullptr) {
955 B2WARNING(
"Track without associated RecoTrack: skipping extrapolation for this track.");
962 B2WARNING(
"RecoTrack fit failed for cardinal representation: skipping extrapolation for this track.");
966 int charge = int(trackRep->getPDGCharge());
972 TVector3 firstPosition, firstMomentum, lastPosition, lastMomentum;
973 TMatrixDSym firstCov(6), lastCov(6);
976 trackRep->getPosMomCov(firstState, firstPosition, firstMomentum, firstCov);
978 trackRep->getPosMomCov(lastState, lastPosition, lastMomentum, lastCov);
980 extState.
tof = lastState.getTime();
981 if (lastPosition.Mag2() < firstPosition.Mag2()) {
982 firstPosition = lastPosition;
983 firstMomentum = -lastMomentum;
985 trackRep->getPosMomCov(firstState, lastPosition, lastMomentum, lastCov);
986 lastMomentum *= -1.0;
988 extState.
tof = firstState.getTime();
991 G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable()->FindParticle(extState.
pdgCode);
992 if (extState.
pdgCode != trackRep->getPDG()) {
993 double pSq = lastMomentum.Mag2();
994 double mass = particle->GetPDGMass() / CLHEP::GeV;
995 extState.
tof *= std::sqrt((pSq + mass * mass) / (pSq + lastState.getMass() * lastState.getMass()));
998 extState.
directionAtIP.set(firstMomentum.Unit().X(), firstMomentum.Unit().Y(), firstMomentum.Unit().Z());
1000 double radius = (firstMomentum.Perp() * CLHEP::GeV / CLHEP::eV) / (CLHEP::c_light * charge *
m_MagneticField);
1002 double centerX = firstPosition.X() + radius * std::cos(centerPhi);
1003 double centerY = firstPosition.Y() + radius * std::sin(centerPhi);
1004 double pocaPhi = atan2(charge * centerY, charge * centerX) + M_PI;
1014 lastCov[0][0] = 5.0E-5;
1015 lastCov[1][1] = 1.0E-7;
1016 lastCov[2][2] = 5.0E-4;
1017 lastCov[3][3] = 3.5E-3;
1018 lastCov[4][4] = 3.5E-3;
1019 lastMomentum = lastMomentum.Unit() * 10.0;
1022 G4ThreeVector posG4e(lastPosition.X() * CLHEP::cm, lastPosition.Y() * CLHEP::cm,
1023 lastPosition.Z() * CLHEP::cm);
1024 G4ThreeVector momG4e(lastMomentum.X() * CLHEP::GeV, lastMomentum.Y() * CLHEP::GeV,
1025 lastMomentum.Z() * CLHEP::GeV);
1026 G4ErrorSymMatrix covG4e(5, 0);
1028 g4eState.SetData(
"g4e_" + particle->GetParticleName(), posG4e, momG4e);
1029 g4eState.SetParameters(posG4e, momG4e);
1030 g4eState.SetError(covG4e);
1031 }
catch (
const genfit::Exception&) {
1032 B2WARNING(
"genfit::MeasuredStateOnPlane() exception: skipping extrapolation for this track. initial momentum = ("
1033 << firstMomentum.X() <<
"," << firstMomentum.Y() <<
"," << firstMomentum.Z() <<
")");
1053 G4ErrorFreeTrajParam param = g4eState.GetParameters();
1054 double p = 1.0 / (param.GetInvP() * CLHEP::GeV);
1056 double lambda = param.GetLambda();
1057 double sinLambda = std::sin(lambda);
1058 double cosLambda = std::cos(lambda);
1059 double phi = param.GetPhi();
1060 double sinPhi = std::sin(phi);
1061 double cosPhi = std::cos(phi);
1065 G4ErrorMatrix jacobian(6, 5, 0);
1067 jacobian(4, 1) = -pSq * cosLambda * cosPhi;
1068 jacobian(5, 1) = -pSq * cosLambda * sinPhi;
1069 jacobian(6, 1) = -pSq * sinLambda;
1071 jacobian(4, 2) = -p * sinLambda * cosPhi;
1072 jacobian(5, 2) = -p * sinLambda * sinPhi;
1073 jacobian(6, 2) = p * cosLambda;
1075 jacobian(4, 3) = -p * cosLambda * sinPhi;
1076 jacobian(5, 3) = p * cosLambda * cosPhi;
1078 jacobian(1, 4) = -sinPhi;
1079 jacobian(2, 4) = cosPhi;
1081 jacobian(1, 5) = -sinLambda * cosPhi;
1082 jacobian(2, 5) = -sinLambda * sinPhi;
1083 jacobian(3, 5) = cosLambda;
1085 G4ErrorTrajErr g4eCov = g4eState.GetError();
1086 covariance.assign(g4eCov.similarity(jacobian));
1102 G4ErrorSymMatrix temp(6, 0);
1103 for (
int k = 0; k < 6; ++k) {
1104 for (
int j = k; j < 6; ++j) {
1105 temp[j][k] = covariance[j][k];
1109 double pInvSq = 1.0 / momentum.Mag2();
1110 double pInv = std::sqrt(pInvSq);
1111 double pPerpInv = 1.0 / momentum.Perp();
1112 double sinLambda = momentum.CosTheta();
1113 double cosLambda = std::sqrt(1.0 - sinLambda * sinLambda);
1114 double phi = momentum.Phi();
1115 double cosPhi = std::cos(phi);
1116 double sinPhi = std::sin(phi);
1119 G4ErrorMatrix jacobian(5, 6, 0);
1121 jacobian(1, 4) = -pInvSq * cosLambda * cosPhi;
1122 jacobian(1, 5) = -pInvSq * cosLambda * sinPhi;
1123 jacobian(1, 6) = -pInvSq * sinLambda;
1125 jacobian(2, 4) = -pInv * sinLambda * cosPhi;
1126 jacobian(2, 5) = -pInv * sinLambda * sinPhi;
1127 jacobian(2, 6) = pInv * cosLambda;
1129 jacobian(3, 4) = -pPerpInv * sinPhi;
1130 jacobian(3, 5) = pPerpInv * cosPhi;
1132 jacobian(4, 1) = -sinPhi;
1133 jacobian(4, 2) = cosPhi;
1135 jacobian(5, 1) = -sinLambda * cosPhi;
1136 jacobian(5, 2) = -sinLambda * sinPhi;
1137 jacobian(5, 3) = cosLambda;
1139 covG4e = temp.similarity(jacobian);
1144 G4ErrorTrajErr& covG4e)
1156 G4ErrorSymMatrix temp(covariance);
1158 double pInvSq = 1.0 / momentum.mag2();
1159 double pInv = std::sqrt(pInvSq);
1160 double pPerpInv = 1.0 / momentum.perp();
1161 double sinLambda = momentum.cosTheta();
1162 double cosLambda = std::sqrt(1.0 - sinLambda * sinLambda);
1163 double phi = momentum.phi();
1164 double cosPhi = std::cos(phi);
1165 double sinPhi = std::sin(phi);
1168 G4ErrorMatrix jacobian(5, 6, 0);
1170 jacobian(1, 4) = -pInvSq * cosLambda * cosPhi;
1171 jacobian(1, 5) = -pInvSq * cosLambda * sinPhi;
1172 jacobian(1, 6) = -pInvSq * sinLambda;
1174 jacobian(2, 4) = -pInv * sinLambda * cosPhi;
1175 jacobian(2, 5) = -pInv * sinLambda * sinPhi;
1176 jacobian(2, 6) = pInv * cosLambda;
1178 jacobian(3, 4) = -pPerpInv * sinPhi;
1179 jacobian(3, 5) = pPerpInv * cosPhi;
1181 jacobian(4, 1) = -sinPhi;
1182 jacobian(4, 2) = cosPhi;
1184 jacobian(5, 1) = -sinLambda * cosPhi;
1185 jacobian(5, 2) = -sinLambda * sinPhi;
1186 jacobian(5, 3) = cosLambda;
1187 covG4e = temp.similarity(jacobian);
1193 const G4ErrorFreeTrajState& g4eState,
1194 const G4StepPoint* stepPoint,
const G4TouchableHandle& touch)
1199 G4ThreeVector pos(stepPoint->GetPosition() / CLHEP::cm);
1200 G4ThreeVector mom(stepPoint->GetMomentum() / CLHEP::GeV);
1203 G4ErrorSymMatrix covariance(6, 0);
1207 pos, mom, covariance);
1209 if (extState.
track !=
nullptr)
1217 std::vector<std::map<const Track*, double> >* bklmHitUsed)
1221 intersection.
hit = -1;
1222 intersection.
chi2 = -1.0;
1223 intersection.
position = g4eState.GetPosition() / CLHEP::cm;
1224 intersection.
momentum = g4eState.GetMomentum() / CLHEP::GeV;
1225 G4ThreeVector prePos = g4eState.GetG4Track()->GetStep()->GetPreStepPoint()->GetPosition() / CLHEP::cm;
1226 G4ThreeVector oldPosition(prePos.x(), prePos.y(), prePos.z());
1227 double r = intersection.
position.perp();
1236 (*bklmHitUsed)[intersection.
hit].insert(std::pair<const Track*, double>(extState.
track, intersection.
chi2));
1238 float layerBarrelEfficiency = 1.;
1242 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1256 intersection.
chi2 = -1.0;
1261 g4eState.GetG4Track()->GetVolume());
1267 int sector = intersection.
sector + 1;
1268 int layer = intersection.
layer + 1;
1271 const CLHEP::Hep3Vector localPosition = m->globalToLocal(intersection.
position);
1272 int zStrip = m->getZStripNumber(localPosition);
1273 int phiStrip = m->getPhiStripNumber(localPosition);
1274 if (zStrip >= 0 && phiStrip >= 0) {
1275 uint16_t channel1, channel2;
1277 section, sector, layer,
1280 section, sector, layer,
1287 B2ERROR(
"No KLM channel status data."
1288 <<
LogVar(
"Section", section)
1289 <<
LogVar(
"Sector", sector)
1290 <<
LogVar(
"Layer", layer)
1291 <<
LogVar(
"Z strip", zStrip)
1292 <<
LogVar(
"Phi strip", phiStrip));
1299 float layerBarrelEfficiency = 1.;
1303 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1324 float layerEndcapEfficiency = 1.;
1328 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1342 intersection.
chi2 = -1.0;
1346 int result, strip1, strip2;
1348 intersection.
position, &strip1, &strip2);
1350 uint16_t channel1, channel2;
1358 B2ERROR(
"Incomplete KLM channel status data.");
1364 float layerEndcapEfficiency = 1.;
1368 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1383 if (intersection.
chi2 >= 0.0) {
1384 ROOT::Math::XYZVector tpos(intersection.
position.x(),
1393 tpos, tposAtHitPlane,
1394 extState.
tof, intersection.
time,
1397 G4Point3D newPos(intersection.
position.x() * CLHEP::cm,
1398 intersection.
position.y() * CLHEP::cm,
1399 intersection.
position.z() * CLHEP::cm);
1400 g4eState.SetPosition(newPos);
1401 G4Vector3D newMom(intersection.
momentum.x() * CLHEP::GeV,
1402 intersection.
momentum.y() * CLHEP::GeV,
1403 intersection.
momentum.z() * CLHEP::GeV);
1404 g4eState.SetMomentum(newMom);
1405 G4ErrorTrajErr covG4e;
1407 g4eState.SetError(covG4e);
1408 extState.
chi2 += intersection.
chi2;
1424 double phi = intersection.
position.phi();
1427 if (phi > TWOPI - PI_8)
1429 int sector = (int)((phi + PI_8) / M_PI_4);
1442 intersection.
layer = layer;
1443 intersection.
sector = sector;
1459 double oldZ = std::fabs(oldPosition.z() -
m_OffsetZ);
1464 for (
int layer = extState.
firstEndcapLayer; layer <= outermostLayer; ++layer) {
1473 intersection.
layer = layer;
1475 isForward ? 2 : 1, intersection.
position) - 1;
1485 G4ThreeVector extPos0(intersection.
position);
1486 double diffBestMagSq = 1.0E60;
1488 int matchingLayer = intersection.
layer + 1;
1490 for (
int h = 0; h <
m_klmHit2ds.getEntries(); ++h) {
1494 if (hit->getLayer() != matchingLayer)
1496 if (hit->isOutOfTime())
1500 G4ThreeVector diff(hit->getPositionX() - intersection.
position.x(),
1501 hit->getPositionY() - intersection.
position.y(),
1502 hit->getPositionZ() - intersection.
position.z());
1503 double dn = diff * n;
1504 if (std::fabs(dn) < 2.0) {
1507 if (diff.mag2() < diffBestMagSq) {
1508 diffBestMagSq = diff.mag2();
1514 if (std::fabs(dn) > 50.0)
1516 int sector = hit->getSector() - 1;
1517 int dSector = abs(intersection.
sector - sector);
1526 dn = diff * nHit + dn2;
1527 if (std::fabs(dn) > 1.0)
1530 G4ThreeVector extDir(intersection.
momentum.unit());
1531 double extDirA = extDir * nHit;
1532 if (std::fabs(extDirA) < 1.0E-6)
1534 G4ThreeVector projection = extDir * (dn2 / extDirA);
1535 if (projection.mag() > 15.0)
1537 diff += projection - nHit * dn;
1538 if (diff.mag2() < diffBestMagSq) {
1539 diffBestMagSq = diff.mag2();
1541 extPos0 = intersection.
position - projection;
1548 intersection.
isForward = (hit->getSection() == 1);
1549 intersection.
sector = hit->getSector() - 1;
1550 intersection.
time = hit->getTime();
1553 int nStrips = hit->getPhiStripMax() - hit->getPhiStripMin() + 1;
1554 double dn = nStrips - 1.5;
1555 double factor = std::pow((0.9 + 0.4 * dn * dn), 1.5) * 0.60;
1557 nStrips = hit->getZStripMax() - hit->getZStripMin() + 1;
1559 factor = std::pow((0.9 + 0.4 * dn * dn), 1.5) * 0.55;
1562 int nStrips = hit->getPhiStripMax() - hit->getPhiStripMin() + 1;
1563 localVariance[0] *= (nStrips * nStrips);
1564 nStrips = hit->getZStripMax() - hit->getZStripMin() + 1;
1565 localVariance[1] *= (nStrips * nStrips);
1567 G4ThreeVector hitPos(hit->getPositionX(), hit->getPositionY(),
1568 hit->getPositionZ());
1570 if (intersection.
chi2 >= 0.0) {
1571 intersection.
hit = bestHit;
1572 hit->isOnTrack(
true);
1573 if (track !=
nullptr) {
1574 track->addRelationTo(hit, intersection.
chi2);
1582 return intersection.
chi2 >= 0.0;
1588 double diffBestMagSq = 1.0E60;
1590 int matchingLayer = intersection.
layer + 1;
1591 int matchingEndcap = (intersection.
isForward ? 2 : 1);
1592 G4ThreeVector n(0.0, 0.0, (intersection.
isForward ? 1.0 : -1.0));
1593 for (
int h = 0; h <
m_klmHit2ds.getEntries(); ++h) {
1597 if (hit->getLayer() != matchingLayer)
1599 if (hit->getSection() != matchingEndcap)
1605 G4ThreeVector diff(hit->getPositionX() - intersection.
position.x(),
1606 hit->getPositionY() - intersection.
position.y(),
1607 hit->getPositionZ() - intersection.
position.z());
1608 double dn = diff * n;
1609 if (std::fabs(dn) > 2.0)
1612 if (diff.mag2() < diffBestMagSq) {
1613 diffBestMagSq = diff.mag2();
1620 intersection.
hit = bestHit;
1621 intersection.
isForward = (hit->getSection() == 2);
1622 intersection.
sector = hit->getSector() - 1;
1623 intersection.
time = hit->getTime();
1625 int nStrips = hit->getXStripMax() - hit->getXStripMin() + 1;
1626 localVariance[0] *= (nStrips * nStrips);
1627 nStrips = hit->getYStripMax() - hit->getYStripMin() + 1;
1628 localVariance[1] *= (nStrips * nStrips);
1629 G4ThreeVector hitPos(hit->getPositionX(), hit->getPositionY(), hit->getPositionZ());
1631 if (intersection.
chi2 >= 0.0) {
1634 if (track !=
nullptr) {
1635 track->addRelationTo(hit, intersection.
chi2);
1645 return intersection.
chi2 >= 0.0;
1650 const G4ThreeVector& hitPos,
const G4ThreeVector& extPos0)
1670 G4ThreeVector extPos(extPos0);
1671 G4ThreeVector extMom(intersection.
momentum);
1672 G4ThreeVector extDir(extMom.unit());
1673 G4ThreeVector diffPos(hitPos - extPos);
1674 G4ErrorSymMatrix extCov(intersection.
covariance);
1676 G4ErrorMatrix extPar(6, 1);
1677 extPar[0][0] = extPos.x();
1678 extPar[1][0] = extPos.y();
1679 extPar[2][0] = extPos.z();
1680 extPar[3][0] = extMom.x();
1681 extPar[4][0] = extMom.y();
1682 extPar[5][0] = extMom.z();
1689 nC = G4ThreeVector(0.0, 0.0, 1.0);
1691 double out = (intersection.
isForward ? 1.0 : -1.0);
1692 nA = G4ThreeVector(0.0, 0.0, out);
1693 nB = G4ThreeVector(out, 0.0, 0.0);
1694 nC = G4ThreeVector(0.0, out, 0.0);
1697 double extDirA = extDir * nA;
1698 if (std::fabs(extDirA) < 1.0E-6)
1700 double extDirBA = extDir * nB / extDirA;
1701 double extDirCA = extDir * nC / extDirA;
1704 G4ThreeVector move = extDir * ((diffPos * nA) / extDirA);
1709 G4ErrorMatrix jacobian(2, 6);
1710 jacobian[0][0] = nB.x() - nA.x() * extDirBA;
1711 jacobian[0][1] = nB.y() - nA.y() * extDirBA;
1712 jacobian[0][2] = nB.z() - nA.z() * extDirBA;
1713 jacobian[1][0] = nC.x() - nA.x() * extDirCA;
1714 jacobian[1][1] = nC.y() - nA.y() * extDirCA;
1715 jacobian[1][2] = nC.z() - nA.z() * extDirCA;
1717 G4ErrorMatrix residual(2, 1);
1718 residual[0][0] = diffPos.x() * jacobian[0][0] + diffPos.y() * jacobian[0][1] + diffPos.z() * jacobian[0][2];
1719 residual[1][0] = diffPos.x() * jacobian[1][0] + diffPos.y() * jacobian[1][1] + diffPos.z() * jacobian[1][2];
1721 G4ErrorSymMatrix hitCov(2, 0);
1722 hitCov[0][0] = localVariance[0];
1723 hitCov[1][1] = localVariance[1];
1726 hitCov[0][0] *= 10.0;
1727 hitCov[1][1] *= 10.0;
1731 G4ErrorSymMatrix correction(extCov.similarity(jacobian) + hitCov);
1738 correction.invert(fail);
1744 intersection.
chi2 = (correction.similarityT(residual))[0][0];
1746 G4ErrorMatrix gain((extCov * jacobian.T()) * correction);
1747 G4ErrorSymMatrix HRH(correction.similarityT(jacobian));
1748 extCov -= HRH.similarity(extCov);
1749 extPar += gain * residual;
1750 extPos.set(extPar[0][0], extPar[1][0], extPar[2][0]);
1751 extMom.set(extPar[3][0], extPar[4][0], extPar[5][0]);
1753 correction = hitCov - extCov.similarity(jacobian);
1754 correction.invert(fail);
1757 diffPos = hitPos - extPos;
1758 residual[0][0] = diffPos.x() * jacobian[0][0] + diffPos.y() * jacobian[0][1] + diffPos.z() * jacobian[0][2];
1759 residual[1][0] = diffPos.x() * jacobian[1][0] + diffPos.y() * jacobian[1][1] + diffPos.z() * jacobian[1][2];
1760 intersection.
chi2 = (correction.similarityT(residual))[0][0];
1767 intersection.
position = extPos + extDir * (((intersection.
position - extPos) * nA) / extDirA);
1793 if (outcome != MuidElementNumbers::c_NotReached) {
1795 int charge = klmMuidLikelihood->
getCharge();
1797 std::map<int, double> mapPdgPDF;
1798 for (
int pdg : signedPdgVector) {
1801 B2FATAL(
"Something went wrong: PDF for PDG code " << pdg <<
" not found!");
1802 double pdf = (search->second)->getPDF(klmMuidLikelihood);
1804 mapPdgPDF.insert(std::pair<int, double>(std::abs(pdg), pdf));
1806 if (denom < 1.0E-20)
1809 for (
auto const& [pdg, pdf] : mapPdgPDF) {
1810 klmMuidLikelihood->
setPDFValue(pdf, std::abs(pdg));
1812 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