4 #include "GenFit/ConstField.h"
5 #include "GenFit/EventDisplay.h"
6 #include "GenFit/Exception.h"
7 #include "GenFit/FieldManager.h"
8 #include "GenFit/KalmanFitStatus.h"
9 #include "GenFit/GblFitter.h"
11 #include "TDatabasePDG.h"
12 #include "TGeoManager.h"
21 #include "StFwdTrackMaker/Common.h"
23 #include "StFwdTrackMaker/include/Tracker/FwdHit.h"
24 #include "StFwdTrackMaker/include/Tracker/TrackFitter.h"
25 #include "StFwdTrackMaker/include/Tracker/STARField.h"
26 #include "StFwdTrackMaker/include/Tracker/FwdGeomUtils.h"
28 #include "StarGenerator/UTIL/StarRandom.h"
29 #include "FitterUtils.h"
38 std::shared_ptr<genfit::Track> getTrack() {
return mFitTrack; }
61 TGeoManager * gMan =
nullptr;
64 LOG_INFO <<
"StFwdTrackMaker is loading the geometry cache: " << mConfig.
get<
string>(
"Geometry", mGeoCache.Data()).c_str() << endm;
65 TGeoManager::Import(mConfig.
get<
string>(
"Geometry", mGeoCache.Data()).c_str());
68 genfit::MaterialEffects::getInstance()->init(
new genfit::TGeoMaterialInterface());
71 genfit::MaterialEffects::getInstance()->setDebugLvl( mConfig.
get<
int>(
"TrackFitter.MaterialEffects:DebugLvl", 0) );
73 genfit::MaterialEffects::getInstance()->setEnergyLossBetheBloch( mConfig.
get<
int>(
"TrackFitter.MaterialEffects.EnergyLossBetheBloch",
true) );
74 genfit::MaterialEffects::getInstance()->setNoiseBetheBloch( mConfig.
get<
int>(
"TrackFitter.MaterialEffects.NoiseBetheBloch",
true) );
75 genfit::MaterialEffects::getInstance()->setNoiseCoulomb( mConfig.
get<
int>(
"TrackFitter.MaterialEffects.NoiseCoulomb",
true) );
76 genfit::MaterialEffects::getInstance()->setEnergyLossBrems( mConfig.
get<
int>(
"TrackFitter.MaterialEffects.EnergyLossBrems",
true) );
77 genfit::MaterialEffects::getInstance()->setNoiseBrems( mConfig.
get<
int>(
"TrackFitter.MaterialEffects.NoiseBrems",
true) );
78 genfit::MaterialEffects::getInstance()->ignoreBoundariesBetweenEqualMaterials( mConfig.
get<
int>(
"TrackFitter.MaterialEffects.ignoreBoundariesBetweenEqualMaterials",
true) );
81 genfit::MaterialEffects::getInstance()->setNoEffects( !mConfig.
get<
bool>(
"TrackFitter:MaterialEffects",
false));
82 if (!mConfig.
get<
bool>(
"TrackFitter:MaterialEffects",
false)){
83 LOG_INFO <<
"Turning OFF GenFit Material Effects in stepper" << endm;
88 if (mConfig.
get<
bool>(
"TrackFitter:constB",
false)) {
89 mBField = std::unique_ptr<genfit::AbsBField>(
new genfit::ConstField(0., 0., 5.0));
90 LOG_INFO <<
"StFwdTrackMaker: Tracking with constant magnetic field" << endm;
91 }
else if (mConfig.
get<
bool>(
"TrackFitter:zeroB",
false)) {
92 mBField = std::unique_ptr<genfit::AbsBField>(
new genfit::ConstField(0., 0., 0.));
93 LOG_INFO <<
"StFwdTrackMaker: Tracking with ZERO magnetic field" << endm;
96 LOG_INFO <<
"StFwdTrackMaker: Tracking with StarFieldAdapter" << endm;
100 genfit::FieldManager::getInstance()->init(mBField.get());
103 mFitter = std::unique_ptr<genfit::AbsKalmanFitter>(
new genfit::KalmanFitterRefTrack());
107 mFitter->setMaxFailedHits(mConfig.
get<
int>(
"TrackFitter.KalmanFitterRefTrack:MaxFailedHits", -1));
108 mFitter->setDebugLvl(mConfig.
get<
int>(
"TrackFitter.KalmanFitterRefTrack:DebugLvl", 0));
109 mFitter->setMaxIterations(mConfig.
get<
int>(
"TrackFitter.KalmanFitterRefTrack:MaxIterations", 40));
110 mFitter->setMinIterations(mConfig.
get<
int>(
"TrackFitter.KalmanFitterRefTrack:MinIterations", 0));
113 mFitter->setRelChi2Change( mConfig.
get<
double>(
"TrackFitter.KalmanFitterRefTrack:RelChi2Change", 1e-3) );
115 mFitter->setDeltaPval( mConfig.
get<
double>(
"TrackFitter.KalmanFitterRefTrack:DeltaPval", 1e-3) );
116 mFitter->setBlowUpFactor( mConfig.
get<
double>(
"TrackFitter.KalmanFitterRefTrack:BlowUpFactor", 1e3) );
126 mFSTZLocations = fwdGeoUtils.fstZ(
127 mConfig.
getVector<
double>(
"TrackFitter.Geometry:fst",
128 {140.286011, 154.286011, 168.286011 }
133 if ( fwdGeoUtils.fstZ( 0 ) < 1.0 ) {
134 LOG_WARN <<
"Using FST z-locations from config or defautl, may not match hits" << endm;
137 const double dzInnerFst = 1.715 + 0.04;
138 const double dzOuterFst = 0.240 + 0.04;
141 std::stringstream sstr;
142 sstr <<
"Adding FST Planes at: ";
144 for (
auto z : mFSTZLocations) {
145 mFSTPlanes.push_back(
146 genfit::SharedPlanePtr(
148 new genfit::DetPlane(TVector3(0, 0, z), TVector3(1, 0, 0), TVector3(0, 1, 0) )
153 mFSTPlanesInner.push_back(
154 genfit::SharedPlanePtr(
156 new genfit::DetPlane(TVector3(0, 0, z - dzInnerFst), TVector3(1, 0, 0), TVector3(0, 1, 0) )
159 mFSTPlanesInner.push_back(
160 genfit::SharedPlanePtr(
162 new genfit::DetPlane(TVector3(0, 0, z + dzInnerFst), TVector3(1, 0, 0), TVector3(0, 1, 0) )
166 mFSTPlanesOuter.push_back(
167 genfit::SharedPlanePtr(
169 new genfit::DetPlane(TVector3(0, 0, z - dzOuterFst), TVector3(1, 0, 0), TVector3(0, 1, 0) )
172 mFSTPlanesOuter.push_back(
173 genfit::SharedPlanePtr(
175 new genfit::DetPlane(TVector3(0, 0, z + dzOuterFst), TVector3(1, 0, 0), TVector3(0, 1, 0) )
179 sstr << delim << z <<
" (-dzInner=" << z - dzInnerFst <<
", +dzInner=" << z+dzInnerFst <<
", -dzOuter=" << z - dzOuterFst <<
", +dzOuter=" << z + dzOuterFst <<
")";
182 LOG_DEBUG << sstr.str() << endm;
186 mFTTZLocations = fwdGeoUtils.fttZ(
187 mConfig.getVector<
double>(
"TrackFitter.Geometry:ftt", {281.082,304.062,325.058,348.068})
190 if ( fwdGeoUtils.fttZ( 0 ) < 1.0 ) {
191 LOG_WARN <<
"Using FTT z-locations from config or default, may not match hits" << endm;
194 if ( mFTTZLocations.size() != 4 ){
195 LOG_ERROR <<
"Wrong number of FTT layers, got " << mFTTZLocations.size() <<
" but expected 4" << endm;
200 sstr <<
"Adding FTT Planes at: ";
202 for (
auto z : mFTTZLocations) {
203 mFTTPlanes.push_back(
204 genfit::SharedPlanePtr(
206 new genfit::DetPlane(TVector3(0, 0, z), TVector3(1, 0, 0), TVector3(0, 1, 0))
212 LOG_DEBUG << sstr.str() << endm;
223 size_t planeId = h->getSector();
225 const TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() );
227 double phi = hitXYZ.Phi();
228 if ( phi < 0 ) phi = TMath::Pi() * 2 + phi;
229 const double phi_slice = phi / (TMath::Pi() / 6.0);
230 const int phi_index = ((int)phi_slice);
231 const double r =sqrt( pow(hitXYZ.x(), 2) + pow(hitXYZ.y(), 2) );
233 const size_t idx = phi_index % 2;
234 auto planeCorr = mFSTPlanesInner[planeId*2 + idx];
236 planeCorr = mFSTPlanesOuter[planeId*2 + idx];
238 double cdz = (h->getZ() - planeCorr->getO().Z());
241 LOG_WARN <<
"FST Z =" << h->getZ() <<
" vs CORR Plane Z = " << planeCorr->getO().Z() <<
" DIFF: " << cdz <<
" phi_slice = " << phi_slice <<
", phi_index = " << phi_index <<
" R=" << hitXYZ.Pt() <<
" idx=" << idx << endm;
255 cm(0, 0) =
static_cast<FwdHit*
>(h)->_covmat(0, 0);
256 cm(1, 1) =
static_cast<FwdHit*
>(h)->_covmat(1, 1);
257 cm(0, 1) =
static_cast<FwdHit*
>(h)->_covmat(0, 1);
269 genfit::MeasuredStateOnPlane
projectToFst(
size_t fstPlane, std::shared_ptr<genfit::Track> fitTrack) {
271 genfit::MeasuredStateOnPlane nil;
275 auto detFst = mFSTPlanes[fstPlane];
277 genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1);
279 fitTrack->getCardinalRep()->extrapolateToPlane(tst, detFst);
291 genfit::MeasuredStateOnPlane
projectToFtt(
size_t iFttPlane, std::shared_ptr<genfit::Track> fitTrack) {
293 genfit::MeasuredStateOnPlane nil;
296 auto fttPlane = mFTTPlanes[iFttPlane];
298 genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1);
300 fitTrack->getCardinalRep()->extrapolateToPlane(tst, fttPlane);
316 TVector3 seedPos(0, 0, 0);
317 TVector3 seedMom(0, 0, 10);
318 gfs.makeSeed( trackSeed, seedPos, seedMom, seedQ );
319 LOG_DEBUG <<
"Setting track fit seed position = " << TString::Format(
"(%f, %f, %f)", seedPos.X(), seedPos.Y(), seedPos.Z() ) << endm;
320 LOG_DEBUG <<
"Setting track fit seed momentum = " << TString::Format(
"(%f, %f, %f)", seedMom.X(), seedMom.Y(), seedMom.Z() ) << endm;
322 LOG_DEBUG <<
"Setting track fit seed charge = " << seedQ << endm;
325 LOG_ERROR <<
"Seed charge is zero, skipping track -> usually means collinear points" << endm;
331 auto theTrackRep =
new genfit::RKTrackRep(mPdgMuon * -1 * seedQ);
334 mFitTrack = std::make_shared<genfit::Track>(theTrackRep, seedPos, seedMom);
341 TVectorD hitCoords(2);
351 for (
auto h : trackSeed) {
352 auto fh =
dynamic_cast<FwdHit*
>(h);
353 hitCoords[0] = h->getX();
354 hitCoords[1] = h->getY();
360 LOG_DEBUG <<
"Treating hit as a spacepoint" << endm;
362 LOG_DEBUG <<
"Including primary vertex in fit" << endm;
368 LOG_INFO <<
"x = " << pv[0] <<
"+/- " << fh->_covmat(0,0) <<
", y = " << pv[1] <<
" +/- " << fh->_covmat(1,1) <<
", z = " << pv[2] <<
" +/- " << fh->_covmat(2,2) << endm;
369 auto tp =
new genfit::TrackPoint();
370 genfit::SpacepointMeasurement *measurement =
new genfit::SpacepointMeasurement(pv, fh->_covmat, fh->_detid, ++hitId, tp);
371 tp->addRawMeasurement(measurement);
372 tp->setTrack(mFitTrack.get());
374 tp->setSortingParameter(0);
377 tp->setSortingParameter(4 + idxFtt);
381 tp->setSortingParameter(1 + idxFst);
385 mFitTrack->insertPoint( tp );
389 genfit::PlanarMeasurement *measurement =
new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), fh->_detid, ++hitId,
nullptr);
391 planeId = h->getSector();
392 genfit::SharedPlanePtr plane;
394 planeId = fh->_vid - 9;
396 LOG_INFO <<
"planeId = " << planeId <<
", sector " << h->getSector() <<
", vid = " << fh->_vid << endm;
397 if (fh->isFtt() && mFTTPlanes.size() <= planeId) {
398 LOG_ERROR <<
"invalid VolumId -> out of bounds DetPlane, vid = " <<
dynamic_cast<FwdHit*
>(h)->_vid <<
" vs. planeId = " << planeId << endm;
404 plane = mFTTPlanes[planeId];
405 else if (fh->isFst())
406 plane = getFstPlane( fh );
408 measurement->setPlane(plane, planeId);
410 mFitTrack->insertPoint(
new genfit::TrackPoint(measurement, mFitTrack.get()));
411 LOG_INFO <<
"\tsetupTrack: Hit at Z = " << h->getZ() <<
" with plane at Z = " << plane->getO().Z() << endm;
413 if (abs(h->getZ() - plane->getO().Z()) > 0.05) {
414 LOG_WARN <<
"Z Mismatch h->z = " << h->getZ() <<
", plane->z = "<< plane->getO().Z() <<
", diff = " << abs(h->getZ() - plane->getO().Z()) << endm;
436 mFitTrack->checkConsistency();
438 mFitter->processTrack(t.get());
441 t->checkConsistency();
444 t->determineCardinalRep();
448 auto status = t->getFitStatus();
449 LOG_INFO <<
"Fit status: " << status->isFitConverged() << endm;
450 LOG_INFO <<
"-Fit pvalue: " << status->getPVal() << endm;
451 LOG_INFO <<
"-Fit Chi2: " << status->getChi2() << endm;
453 if ( status->isFitConverged() ){
455 auto cr = t->getCardinalRep();
456 auto p = cr->getMom( t->getFittedState( 0, cr ));
457 int rcQ = status->getCharge();
458 LOG_INFO <<
"Fit momentum: " << p.X() <<
", " << p.Y() <<
", " << p.Z() << endm;
459 LOG_INFO <<
"\tFit Pt: " << p.Pt() <<
", eta: " << p.Eta() <<
", phi: " << p.Phi() << endm;
464 }
catch (genfit::Exception &e) {
465 LOG_ERROR <<
"Exception on fit update" << e.what() << endm;
467 LOG_INFO <<
"Track fit update complete!" << endm;
479 long long itStart = FwdTrackerUtils::nowNanoSecond();
480 LOG_DEBUG <<
"Fitting track with " << trackSeed.size() <<
" FWD Measurements" << endm;
485 std::sort(trackSeed.begin(), trackSeed.end(),
486 [](KiTrack::IHit *a, KiTrack::IHit *b)
487 {
return a->getZ() < b->getZ(); }
493 bool valid = setupTrack(trackSeed);
495 LOG_ERROR <<
"Failed to setup track for fit" << endm;
498 LOG_DEBUG <<
"Ready to fit with " << mFitTrack->getNumPoints() <<
" track points" << endm;
503 performFit( mFitTrack );
504 long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6;
509 vector<genfit::SharedPlanePtr> mFTTPlanes;
510 vector<genfit::SharedPlanePtr> mFSTPlanes;
511 vector<genfit::SharedPlanePtr> mFSTPlanesInner;
512 vector<genfit::SharedPlanePtr> mFSTPlanesOuter;
515 std::unique_ptr<genfit::AbsBField> mBField;
521 std::unique_ptr<genfit::AbsKalmanFitter> mFitter =
nullptr;
524 const int mPdgPiPlus = 211;
525 const int mPdgPiMinus = -211;
526 const int mPdgPositron = 11;
527 const int mPdgElectron = -11;
528 const int mPdgMuon = 13;
529 const int mPdgAntiMuon = -13;
533 vector<double> mFSTZLocations, mFTTZLocations;
536 std::shared_ptr<genfit::Track> mFitTrack;
void performFit(std::shared_ptr< genfit::Track > t)
performs the fit on a track
genfit::SharedPlanePtr getFstPlane(FwdHit *h)
Get the Fst Plane object for a given hit.
genfit::MeasuredStateOnPlane projectToFtt(size_t iFttPlane, std::shared_ptr< genfit::Track > fitTrack)
Get projection to given FTT plane.
TMatrixDSym CovMatPlane(KiTrack::IHit *h)
Convert the 3x3 covmat to 2x2 by dropping z.
std::vector< T > getVector(std::string path, std::vector< T > dv) const
Get a Vector object from config.
genfit::MeasuredStateOnPlane projectToFst(size_t fstPlane, std::shared_ptr< genfit::Track > fitTrack)
Get projection to given FST plane.
TrackFitter(FwdTrackerConfig _mConfig, TString geoCache)
Construct a new Track Fitter object.
T get(std::string path, T dv) const
template function for getting any type that can be converted from string via stringstream ...
bool setupTrack(Seed_t trackSeed)
setup the track from the given seed and optional primary vertex
long long fitTrack(Seed_t trackSeed, TVector3 *seedMomentum=0)
Primary track fitting routine.
void setup()
Setup the tracker object Load geometry Setup Material Effects Setup the magnetic field Setup the fitt...