1 #include "StFwdTrackMaker/StFwdClosureMaker.h"
2 #include "St_base/StMessMgr.h"
3 #include "StBFChain/StBFChain.h"
4 #include "StFwdTrackMaker/StFwdTrackMaker.h"
6 #include "StFwdTrackMaker/include/Tracker/FwdTracker.h"
7 #include "StFwdTrackMaker/include/Tracker/ObjExporter.h"
9 #include "StEvent/StBTofCollection.h"
10 #include "StEvent/StBTofHeader.h"
11 #include "StEvent/StEvent.h"
12 #include "StEvent/StFttCluster.h"
13 #include "StEvent/StFttCollection.h"
14 #include "StEvent/StFcsCluster.h"
15 #include "StEvent/StFcsCollection.h"
16 #include "StFcsDbMaker/StFcsDb.h"
17 #include "StRoot/StEpdUtil/StEpdGeom.h"
18 #include "StEvent/StFwdTrackCollection.h"
19 #include "StEvent/StFwdTrack.h"
22 #include "StMuDSTMaker/COMMON/StMuDstMaker.h"
23 #include "StMuDSTMaker/COMMON/StMuDst.h"
24 #include "StMuDSTMaker/COMMON/StMuEvent.h"
25 #include "StMuDSTMaker/COMMON/StMuFstCollection.h"
26 #include "StMuDSTMaker/COMMON/StMuFstHit.h"
27 #include "StMuDSTMaker/COMMON/StMuPrimaryVertex.h"
28 #include "StMuDSTMaker/COMMON/StMuFwdTrack.h"
29 #include "StMuDSTMaker/COMMON/StMuFwdTrackCollection.h"
30 #include "StMuDSTMaker/COMMON/StMuFcsCollection.h"
31 #include "StMuDSTMaker/COMMON/StMuFcsCluster.h"
32 #include "StMuDSTMaker/COMMON/StMuFcsHit.h"
33 #include "StMuDSTMaker/COMMON/StMuFttCluster.h"
34 #include "StMuDSTMaker/COMMON/StMuFttPoint.h"
35 #include "StMuDSTMaker/COMMON/StMuMcTrack.h"
36 #include "StMuDSTMaker/COMMON/StMuFstHit.h"
38 #include "tables/St_g2t_fts_hit_Table.h"
39 #include "tables/St_g2t_track_Table.h"
40 #include "tables/St_g2t_vertex_Table.h"
41 #include "tables/St_g2t_event_Table.h"
49 TVector3 StFwdClosureMaker::raster(TVector3 p0) {
54 const double minR = 5.0;
56 p.SetPerp(minR + (std::floor((r - minR) / mRasterR) * mRasterR + mRasterR / 2.0));
57 p.SetPhi(-TMath::Pi() + (std::floor((phi + TMath::Pi()) / mRasterPhi) * mRasterPhi + mRasterPhi / 2.0));
61 TMatrixDSym StFwdClosureMaker::makeSiCovMat(TVector3
hit) {
68 const float x = hit.X();
69 const float y = hit.Y();
70 const float R = sqrt(x * x + y * y);
71 const float cosphi = x / R;
72 const float sinphi = y / R;
73 const float sqrt12 = sqrt(12.);
75 const float dr = mRasterR / sqrt12;
76 const float dphi = (mRasterPhi) / sqrt12;
82 T(0, 1) = -R * sinphi;
88 J(1, 0) = -R * sinphi;
92 cmcyl(0, 0) = dr * dr;
93 cmcyl(1, 1) = dphi * dphi;
95 TMatrixD r = T * cmcyl * J;
105 TMatrixDSym tamvoc(3);
106 tamvoc( 0, 0 ) =
cm(0, 0); tamvoc( 0, 1 ) =
cm(0, 1); tamvoc( 0, 2 ) = 0.0;
107 tamvoc( 1, 0 ) =
cm(1, 0); tamvoc( 1, 1 ) =
cm(1, 1); tamvoc( 1, 2 ) = 0.0;
108 tamvoc( 2, 0 ) = 0.0; tamvoc( 2, 1 ) = 0.0; tamvoc( 2, 2 ) = 0.01*0.01;
114 StFwdClosureMaker::StFwdClosureMaker() :
StMaker(
"fwdClosureMaker") {}
116 TGeoManager * gMan =
nullptr;
117 std::unique_ptr<genfit::AbsKalmanFitter> mFitter =
nullptr;
118 std::unique_ptr<genfit::AbsBField> mBField;
119 std::map< string, TH1* > mHistograms;
121 TH1 * addHistogram1D(
string name,
string title,
int nbins,
double min,
double max ){
122 TH1 * h =
new TH1F( name.c_str(), title.c_str(), nbins, min, max );
123 mHistograms[name] = h;
127 TH2 * addHistogram2D(
string name,
string title,
int nbinsX,
double minX,
double maxX,
int nbinsY,
double minY,
double maxY ){
128 TH2 * h =
new TH2F( name.c_str(), title.c_str(), nbinsX, minX, maxX, nbinsY, minY, maxY );
129 mHistograms[name] = h;
133 TH1 * getHistogram1D(
string name ){
134 if ( mHistograms.count(name) )
135 return mHistograms[name];
136 assert(
false &&
"Histogram not found" );
139 TH2 * getHistogram2D(
string name ){
140 return dynamic_cast<TH2*
>( getHistogram1D(name) );
148 double determinant(
double a,
double b,
double c,
double d) {
149 return a * d - b * c;
153 double computeCurvature(
const Point& p1,
const Point& p2,
const Point& p3) {
155 double A = std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2));
156 double B = std::sqrt(std::pow(p3.x - p2.x, 2) + std::pow(p3.y - p2.y, 2));
157 double C = std::sqrt(std::pow(p1.x - p3.x, 2) + std::pow(p1.y - p3.y, 2));
160 double det = determinant(p2.x - p1.x, p2.y - p1.y, p3.x - p1.x, p3.y - p1.y);
162 double charge = det > 0 ? -1 : 1;
164 double area = std::abs(det) / 2.0;
167 std::cerr <<
"The points are collinear, curvature is undefined." << std::endl;
173 double radius = (A * B * C) / (4 * area);
176 return charge / radius;
179 int StFwdClosureMaker::Init() {
185 TGeoManager::Import(
"fGeom.root");
188 genfit::MaterialEffects::getInstance()->init(
new genfit::TGeoMaterialInterface());
189 genfit::MaterialEffects::getInstance()->setNoEffects(
true );
193 genfit::FieldManager::getInstance()->init(mBField.get());
196 mFitter = std::unique_ptr<genfit::AbsKalmanFitter>(
new genfit::KalmanFitterRefTrack(
202 mFitter->setRelChi2Change( mRelChi2 );
205 addHistogram2D(
"PtCorrelation",
"PtCorrelation; MC; RC;", 100, 0, 1, 100, 0, 1 );
206 addHistogram1D(
"PtResolution",
"PtResolution; (p_{T}^{MC} - p_{T}^{RC}) / p_{T}^{MC};", 100, -5, 5 );
207 addHistogram1D(
"CurveResolution",
"CurveResolution; (1/p_{T}^{MC} - 1/p_{T}^{RC}) / 1/p_{T}^{MC};", 100, -5, 5 );
208 addHistogram2D(
"CurveResolutionVsPt",
"CurveResolution; Pt (GeV/c); (1/p_{T}^{MC} - 1/p_{T}^{RC}) / 1/p_{T}^{MC};", 100, 0, 2.0, 100, -5, 5 );
209 addHistogram2D(
"PtResolutionVsPt",
"PtResolution; Pt (GeV/c); (p_{T}^{MC} - p_{T}^{RC}) / p_{T}^{MC};", 100, 0, 2.0, 100, -5, 5 );
210 addHistogram1D(
"PointCurvePtResolution",
"PointCurve PtResolution; (p_{T}^{MC} - p_{T}^{RC}) / p_{T}^{MC};", 100, -5, 5 );
211 addHistogram1D(
"PointCurveCurveResolution",
"PointCurve CurveResolution; (1/p_{T}^{MC} - 1/p_{T}^{RC}) / 1/p_{T}^{MC};", 100, -5, 5 );
213 addHistogram1D(
"QCurve",
"QCurve; q/Pt;", 100, -5, 5 );
214 addHistogram2D(
"QMatrix",
"QMatrix; MC; RC;", 4, -2, 2, 4, -2, 2 );
215 addHistogram2D(
"QidVsPt",
"QMatrix; Pt; Qid;", 100, 0, 2.0, 2, -0.5, 1.5 );
223 getHistogram1D(
"PtResolution")->Draw();
224 gPad->Print(
"ClosurePtResolution.pdf" );
226 getHistogram1D(
"CurveResolution")->Draw();
227 gPad->Print(
"ClosureCurveResolution.pdf" );
229 getHistogram1D(
"PointCurvePtResolution")->Draw();
230 gPad->Print(
"ClosurePointCurvePtResolution.pdf" );
232 getHistogram1D(
"PointCurveCurveResolution")->Draw();
233 gPad->Print(
"ClosurePointCurveCurveResolution.pdf" );
235 TFile * fOut =
new TFile(mOutFile,
"RECREATE");
237 for (
auto h : mHistograms ){
246 LOG_INFO <<
"Make (StFwdClosureMaker)" << endm;
251 St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet(
"geant/g2t_vertex");
259 TVector3 mcMom(0,0,0);
262 St_g2t_track *g2t_track = (St_g2t_track *)GetDataSet(
"geant/g2t_track");
266 LOG_DEBUG << g2t_track->GetNRows() <<
" mc tracks in geant/g2t_track " << endm;
268 for (
int irow = 0; irow < g2t_track->GetNRows(); irow++) {
269 g2t_track_st *
track = (g2t_track_st *)g2t_track->At(irow);
274 int track_id = track->id;
275 float pt2 = track->p[0] * track->p[0] + track->p[1] * track->p[1];
276 float pt = std::sqrt(pt2);
277 float eta = track->eta;
278 TVector3 pp( track->p[0], track->p[1], track->p[2] );
279 if ( track_id == 1 ){
280 mcMom.SetXYZ( track->p[0], track->p[1], track->p[2] );
283 float phi = std::atan2(track->p[1], track->p[0]);
284 int q = track->charge;
285 LOG_INFO <<
"McTrack: " << track_id <<
", pt = " << pt <<
", eta = " << eta <<
", phi = " << phi <<
", q = " << q << endm;
290 vector<genfit::SpacepointMeasurement*> spoints;
295 St_g2t_fts_hit *g2t_fsi_hits = (St_g2t_fts_hit *)GetDataSet(
"geant/g2t_fsi_hit");
296 if ( !g2t_fsi_hits ){
297 LOG_DEBUG <<
"No g2t_fts_hits, cannot load FST hits from GEANT" << endm;
302 TMatrixDSym hitCov3(3);
303 const double sigXY = 0.01;
304 hitCov3(0, 0) = sigXY * sigXY;
305 hitCov3(1, 1) = sigXY * sigXY;
308 TMatrixDSym vStripCov3(3);
309 vStripCov3(0, 0) = sigXY * sigXY;
310 vStripCov3(1, 1) = 50;
311 vStripCov3(2, 2) = 0.1;
313 TMatrixDSym hStripCov3(3);
314 hStripCov3(0, 0) = 50;
315 hStripCov3(1, 1) = sigXY * sigXY;
316 hStripCov3(2, 2) = 0.1;
321 if ( g2t_vertex !=
nullptr ) {
323 g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(0);
326 cov(0, 0) = pow(mPrimaryVertexSigXY,2);
327 cov(1, 1) = pow(mPrimaryVertexSigXY,2);
328 cov(2, 2) = pow(mPrimaryVertexSigZ, 2);
329 auto rhc = TVectorD( 3 );
330 rhc[0] = vert->ge_x[0];
331 rhc[1] = vert->ge_x[1];
332 rhc[2] = vert->ge_x[2];
333 auto spoint =
new genfit::SpacepointMeasurement(rhc, cov, 0, 0,
nullptr);
334 spoints.push_back(spoint);
341 for (
int i = 0; i < g2t_fsi_hits->GetNRows(); i++) {
343 g2t_fts_hit_st *git = (g2t_fts_hit_st *)g2t_fsi_hits->At(i);
348 int volume_id = git->volume_id;
349 int d = volume_id / 1000;
356 auto rhc = TVectorD( 3 );
357 TVector3 rastered = raster( TVector3( x, y, z ) );
358 rhc[0] = rastered.X();
359 rhc[1] = rastered.Y();
360 rhc[2] = rastered.Z();
361 auto spoint =
new genfit::SpacepointMeasurement(rhc, makeSiCovMat(TVector3( x, y, z )), 0, i+1,
nullptr);
362 spoints.push_back(spoint);
363 LOG_INFO <<
"FST HIT: d = " << d <<
", x=" << x <<
", y=" << y <<
", z=" << z << endm;
366 St_g2t_fts_hit *g2t_stg_hits = (St_g2t_fts_hit *)GetDataSet(
"geant/g2t_stg_hit");
368 LOG_WARN <<
"geant/g2t_stg_hit is empty" << endm;
371 int nstg = g2t_stg_hits->GetNRows();
373 LOG_DEBUG <<
"This event has " << nstg <<
" stg hits in geant/g2t_stg_hit " << endm;
375 for (
int i = 0; i < nstg; i++) {
377 g2t_fts_hit_st *git = (g2t_fts_hit_st *)g2t_stg_hits->At(i);
381 int volume_id = git->volume_id;
382 int plane_id = (volume_id - 1) / 100;
385 if ( mFttMode == kPoint && volume_id % 2 ==0 )
392 if (plane_id < 0 || plane_id >= 4) {
396 auto rhc = TVectorD( 3 );
400 LOG_INFO <<
"FTT HIT: plane_id = " << plane_id <<
", volume_d = " << volume_id <<
" x=" << x <<
", y=" << y <<
", z=" << z << endm;
402 if ( kPoint == mFttMode ){
403 auto spoint =
new genfit::SpacepointMeasurement(rhc, hitCov3, 0, i+4,
nullptr);
404 if ( nFttHits < mNumFttToUse )
405 spoints.push_back(spoint);
407 if ( volume_id % 2 == 0 ){
408 auto spoint =
new genfit::SpacepointMeasurement(rhc, vStripCov3, 0, i+4,
nullptr);
409 if ( nFttHits < mNumFttToUse )
410 spoints.push_back(spoint);
412 auto spoint =
new genfit::SpacepointMeasurement(rhc, hStripCov3, 0, i+4,
nullptr);
413 if ( nFttHits < mNumFttToUse )
414 spoints.push_back(spoint);
421 float ptCurve = 9999.0;
423 if ( spoints.size() >= 3 ){
424 double curve = computeCurvature( {spoints[0]->getRawHitCoords()[0], spoints[0]->getRawHitCoords()[1]},
425 {spoints[1]->getRawHitCoords()[0], spoints[1]->getRawHitCoords()[1]},
426 {spoints[2]->getRawHitCoords()[0], spoints[2]->getRawHitCoords()[1]} );
427 const double K = 0.00029979;
428 const double BStrength = 5;
429 double pt = fabs((K*BStrength)/curve);
430 qCurve = curve > 0 ? 1 : -1;
432 LOG_INFO <<
"Curve: " << curve <<
", Pt: " << pt << endm;
439 auto theTrackRep =
new genfit::RKTrackRep(-13 * qCurve);
440 auto seedPos = TVector3(0, 0, 0);
441 auto seedMom = TVector3(0, 0, 10);
443 auto mFitTrack = std::make_shared<genfit::Track>(theTrackRep, seedPos, seedMom);
445 LOG_INFO <<
"Track fit with " << spoints.size() <<
" space points" << endm;
447 for (
size_t i = 0; i < spoints.size(); i++ ){
448 mFitTrack->insertPoint(
new genfit::TrackPoint(spoints[i], mFitTrack.get()));
451 LOG_INFO <<
"Track prep = " << mFitter->isTrackPrepared( mFitTrack.get(), theTrackRep ) << endm;
454 mFitTrack->checkConsistency();
456 mFitter->processTrack(mFitTrack.get());
458 mFitTrack->checkConsistency();
459 mFitTrack->determineCardinalRep();
464 auto status = mFitTrack->getFitStatus();
465 LOG_INFO <<
"Fit status: " << status->isFitConverged() << endm;
466 LOG_INFO <<
"-Fit pvalue: " << status->getPVal() << endm;
467 LOG_INFO <<
"-Fit Chi2: " << status->getChi2() << endm;
471 auto cr = mFitTrack->getCardinalRep();
472 auto p = cr->getMom( mFitTrack->getFittedState( 0, cr ));
473 int rcQ = status->getCharge();
474 LOG_INFO <<
"Fit momentum: " << p.X() <<
", " << p.Y() <<
", " << p.Z() << endm;
475 LOG_INFO <<
"\tFit Pt: " << p.Pt() <<
", eta: " << p.Eta() <<
", phi: " << p.Phi() << endm;
476 LOG_INFO <<
"\tMc Pt: " << mcMom.Pt() <<
", eta: " << mcMom.Eta() <<
", phi: " << mcMom.Phi() << endm;
479 if (status->isFitConvergedPartially()){
480 getHistogram1D(
"PtResolution")->Fill( (p.Pt() - mcMom.Pt()) / mcMom.Pt() );
481 getHistogram1D(
"CurveResolution")->Fill( (1/p.Pt() - 1/mcMom.Pt()) / (1/mcMom.Pt()) );
482 getHistogram1D(
"PtCorrelation")->Fill( mcMom.Pt(), p.Pt() );
483 getHistogram1D(
"QCurve")->Fill( rcQ / p.Pt() );
485 getHistogram1D(
"PointCurvePtResolution")->Fill( (ptCurve - mcMom.Pt()) / mcMom.Pt() );
486 getHistogram1D(
"PointCurveCurveResolution")->Fill( (1/ptCurve - 1/mcMom.Pt()) / (1/mcMom.Pt()) );
488 getHistogram2D(
"PtResolutionVsPt")->Fill( mcMom.Pt(), (p.Pt() - mcMom.Pt()) / mcMom.Pt() );
489 getHistogram2D(
"CurveResolutionVsPt")->Fill( mcMom.Pt(), (1/p.Pt() - 1/mcMom.Pt()) / (1/mcMom.Pt()) );
491 getHistogram2D(
"QMatrix")->Fill( mcQ, rcQ );
492 getHistogram2D(
"QidVsPt")->Fill( mcMom.Pt(), mcQ == rcQ ? 1 : 0 );
495 LOG_INFO <<
"Fit did not converge" << endm;
499 }
catch (genfit::Exception &e) {
500 LOG_ERROR <<
"GenFit failed to fit track with: " << e.what() << endm;
522 void StFwdClosureMaker::Clear(
const Option_t *opts) {
const Double_t cm
If an event generator measures distances in cm, then multiply by cm.