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)
80 m_ExtInitialized(false),
81 m_MuidInitialized(false),
85 m_MaxDistSqInVariances(0.0),
86 m_MaxKLMTrackClusterDistance(0.0),
87 m_MaxECLTrackClusterDistance(0.0),
91 m_HypothesesExt(nullptr),
92 m_HypothesesMuid(nullptr),
93 m_DefaultHypotheses(nullptr),
95 m_BKLMVolumes(nullptr),
97 m_TargetMuid(nullptr),
103 m_BarrelHalfLength(0.0),
104 m_OutermostActiveBarrelLayer(0),
105 m_BarrelScintVariance(0.0),
108 m_EndcapMiddleZ(0.0),
109 m_EndcapHalfLength(0.0),
110 m_OutermostActiveForwardEndcapLayer(0),
111 m_OutermostActiveBackwardEndcapLayer(0),
112 m_EndcapScintVariance(0.0),
113 m_eklmTransformData(nullptr)
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)
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(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);
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) {
545 createExtHit(EXT_ENTER, extState, g4eState, preStepPoint, preTouch);
556 if (postStatus == fGeomBoundary) {
559 createExtHit(EXT_EXIT, extState, g4eState, postStepPoint, preTouch);
563 if (
createMuidHit(extState, g4eState, klmMuidLikelihood, bklmHitUsed)) {
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)) {
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) {
686 (*klmClusterInfo)[c].first->addRelationTo(h);
687 if (extState.
track !=
nullptr) {
690 if (klmHit[c].getDistance() < minDistance) {
692 minDistance = klmHit[c].getDistance();
698 if (extState.
track !=
nullptr) {
699 extState.
track->
addRelationTo((*klmClusterInfo)[closestCluster].first, 1. / (minDistance / CLHEP::cm));
711 if (g4eState.GetMomentum().perp() <=
m_MinPt)
715 G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable()->FindParticle(extState.
pdgCode);
716 double mass = particle->GetPDGMass();
717 double minPSq = (mass +
m_MinKE) * (mass +
m_MinKE) - mass * mass;
718 G4ErrorMode propagationMode = (extState.
isCosmic ? G4ErrorMode_PropBackwards : G4ErrorMode_PropForwards);
722 G4Track* track = g4eState.GetG4Track();
723 const G4Step* step = track->GetStep();
724 const G4StepPoint* preStepPoint = step->GetPreStepPoint();
725 const G4StepPoint* postStepPoint = step->GetPostStepPoint();
726 G4TouchableHandle preTouch = preStepPoint->GetTouchableHandle();
727 G4VPhysicalVolume* pVol = preTouch->GetVolume();
728 const G4int preStatus = preStepPoint->GetStepStatus();
729 const G4int postStatus = postStepPoint->GetStepStatus();
730 G4ThreeVector pos = track->GetPosition();
731 G4ThreeVector mom = track->GetMomentum();
735 if (preStatus == fUndefined) {
737 createExtHit(EXT_FIRST, extState, g4eState, preStepPoint, preTouch);
741 if (step->GetStepLength() > 0.0) {
742 double dt = step->GetDeltaTime();
743 double dl = step->GetStepLength() / track->GetMaterial()->GetRadlen();
744 if (preStatus == fGeomBoundary) {
746 createExtHit(EXT_ENTER, extState, g4eState, preStepPoint, preTouch);
757 if (postStatus == fGeomBoundary) {
759 createExtHit(EXT_EXIT, extState, g4eState, postStepPoint, preTouch);
764 if (errCode || (mom.mag2() < minPSq)) {
766 createExtHit(EXT_STOP, extState, g4eState, postStepPoint, preTouch);
773 createExtHit(EXT_ESCAPE, extState, g4eState, postStepPoint, preTouch);
790 G4PhysicalVolumeStore* pvStore = G4PhysicalVolumeStore::GetInstance();
791 if (pvStore->size() == 0) {
792 B2FATAL(
"No geometry defined. Please create the geometry first.");
796 m_EnterExit =
new std::map<G4VPhysicalVolume*, enum VolTypes>;
798 for (std::vector<G4VPhysicalVolume*>::iterator iVol = pvStore->begin();
799 iVol != pvStore->end(); ++iVol) {
800 const G4String name = (*iVol)->GetName();
803 if (name.find(
"TOPModule") != std::string::npos) {
807 else if (name.find(
"_TOPPrism_") != std::string::npos ||
808 name.find(
"_TOPBarSegment") != std::string::npos ||
809 name.find(
"_TOPMirrorSegment") != std::string::npos) {
813 else if (name.find(
"TOPBarSegment1Glue") != std::string::npos ||
814 name.find(
"TOPBarSegment2Glue") != std::string::npos ||
815 name.find(
"TOPMirrorSegmentGlue") != std::string::npos) {
818 }
else if (name ==
"ARICH.AerogelSupportPlate") {
820 }
else if (name ==
"ARICH.AerogelImgPlate") {
822 }
else if (name.find(
"ARICH.HAPDWindow") != std::string::npos) {
826 else if (name.find(
"lv_barrel_crystal_") != std::string::npos ||
827 name.find(
"lv_forward_crystal_") != std::string::npos ||
828 name.find(
"lv_backward_crystal_") != std::string::npos) {
833 else if (name.compare(0, 5,
"BKLM.") == 0) {
834 if (name.find(
"GasPhysical") != std::string::npos) {
836 }
else if (name.find(
"ScintActiveType") != std::string::npos) {
838 }
else if ((name.find(
"ScintType") != std::string::npos) ||
839 (name.find(
"ElectrodePhysical") != std::string::npos)) {
844 else if (name.compare(0, 14,
"StripSensitive") == 0) {
856 detID = Const::EDetector::invalidDetector;
859 G4VPhysicalVolume* pv = touch->GetVolume(0);
860 std::map<G4VPhysicalVolume*, enum VolTypes>::iterator it =
m_EnterExit->find(pv);
864 switch (it->second) {
866 detID = Const::EDetector::CDC;
867 copyID = pv->GetCopyNo();
870 detID = Const::EDetector::TOP;
871 copyID = -(pv->GetCopyNo());
874 detID = Const::EDetector::TOP;
875 if (touch->GetHistoryDepth() >= 1)
876 copyID = touch->GetVolume(1)->GetCopyNo();
879 detID = Const::EDetector::TOP;
880 if (touch->GetHistoryDepth() >= 2)
881 copyID = touch->GetVolume(2)->GetCopyNo();
884 detID = Const::EDetector::ARICH;
888 detID = Const::EDetector::ARICH;
892 detID = Const::EDetector::ARICH;
893 if (touch->GetHistoryDepth() >= 2)
894 copyID = touch->GetVolume(2)->GetCopyNo();
897 detID = Const::EDetector::ECL;
901 detID = Const::EDetector::BKLM;
902 if (touch->GetHistoryDepth() == DEPTH_RPC) {
904 int layer = touch->GetCopyNumber(4);
905 int sector = touch->GetCopyNumber(6);
906 int section = touch->GetCopyNumber(7);
911 detID = Const::EDetector::BKLM;
912 if (touch->GetHistoryDepth() == DEPTH_SCINT) {
913 int strip = touch->GetCopyNumber(1);
914 int plane = (touch->GetCopyNumber(2) == BKLM_INNER) ?
917 int layer = touch->GetCopyNumber(6);
918 int sector = touch->GetCopyNumber(8);
919 int section = touch->GetCopyNumber(9);
921 section, sector, layer, plane, strip);
926 detID = Const::EDetector::EKLM;
928 touch->GetVolume(7)->GetCopyNo(),
929 touch->GetVolume(6)->GetCopyNo(),
930 touch->GetVolume(5)->GetCopyNo(),
931 touch->GetVolume(4)->GetCopyNo(),
932 touch->GetVolume(1)->GetCopyNo());
940 ExtState extState = {&b2track, pdgCode,
false, 0.0, 0.0,
941 G4ThreeVector(0, 0, 1), 0.0, 0, 0, 0, -1, -1, -1, -1, 0, 0,
false
944 if (recoTrack ==
nullptr) {
945 B2WARNING(
"Track without associated RecoTrack: skipping extrapolation for this track.");
952 B2WARNING(
"RecoTrack fit failed for cardinal representation: skipping extrapolation for this track.");
956 int charge = int(trackRep->getPDGCharge());
962 TVector3 firstPosition, firstMomentum, lastPosition, lastMomentum;
963 TMatrixDSym firstCov(6), lastCov(6);
966 trackRep->getPosMomCov(firstState, firstPosition, firstMomentum, firstCov);
968 trackRep->getPosMomCov(lastState, lastPosition, lastMomentum, lastCov);
970 extState.
tof = lastState.getTime();
971 if (lastPosition.Mag2() < firstPosition.Mag2()) {
972 firstPosition = lastPosition;
973 firstMomentum = -lastMomentum;
975 trackRep->getPosMomCov(firstState, lastPosition, lastMomentum, lastCov);
976 lastMomentum *= -1.0;
978 extState.
tof = firstState.getTime();
981 G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable()->FindParticle(extState.
pdgCode);
982 if (extState.
pdgCode != trackRep->getPDG()) {
983 double pSq = lastMomentum.Mag2();
984 double mass = particle->GetPDGMass() / CLHEP::GeV;
985 extState.
tof *= std::sqrt((pSq + mass * mass) / (pSq + lastState.getMass() * lastState.getMass()));
988 extState.
directionAtIP.set(firstMomentum.Unit().X(), firstMomentum.Unit().Y(), firstMomentum.Unit().Z());
990 double radius = (firstMomentum.Perp() * CLHEP::GeV / CLHEP::eV) / (CLHEP::c_light * charge *
m_MagneticField);
992 double centerX = firstPosition.X() + radius * std::cos(centerPhi);
993 double centerY = firstPosition.Y() + radius * std::sin(centerPhi);
994 double pocaPhi = atan2(charge * centerY, charge * centerX) + M_PI;
1004 lastCov[0][0] = 5.0E-5;
1005 lastCov[1][1] = 1.0E-7;
1006 lastCov[2][2] = 5.0E-4;
1007 lastCov[3][3] = 3.5E-3;
1008 lastCov[4][4] = 3.5E-3;
1009 lastMomentum = lastMomentum.Unit() * 10.0;
1012 G4ThreeVector posG4e(lastPosition.X() * CLHEP::cm, lastPosition.Y() * CLHEP::cm,
1013 lastPosition.Z() * CLHEP::cm);
1014 G4ThreeVector momG4e(lastMomentum.X() * CLHEP::GeV, lastMomentum.Y() * CLHEP::GeV,
1015 lastMomentum.Z() * CLHEP::GeV);
1016 G4ErrorSymMatrix covG4e(5, 0);
1018 g4eState.SetData(
"g4e_" + particle->GetParticleName(), posG4e, momG4e);
1019 g4eState.SetParameters(posG4e, momG4e);
1020 g4eState.SetError(covG4e);
1021 }
catch (
const genfit::Exception&) {
1022 B2WARNING(
"genfit::MeasuredStateOnPlane() exception: skipping extrapolation for this track. initial momentum = ("
1023 << firstMomentum.X() <<
"," << firstMomentum.Y() <<
"," << firstMomentum.Z() <<
")");
1043 G4ErrorFreeTrajParam param = g4eState.GetParameters();
1044 double p = 1.0 / (param.GetInvP() * CLHEP::GeV);
1046 double lambda = param.GetLambda();
1047 double sinLambda = std::sin(lambda);
1048 double cosLambda = std::cos(lambda);
1049 double phi = param.GetPhi();
1050 double sinPhi = std::sin(phi);
1051 double cosPhi = std::cos(phi);
1055 G4ErrorMatrix jacobian(6, 5, 0);
1057 jacobian(4, 1) = -pSq * cosLambda * cosPhi;
1058 jacobian(5, 1) = -pSq * cosLambda * sinPhi;
1059 jacobian(6, 1) = -pSq * sinLambda;
1061 jacobian(4, 2) = -p * sinLambda * cosPhi;
1062 jacobian(5, 2) = -p * sinLambda * sinPhi;
1063 jacobian(6, 2) = p * cosLambda;
1065 jacobian(4, 3) = -p * cosLambda * sinPhi;
1066 jacobian(5, 3) = p * cosLambda * cosPhi;
1068 jacobian(1, 4) = -sinPhi;
1069 jacobian(2, 4) = cosPhi;
1071 jacobian(1, 5) = -sinLambda * cosPhi;
1072 jacobian(2, 5) = -sinLambda * sinPhi;
1073 jacobian(3, 5) = cosLambda;
1075 G4ErrorTrajErr g4eCov = g4eState.GetError();
1076 covariance.assign(g4eCov.similarity(jacobian));
1092 G4ErrorSymMatrix temp(6, 0);
1093 for (
int k = 0; k < 6; ++k) {
1094 for (
int j = k; j < 6; ++j) {
1095 temp[j][k] = covariance[j][k];
1099 double pInvSq = 1.0 / momentum.Mag2();
1100 double pInv = std::sqrt(pInvSq);
1101 double pPerpInv = 1.0 / momentum.Perp();
1102 double sinLambda = momentum.CosTheta();
1103 double cosLambda = std::sqrt(1.0 - sinLambda * sinLambda);
1104 double phi = momentum.Phi();
1105 double cosPhi = std::cos(phi);
1106 double sinPhi = std::sin(phi);
1109 G4ErrorMatrix jacobian(5, 6, 0);
1111 jacobian(1, 4) = -pInvSq * cosLambda * cosPhi;
1112 jacobian(1, 5) = -pInvSq * cosLambda * sinPhi;
1113 jacobian(1, 6) = -pInvSq * sinLambda;
1115 jacobian(2, 4) = -pInv * sinLambda * cosPhi;
1116 jacobian(2, 5) = -pInv * sinLambda * sinPhi;
1117 jacobian(2, 6) = pInv * cosLambda;
1119 jacobian(3, 4) = -pPerpInv * sinPhi;
1120 jacobian(3, 5) = pPerpInv * cosPhi;
1122 jacobian(4, 1) = -sinPhi;
1123 jacobian(4, 2) = cosPhi;
1125 jacobian(5, 1) = -sinLambda * cosPhi;
1126 jacobian(5, 2) = -sinLambda * sinPhi;
1127 jacobian(5, 3) = cosLambda;
1129 covG4e = temp.similarity(jacobian);
1134 G4ErrorTrajErr& covG4e)
1146 G4ErrorSymMatrix temp(covariance);
1148 double pInvSq = 1.0 / momentum.mag2();
1149 double pInv = std::sqrt(pInvSq);
1150 double pPerpInv = 1.0 / momentum.perp();
1151 double sinLambda = momentum.cosTheta();
1152 double cosLambda = std::sqrt(1.0 - sinLambda * sinLambda);
1153 double phi = momentum.phi();
1154 double cosPhi = std::cos(phi);
1155 double sinPhi = std::sin(phi);
1158 G4ErrorMatrix jacobian(5, 6, 0);
1160 jacobian(1, 4) = -pInvSq * cosLambda * cosPhi;
1161 jacobian(1, 5) = -pInvSq * cosLambda * sinPhi;
1162 jacobian(1, 6) = -pInvSq * sinLambda;
1164 jacobian(2, 4) = -pInv * sinLambda * cosPhi;
1165 jacobian(2, 5) = -pInv * sinLambda * sinPhi;
1166 jacobian(2, 6) = pInv * cosLambda;
1168 jacobian(3, 4) = -pPerpInv * sinPhi;
1169 jacobian(3, 5) = pPerpInv * cosPhi;
1171 jacobian(4, 1) = -sinPhi;
1172 jacobian(4, 2) = cosPhi;
1174 jacobian(5, 1) = -sinLambda * cosPhi;
1175 jacobian(5, 2) = -sinLambda * sinPhi;
1176 jacobian(5, 3) = cosLambda;
1177 covG4e = temp.similarity(jacobian);
1183 const G4ErrorFreeTrajState& g4eState,
1184 const G4StepPoint* stepPoint,
const G4TouchableHandle& touch)
1189 G4ThreeVector pos(stepPoint->GetPosition() / CLHEP::cm);
1190 G4ThreeVector mom(stepPoint->GetMomentum() / CLHEP::GeV);
1193 G4ErrorSymMatrix covariance(6, 0);
1197 pos, mom, covariance);
1199 if (extState.
track !=
nullptr)
1207 std::vector<std::map<const Track*, double> >* bklmHitUsed)
1211 intersection.
hit = -1;
1212 intersection.
chi2 = -1.0;
1213 intersection.
position = g4eState.GetPosition() / CLHEP::cm;
1214 intersection.
momentum = g4eState.GetMomentum() / CLHEP::GeV;
1215 G4ThreeVector prePos = g4eState.GetG4Track()->GetStep()->GetPreStepPoint()->GetPosition() / CLHEP::cm;
1216 G4ThreeVector oldPosition(prePos.x(), prePos.y(), prePos.z());
1217 double r = intersection.
position.perp();
1226 (*bklmHitUsed)[intersection.
hit].insert(std::pair<const Track*, double>(extState.
track, intersection.
chi2));
1228 float layerBarrelEfficiency = 1.;
1232 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1246 intersection.
chi2 = -1.0;
1251 g4eState.GetG4Track()->GetVolume());
1257 int sector = intersection.
sector + 1;
1258 int layer = intersection.
layer + 1;
1261 const CLHEP::Hep3Vector localPosition = m->globalToLocal(intersection.
position);
1262 int zStrip = m->getZStripNumber(localPosition);
1263 int phiStrip = m->getPhiStripNumber(localPosition);
1264 if (zStrip >= 0 && phiStrip >= 0) {
1265 uint16_t channel1, channel2;
1267 section, sector, layer,
1270 section, sector, layer,
1277 B2ERROR(
"No KLM channel status data."
1278 <<
LogVar(
"Section", section)
1279 <<
LogVar(
"Sector", sector)
1280 <<
LogVar(
"Layer", layer)
1281 <<
LogVar(
"Z strip", zStrip)
1282 <<
LogVar(
"Phi strip", phiStrip));
1289 float layerBarrelEfficiency = 1.;
1293 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1314 float layerEndcapEfficiency = 1.;
1318 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1332 intersection.
chi2 = -1.0;
1336 int result, strip1, strip2;
1338 intersection.
position, &strip1, &strip2);
1340 uint16_t channel1, channel2;
1348 B2ERROR(
"Incomplete KLM channel status data.");
1354 float layerEndcapEfficiency = 1.;
1358 intersection.
sector + 1, intersection.
layer + 1, plane, 1);
1373 if (intersection.
chi2 >= 0.0) {
1374 ROOT::Math::XYZVector tpos(intersection.
position.x(),
1383 tpos, tposAtHitPlane,
1384 extState.
tof, intersection.
time,
1387 G4Point3D newPos(intersection.
position.x() * CLHEP::cm,
1388 intersection.
position.y() * CLHEP::cm,
1389 intersection.
position.z() * CLHEP::cm);
1390 g4eState.SetPosition(newPos);
1391 G4Vector3D newMom(intersection.
momentum.x() * CLHEP::GeV,
1392 intersection.
momentum.y() * CLHEP::GeV,
1393 intersection.
momentum.z() * CLHEP::GeV);
1394 g4eState.SetMomentum(newMom);
1395 G4ErrorTrajErr covG4e;
1397 g4eState.SetError(covG4e);
1398 extState.
chi2 += intersection.
chi2;
1414 double phi = intersection.
position.phi();
1417 if (phi > TWOPI - PI_8)
1419 int sector = (int)((phi + PI_8) / M_PI_4);
1432 intersection.
layer = layer;
1433 intersection.
sector = sector;
1449 double oldZ = std::fabs(oldPosition.z() -
m_OffsetZ);
1454 for (
int layer = extState.
firstEndcapLayer; layer <= outermostLayer; ++layer) {
1463 intersection.
layer = layer;
1465 isForward ? 2 : 1, intersection.
position) - 1;
1475 G4ThreeVector extPos0(intersection.
position);
1476 double diffBestMagSq = 1.0E60;
1478 int matchingLayer = intersection.
layer + 1;
1480 for (
int h = 0; h <
m_klmHit2ds.getEntries(); ++h) {
1484 if (hit->getLayer() != matchingLayer)
1486 if (hit->isOutOfTime())
1490 G4ThreeVector diff(hit->getPositionX() - intersection.
position.x(),
1491 hit->getPositionY() - intersection.
position.y(),
1492 hit->getPositionZ() - intersection.
position.z());
1493 double dn = diff * n;
1494 if (std::fabs(dn) < 2.0) {
1497 if (diff.mag2() < diffBestMagSq) {
1498 diffBestMagSq = diff.mag2();
1504 if (std::fabs(dn) > 50.0)
1506 int sector = hit->getSector() - 1;
1507 int dSector = abs(intersection.
sector - sector);
1516 dn = diff * nHit + dn2;
1517 if (std::fabs(dn) > 1.0)
1520 G4ThreeVector extDir(intersection.
momentum.unit());
1521 double extDirA = extDir * nHit;
1522 if (std::fabs(extDirA) < 1.0E-6)
1524 G4ThreeVector projection = extDir * (dn2 / extDirA);
1525 if (projection.mag() > 15.0)
1527 diff += projection - nHit * dn;
1528 if (diff.mag2() < diffBestMagSq) {
1529 diffBestMagSq = diff.mag2();
1531 extPos0 = intersection.
position - projection;
1538 intersection.
isForward = (hit->getSection() == 1);
1539 intersection.
sector = hit->getSector() - 1;
1540 intersection.
time = hit->getTime();
1543 int nStrips = hit->getPhiStripMax() - hit->getPhiStripMin() + 1;
1544 double dn = nStrips - 1.5;
1545 double factor = std::pow((0.9 + 0.4 * dn * dn), 1.5) * 0.60;
1547 nStrips = hit->getZStripMax() - hit->getZStripMin() + 1;
1549 factor = std::pow((0.9 + 0.4 * dn * dn), 1.5) * 0.55;
1552 int nStrips = hit->getPhiStripMax() - hit->getPhiStripMin() + 1;
1553 localVariance[0] *= (nStrips * nStrips);
1554 nStrips = hit->getZStripMax() - hit->getZStripMin() + 1;
1555 localVariance[1] *= (nStrips * nStrips);
1557 G4ThreeVector hitPos(hit->getPositionX(), hit->getPositionY(),
1558 hit->getPositionZ());
1560 if (intersection.
chi2 >= 0.0) {
1561 intersection.
hit = bestHit;
1562 hit->isOnTrack(
true);
1563 if (track !=
nullptr) {
1564 track->addRelationTo(hit, intersection.
chi2);
1572 return intersection.
chi2 >= 0.0;
1578 double diffBestMagSq = 1.0E60;
1580 int matchingLayer = intersection.
layer + 1;
1581 int matchingEndcap = (intersection.
isForward ? 2 : 1);
1582 G4ThreeVector n(0.0, 0.0, (intersection.
isForward ? 1.0 : -1.0));
1583 for (
int h = 0; h <
m_klmHit2ds.getEntries(); ++h) {
1587 if (hit->getLayer() != matchingLayer)
1589 if (hit->getSection() != matchingEndcap)
1595 G4ThreeVector diff(hit->getPositionX() - intersection.
position.x(),
1596 hit->getPositionY() - intersection.
position.y(),
1597 hit->getPositionZ() - intersection.
position.z());
1598 double dn = diff * n;
1599 if (std::fabs(dn) > 2.0)
1602 if (diff.mag2() < diffBestMagSq) {
1603 diffBestMagSq = diff.mag2();
1610 intersection.
hit = bestHit;
1611 intersection.
isForward = (hit->getSection() == 2);
1612 intersection.
sector = hit->getSector() - 1;
1613 intersection.
time = hit->getTime();
1615 int nStrips = hit->getXStripMax() - hit->getXStripMin() + 1;
1616 localVariance[0] *= (nStrips * nStrips);
1617 nStrips = hit->getYStripMax() - hit->getYStripMin() + 1;
1618 localVariance[1] *= (nStrips * nStrips);
1619 G4ThreeVector hitPos(hit->getPositionX(), hit->getPositionY(), hit->getPositionZ());
1621 if (intersection.
chi2 >= 0.0) {
1624 if (track !=
nullptr) {
1625 track->addRelationTo(hit, intersection.
chi2);
1635 return intersection.
chi2 >= 0.0;
1640 const G4ThreeVector& hitPos,
const G4ThreeVector& extPos0)
1660 G4ThreeVector extPos(extPos0);
1661 G4ThreeVector extMom(intersection.
momentum);
1662 G4ThreeVector extDir(extMom.unit());
1663 G4ThreeVector diffPos(hitPos - extPos);
1664 G4ErrorSymMatrix extCov(intersection.
covariance);
1666 G4ErrorMatrix extPar(6, 1);
1667 extPar[0][0] = extPos.x();
1668 extPar[1][0] = extPos.y();
1669 extPar[2][0] = extPos.z();
1670 extPar[3][0] = extMom.x();
1671 extPar[4][0] = extMom.y();
1672 extPar[5][0] = extMom.z();
1679 nC = G4ThreeVector(0.0, 0.0, 1.0);
1681 double out = (intersection.
isForward ? 1.0 : -1.0);
1682 nA = G4ThreeVector(0.0, 0.0, out);
1683 nB = G4ThreeVector(out, 0.0, 0.0);
1684 nC = G4ThreeVector(0.0, out, 0.0);
1687 double extDirA = extDir * nA;
1688 if (std::fabs(extDirA) < 1.0E-6)
1690 double extDirBA = extDir * nB / extDirA;
1691 double extDirCA = extDir * nC / extDirA;
1694 G4ThreeVector move = extDir * ((diffPos * nA) / extDirA);
1699 G4ErrorMatrix jacobian(2, 6);
1700 jacobian[0][0] = nB.x() - nA.x() * extDirBA;
1701 jacobian[0][1] = nB.y() - nA.y() * extDirBA;
1702 jacobian[0][2] = nB.z() - nA.z() * extDirBA;
1703 jacobian[1][0] = nC.x() - nA.x() * extDirCA;
1704 jacobian[1][1] = nC.y() - nA.y() * extDirCA;
1705 jacobian[1][2] = nC.z() - nA.z() * extDirCA;
1707 G4ErrorMatrix residual(2, 1);
1708 residual[0][0] = diffPos.x() * jacobian[0][0] + diffPos.y() * jacobian[0][1] + diffPos.z() * jacobian[0][2];
1709 residual[1][0] = diffPos.x() * jacobian[1][0] + diffPos.y() * jacobian[1][1] + diffPos.z() * jacobian[1][2];
1711 G4ErrorSymMatrix hitCov(2, 0);
1712 hitCov[0][0] = localVariance[0];
1713 hitCov[1][1] = localVariance[1];
1716 hitCov[0][0] *= 10.0;
1717 hitCov[1][1] *= 10.0;
1721 G4ErrorSymMatrix correction(extCov.similarity(jacobian) + hitCov);
1728 correction.invert(fail);
1734 intersection.
chi2 = (correction.similarityT(residual))[0][0];
1736 G4ErrorMatrix gain((extCov * jacobian.T()) * correction);
1737 G4ErrorSymMatrix HRH(correction.similarityT(jacobian));
1738 extCov -= HRH.similarity(extCov);
1739 extPar += gain * residual;
1740 extPos.set(extPar[0][0], extPar[1][0], extPar[2][0]);
1741 extMom.set(extPar[3][0], extPar[4][0], extPar[5][0]);
1743 correction = hitCov - extCov.similarity(jacobian);
1744 correction.invert(fail);
1747 diffPos = hitPos - extPos;
1748 residual[0][0] = diffPos.x() * jacobian[0][0] + diffPos.y() * jacobian[0][1] + diffPos.z() * jacobian[0][2];
1749 residual[1][0] = diffPos.x() * jacobian[1][0] + diffPos.y() * jacobian[1][1] + diffPos.z() * jacobian[1][2];
1750 intersection.
chi2 = (correction.similarityT(residual))[0][0];
1757 intersection.
position = extPos + extDir * (((intersection.
position - extPos) * nA) / extDirA);
1783 if (outcome != MuidElementNumbers::c_NotReached) {
1785 int charge = klmMuidLikelihood->
getCharge();
1787 std::map<int, double> mapPdgPDF;
1788 for (
int pdg : signedPdgVector) {
1791 B2FATAL(
"Something went wrong: PDF for PDG code " << pdg <<
" not found!");
1792 double pdf = (search->second)->getPDF(klmMuidLikelihood);
1794 mapPdgPDF.insert(std::pair<int, double>(std::abs(pdg), pdf));
1796 if (denom < 1.0E-20)
1799 for (
auto const& [pdg, pdf] : mapPdgPDF) {
1800 klmMuidLikelihood->
setPDFValue(pdf, std::abs(pdg));
1802 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 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.
int getMaximalDetectorLayerNumber(int section) const
Get maximal detector layer number.
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).
KLMChannelNumber channelNumberBKLM(int section, int sector, int layer, int plane, int strip) const
Get channel number for BKLM.
static const KLMElementNumbers & Instance()
Instantiation.
KLMChannelNumber channelNumberEKLM(int section, int sector, int layer, int plane, int strip) const
Get channel number for EKLM.
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...
virtual G4double GetDistanceFromPoint(const G4ThreeVector &point, const G4ThreeVector &direc) const
Get the distance from a point to the cylinder along direc.
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 RunTermination()
Terminate a run and set state to G4ErrorState_Init.
void EventTermination(G4ErrorMode)
Terminate an event and set state to G4ErrorState_Init.
G4ErrorPropagator * GetPropagator() const
Get the propagator.
void InitTrackPropagation(G4ErrorMode)
Initialize for propagation of a track and set state to G4ErrorState_Propagating.
void Initialize(const char[], const std::string &, double, double, bool, int, const std::vector< std::string > &)
Initialize Geant4 and Geant4e.
G4int PropagateOneStep(G4ErrorTrajState *currentTS, G4ErrorMode mode=G4ErrorMode_PropForwards)
Propagate a track by one step.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
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